[jhbuild] Add support for Meson build system



commit 5025a72706a812ec1db79b7b67f7583c0b71e4fb
Author: Frédéric Péters <fpeters 0d be>
Date:   Sat Aug 13 15:44:36 2016 +0200

    Add support for Meson build system
    
    https://bugzilla.gnome.org/show_bug.cgi?id=756244

 doc/C/index.docbook        |   53 +++++++++++++-
 jhbuild/config.py          |    1 +
 jhbuild/defaults.jhbuildrc |    2 +
 jhbuild/modtypes/meson.py  |  171 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 226 insertions(+), 1 deletions(-)
---
diff --git a/doc/C/index.docbook b/doc/C/index.docbook
index d92a0bd..b45ad50 100644
--- a/doc/C/index.docbook
+++ b/doc/C/index.docbook
@@ -69,7 +69,7 @@
       <ulink url="http://www.selenic.com/mercurial/";>Mercurial</ulink>
       repositories, as well as Tar and Zip archives hosted on web or FTP sites.
       JHBuild can build modules using a variety of build systems, including
-      Autotools, CMake, WAF, Python Distutils and Perl Makefiles.</para>
+      Autotools, CMake, Meson, WAF, Python Distutils and Perl Makefiles.</para>
 
     <para>JHBuild is not intended as a replacement for the distribution's
       package management system. Instead, it makes it easy to build software
@@ -3003,6 +3003,57 @@ Optional packages: (JHBuild will build the missing packages)
 </programlisting>
       </section>
 
+      <section id="moduleset-syntax-defs-meson">
+        <title>Meson</title>
+
+        <para>The <sgmltag class="element">meson</sgmltag> element is used to
+          define a module which is built using the Meson build system.</para>
+
+<programlisting>
+  &lt;meson id="<replaceable>modulename</replaceable>"
+            [ skip-install="<replaceable>skip-install</replaceable>" ]&gt;
+  &lt;branch [ ... ] &gt;
+    [...]
+  &lt;/branch&gt;
+
+  &lt;dependencies&gt;
+    &lt;dep package="<replaceable>modulename</replaceable>"/&gt;
+    ...
+  &lt;/dependencies&gt;
+  &lt;after&gt;
+    &lt;dep package="<replaceable>modulename</replaceable>"/&gt;
+    ...
+  &lt;/after&gt;
+&lt;/meson&gt;
+</programlisting>
+      </section>
+
+      <section id="moduleset-syntax-defs-distutils">
+        <title>distutils</title>
+
+        <para>The <sgmltag class="element">distutils</sgmltag> element is used
+          to define a module which is built using python's distutils</para>
+
+<programlisting>
+&lt;distutils id="<replaceable>modulename</replaceable>"
+            [ supports-non-srcdir-builds="<replaceable>yes|no</replaceable>" ]&gt;
+  &lt;branch [ ... ] &gt;
+    [...]
+  &lt;/branch&gt;
+
+  &lt;dependencies&gt;
+    &lt;dep package="<replaceable>modulename</replaceable>"/&gt;
+    ...
+  &lt;/dependencies&gt;
+  &lt;after&gt;
+    &lt;dep package="<replaceable>modulename</replaceable>"/&gt;
+    ...
+  &lt;/after&gt;
+&lt;/distutils&gt;
+</programlisting>
+      </section>
+
+
       <section id="moduleset-syntax-defs-distutils">
         <title>distutils</title>
 
diff --git a/jhbuild/config.py b/jhbuild/config.py
index 4ae5d23..1dcc144 100644
--- a/jhbuild/config.py
+++ b/jhbuild/config.py
@@ -62,6 +62,7 @@ _known_keys = [ 'moduleset', 'modules', 'skip', 'tags', 'prefix',
                 'use_local_modulesets', 'ignore_suggests', 'modulesets_dir',
                 'mirror_policy', 'module_mirror_policy', 'dvcs_mirror_dir',
                 'shallow_clone', 'build_targets', 'cmakeargs', 'module_cmakeargs',
+                'mesonargs', 'module_mesonargs',
                 'print_command_pattern', 'static_analyzer',
                 'module_static_analyzer', 'static_analyzer_template',
                 'static_analyzer_outputdir', 'check_sysdeps', 'system_prefix',
diff --git a/jhbuild/defaults.jhbuildrc b/jhbuild/defaults.jhbuildrc
index 8fc52b8..5a6664f 100644
--- a/jhbuild/defaults.jhbuildrc
+++ b/jhbuild/defaults.jhbuildrc
@@ -77,6 +77,7 @@ except ImportError as _e:
 # override environment variables, command line arguments, etc
 autogenargs = '--disable-static --disable-gtk-doc'
 cmakeargs = ''
+mesonargs = ''
 makeargs = ''
 cflags = ''
 
@@ -90,6 +91,7 @@ svnroots = {}
 branches = {}
 module_autogenargs = {}
 module_cmakeargs = {}
+module_mesonargs = {}
 module_makeargs = {}
 module_extra_env = {}
 module_makecheck = {}
diff --git a/jhbuild/modtypes/meson.py b/jhbuild/modtypes/meson.py
new file mode 100644
index 0000000..eb344a1
--- /dev/null
+++ b/jhbuild/modtypes/meson.py
@@ -0,0 +1,171 @@
+# jhbuild - a tool to ease building collections of source packages
+# Copyright (C) 2001-2006  James Henstridge
+#
+#   meson.py: meson module type definitions.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+__metaclass__ = type
+
+import os
+
+from jhbuild.errors import BuildStateError, CommandError
+from jhbuild.modtypes import \
+     Package, DownloadableModule, register_module_type, MakeModule
+from jhbuild.modtypes.autotools import collect_args
+from jhbuild.commands.sanitycheck import inpath
+
+__all__ = [ 'MesonModule' ]
+
+class MesonModule(MakeModule, DownloadableModule):
+    """Base type for modules that use Meson build system."""
+    type = 'meson'
+
+    PHASE_CHECKOUT = DownloadableModule.PHASE_CHECKOUT
+    PHASE_FORCE_CHECKOUT = DownloadableModule.PHASE_FORCE_CHECKOUT
+    PHASE_CLEAN = 'clean'
+    PHASE_CONFIGURE = 'configure'
+    PHASE_BUILD = 'build'
+    PHASE_DIST = 'dist'
+    PHASE_INSTALL = 'install'
+
+    def __init__(self, name, branch=None,
+                 mesonargs='', makeargs='',
+                 skip_install_phase=False):
+        MakeModule.__init__(self, name, branch=branch, makeargs=makeargs)
+        self.mesonargs = mesonargs
+        self.supports_non_srcdir_builds = True
+        self.skip_install_phase = skip_install_phase
+        self.force_non_srcdir_builds = True
+        self.supports_install_destdir = True
+
+    def eval_args(self, args):
+        args = Package.eval_args(self, args)
+        args = args.replace('${libsuffix}', '')
+        return args
+
+    def get_srcdir(self, buildscript):
+        return self.branch.srcdir
+
+    def get_builddir(self, buildscript):
+        builddir = self.get_srcdir(buildscript)
+        if buildscript.config.buildroot and self.supports_non_srcdir_builds:
+            d = buildscript.config.builddir_pattern % (
+                self.branch.checkoutdir or self.branch.get_module_basename())
+            builddir = os.path.join(buildscript.config.buildroot, d)
+        if self.force_non_srcdir_builds and builddir == self.get_srcdir(buildscript):
+            builddir = os.path.join(builddir, 'build')
+        return builddir
+
+    def get_mesonargs(self):
+        args = '%s %s' % (self.mesonargs,
+                          self.config.module_mesonargs.get(
+                              self.name, self.config.mesonargs))
+        return self.eval_args(args)
+
+    def do_configure(self, buildscript):
+        buildscript.set_action(_('Configuring'), self)
+        srcdir = self.get_srcdir(buildscript)
+        builddir = self.get_builddir(buildscript)
+        if not os.path.exists(builddir):
+            os.makedirs(builddir)
+        if os.path.exists(os.path.join(builddir, 'meson-private/coredata.dat')):
+            os.unlink(os.path.join(builddir, 'meson-private/coredata.dat'))
+        prefix = os.path.expanduser(buildscript.config.prefix)
+        if not inpath('meson', os.environ['PATH'].split(os.pathsep)):
+            raise CommandError(_('%s not found') % 'meson')
+        baseargs = '--prefix %s' % prefix
+        mesonargs = self.get_mesonargs()
+        cmd = 'meson %s %s %s' % (baseargs, mesonargs, srcdir)
+        buildscript.execute(cmd, cwd=builddir, extra_env=self.extra_env)
+    do_configure.depends = [PHASE_CHECKOUT]
+    do_configure.error_phases = [PHASE_FORCE_CHECKOUT]
+
+    def skip_configure(self, buildscript, last_phase):
+        # don't skip this stage if we got here from one of the
+        # following phases:
+        if last_phase in [self.PHASE_FORCE_CHECKOUT,
+                          self.PHASE_CLEAN,
+                          self.PHASE_BUILD,
+                          self.PHASE_INSTALL]:
+            return False
+
+        if buildscript.config.alwaysautogen:
+            return False
+
+        srcdir = self.get_srcdir(buildscript)
+        builddir = self.get_builddir(buildscript)
+        meson_marker_path = os.path.join(builddir, 'meson-private')
+        if not os.path.exists(meson_marker_path):
+            return False
+
+        return True
+
+    def do_clean(self, buildscript):
+        buildscript.set_action(_('Cleaning'), self)
+        builddir = self.get_builddir(buildscript)
+        buildscript.execute('ninja clean', cwd=builddir, extra_env=self.extra_env)
+    do_clean.depends = [PHASE_CONFIGURE]
+    do_clean.error_phases = [PHASE_FORCE_CHECKOUT, PHASE_CONFIGURE]
+
+    def do_build(self, buildscript):
+        buildscript.set_action(_('Building'), self)
+        builddir = self.get_builddir(buildscript)
+        buildscript.execute('ninja', cwd=builddir, extra_env=self.extra_env)
+    do_build.depends = [PHASE_CONFIGURE]
+    do_build.error_phases = [PHASE_FORCE_CHECKOUT]
+
+    def do_dist(self, buildscript):
+        buildscript.set_action(_('Creating tarball for'), self)
+        buildscript.execute('ninja dist', cwd=builddir, extra_env=self.extra_env)
+    do_dist.depends = [PHASE_CONFIGURE]
+    do_dist.error_phases = [PHASE_FORCE_CHECKOUT, PHASE_CONFIGURE]
+
+    def skip_install(self, buildscript, last_phase):
+        return self.config.noinstall or self.skip_install_phase
+
+    def do_install(self, buildscript):
+        buildscript.set_action(_('Installing'), self)
+        builddir = self.get_builddir(buildscript)
+        destdir = self.prepare_installroot(buildscript)
+        extra_env = (self.extra_env or {}).copy()
+        extra_env['DESTDIR'] = destdir
+        buildscript.execute('ninja install', cwd=builddir, extra_env=extra_env)
+        self.process_install(buildscript, self.get_revision())
+    do_install.depends = [PHASE_BUILD]
+
+    def xml_tag_and_attrs(self):
+        return 'meson', [('id', 'name', None),
+                         ('skip-install', 'skip_install_phase', False)]
+
+
+def parse_meson(node, config, uri, repositories, default_repo):
+    instance = MesonModule.parse_from_xml(node, config, uri, repositories, default_repo)
+
+    instance.dependencies += ['meson', instance.get_makecmd(config)]
+
+    instance.mesonargs = collect_args(instance, node, 'mesonargs')
+    instance.makeargs = collect_args(instance, node, 'makeargs')
+
+    if node.hasAttribute('skip-install'):
+        skip_install = node.getAttribute('skip-install')
+        if skip_install.lower() in ('true', 'yes'):
+            instance.skip_install_phase = True
+        else:
+            instance.skip_install_phase = False
+
+    return instance
+
+register_module_type('meson', parse_meson)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]