diff options
43 files changed, 529 insertions, 221 deletions
diff --git a/.appveyor.yml b/.appveyor.yml index 2ef722f..56a123a 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -68,7 +68,7 @@ install: - ps: (new-object net.webclient).DownloadFile('http://nirbheek.in/files/binaries/ninja/win32/ninja.exe', 'C:\projects\meson\ninja.exe') # Use the x86 python only when building for x86 for the cpython tests. # For all other archs (including, say, arm), use the x64 python. - - cmd: if %arch%==x86 (set MESON_PYTHON_PATH=C:\python34) else (set MESON_PYTHON_PATH=C:\python34-x64) + - cmd: if %arch%==x86 (set MESON_PYTHON_PATH=C:\python35) else (set MESON_PYTHON_PATH=C:\python35-x64) # Set paths for BOOST dll files - cmd: if %compiler%==msvc2015 ( if %arch%==x86 ( set "PATH=%PATH%;C:\Libraries\boost_1_59_0\lib32-msvc-14.0" ) else ( set "PATH=%PATH%;C:\Libraries\boost_1_59_0\lib64-msvc-14.0" ) ) diff --git a/.travis.yml b/.travis.yml index e69cb31..f077c9c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,4 +49,4 @@ script: withgit \ /bin/sh -c "cd /root && mkdir -p tools; wget -c http://nirbheek.in/files/binaries/ninja/linux-amd64/ninja -O /root/tools/ninja; chmod +x /root/tools/ninja; CC=$CC CXX=$CXX OBJC=$CC OBJCXX=$CXX PATH=/root/tools:$PATH MESON_FIXED_NINJA=1 ./run_tests.py -- $MESON_ARGS && chmod -R a+rwX .coverage" fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then SDKROOT=$(xcodebuild -version -sdk macosx Path) OBJC=$CC OBJCXX=$CXX PATH=$HOME/tools:$PATH MESON_FIXED_NINJA=1 ./run_tests.py --backend=ninja -- $MESON_ARGS ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then SDKROOT=$(xcodebuild -version -sdk macosx Path) CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib OBJC=$CC OBJCXX=$CXX PATH=$HOME/tools:$PATH MESON_FIXED_NINJA=1 ./run_tests.py --backend=ninja -- $MESON_ARGS ; fi diff --git a/ci/appveyor-install.bat b/ci/appveyor-install.bat index becc80a..1e60179 100644..100755 --- a/ci/appveyor-install.bat +++ b/ci/appveyor-install.bat @@ -1,5 +1,5 @@ set CACHE=C:\cache -set CYGWIN_MIRROR="http://cygwin.mirror.constant.com" +set CYGWIN_MIRROR=http://cygwin.mirror.constant.com if _%arch%_ == _x64_ set SETUP=setup-x86_64.exe && set CYGWIN_ROOT=C:\cygwin64 if _%arch%_ == _x86_ set SETUP=setup-x86.exe && set CYGWIN_ROOT=C:\cygwin @@ -7,5 +7,16 @@ if _%arch%_ == _x86_ set SETUP=setup-x86.exe && set CYGWIN_ROOT=C:\cygwin if not exist %CACHE% mkdir %CACHE% echo Updating Cygwin and installing ninja and test prerequisites -%CYGWIN_ROOT%\%SETUP% -qnNdO -R "%CYGWIN_ROOT%" -s "%CYGWIN_MIRROR%" -l "%CACHE%" -g -P "ninja,gcc-objc,gcc-objc++,libglib2.0-devel,zlib-devel,python3-pip" +%CYGWIN_ROOT%\%SETUP% -qnNdO -R "%CYGWIN_ROOT%" -s "%CYGWIN_MIRROR%" -l "%CACHE%" -g -P ^ +gcc-objc++,^ +gcc-objc,^ +gobject-introspection,^ +libboost-devel,^ +libglib2.0-devel,^ +libgtk3-devel,^ +ninja,^ +python3-pip,^ +vala,^ +zlib-devel + echo Install done diff --git a/data/macros.meson b/data/macros.meson index b31f77e..732b68d 100644 --- a/data/macros.meson +++ b/data/macros.meson @@ -34,8 +34,8 @@ %meson_test \ %ninja_test -C %{_vpath_builddir} || \ - { rc=$?; \ + ( rc=$?; \ echo "-----BEGIN TESTLOG-----"; \ cat %{_vpath_builddir}/meson-logs/testlog.txt; \ echo "-----END TESTLOG-----"; \ - exit $rc; } + exit $rc; ) diff --git a/docs/markdown/Users.md b/docs/markdown/Users.md index 959eac6..616fdc5 100644 --- a/docs/markdown/Users.md +++ b/docs/markdown/Users.md @@ -26,6 +26,7 @@ If you have a project that uses Meson that you want to add to this list, let us - [GtkDApp](https://gitlab.com/csoriano/GtkDApp), an application template for developing Flatpak apps with Gtk+ and D - [HexChat](https://github.com/hexchat/hexchat), a cross-platform IRC client in C - [Json-glib](https://git.gnome.org/browse/json-glib), GLib-based JSON manipulation library + - [Ksh](https://github.com/att/ast), a Korn Shell - [Libepoxy](https://github.com/anholt/libepoxy/), a library for handling OpenGL function pointer management - [Libgit2-glib](https://git.gnome.org/browse/libgit2-glib/), a GLib wrapper for libgit2 - [Libhttpseverywhere](https://github.com/grindhold/libhttpseverywhere), a library to enable httpseverywhere on any desktop app diff --git a/docs/markdown/index.md b/docs/markdown/index.md index 5f42cc7..6893564 100644 --- a/docs/markdown/index.md +++ b/docs/markdown/index.md @@ -16,7 +16,7 @@ code. ## Features -* multiplatform support for Linux, OSX, Windows, GCC, Clang, Visual Studio and others +* multiplatform support for Linux, macOS, Windows, GCC, Clang, Visual Studio and others * supported languages include C, C++, D, Fortran, Java, Rust * build definitions in a very readable and user friendly non-Turing complete DSL * cross compilation for many operating systems as well as bare metal @@ -35,8 +35,8 @@ The second way is via IRC. The channel to use is `#mesonbuild` at ## Development -All development on Meson is done on [GitHub -project](https://github.com/mesonbuild/meson). Instruction on +All development on Meson is done on the [GitHub +project](https://github.com/mesonbuild/meson). Instructions for contributing can be found on the [contribution page](Contributing.md). diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index f24bb64..2429fba 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -42,8 +42,12 @@ def ninja_quote(text): for char in ('$', ' ', ':'): text = text.replace(char, '$' + char) if '\n' in text: - raise MesonException('Ninja does not support newlines in rules. ' - 'Please report this error with a test case to the Meson bug tracker.') + errmsg = '''Ninja does not support newlines in rules. The content was: + +%s + +Please report this error with a test case to the Meson bug tracker.''' % text + raise MesonException(errmsg) return text diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 4a35bec..8a2e716 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -839,7 +839,7 @@ This will become a hard error in a future Meson release.''') self.external_deps.append(extpart) # Deps of deps. self.add_deps(dep.ext_deps) - elif isinstance(dep, dependencies.ExternalDependency): + elif isinstance(dep, dependencies.Dependency): self.external_deps.append(dep) self.process_sourcelist(dep.get_sources()) elif isinstance(dep, BuildTarget): diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index d4a91a7..0fdac8b 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -18,7 +18,7 @@ import pickle, os, uuid import sys from pathlib import PurePath from collections import OrderedDict -from .mesonlib import MesonException, commonpath +from .mesonlib import MesonException from .mesonlib import default_libdir, default_libexecdir, default_prefix import ast @@ -274,7 +274,7 @@ class CoreData: # commonpath will always return a path in the native format, so we # must use pathlib.PurePath to do the same conversion before # comparing. - if commonpath([value, prefix]) != str(PurePath(prefix)): + if os.path.commonpath([value, prefix]) != str(PurePath(prefix)): m = 'The value of the {!r} option is {!r} which must be a ' \ 'subdir of the prefix {!r}.\nNote that if you pass a ' \ 'relative path, it is assumed to be a subdir of prefix.' diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py index ea0711f..9614f1f 100644 --- a/mesonbuild/dependencies/misc.py +++ b/mesonbuild/dependencies/misc.py @@ -25,7 +25,6 @@ from pathlib import Path from .. import mlog from .. import mesonlib -from ..mesonlib import Popen_safe, extract_as_list from ..environment import detect_cpu_family from .base import ( @@ -52,7 +51,7 @@ from .base import ( # - boost_<module>.lib|.dll (shared) # where compiler is vc141 for example. # -# NOTE: -gb means runtime and build time debugging is on +# NOTE: -gd means runtime and build time debugging is on # -mt means threading=multi # # The `modules` argument accept library names. This is because every module that @@ -62,6 +61,47 @@ from .base import ( # * http://www.boost.org/doc/libs/1_65_1/doc/html/stacktrace/configuration_and_build.html # * http://www.boost.org/doc/libs/1_65_1/libs/math/doc/html/math_toolkit/main_tr1.html +# **On Unix**, official packaged versions of boost libraries follow the following schemes: +# +# Linux / Debian: libboost_<module>.so.1.66.0 -> libboost_<module>.so +# Linux / Red Hat: libboost_<module>.so.1.66.0 -> libboost_<module>.so +# Linux / OpenSuse: libboost_<module>.so.1.66.0 -> libboost_<module>.so +# Mac / homebrew: libboost_<module>.dylib + libboost_<module>-mt.dylib (location = /usr/local/lib) +# Mac / macports: libboost_<module>.dylib + libboost_<module>-mt.dylib (location = /opt/local/lib) +# +# Its not clear that any other abi tags (e.g. -gd) are used in official packages. +# +# On Linux systems, boost libs have multithreading support enabled, but without the -mt tag. +# +# Boost documentation recommends using complex abi tags like "-lboost_regex-gcc34-mt-d-1_36". +# (See http://www.boost.org/doc/libs/1_66_0/more/getting_started/unix-variants.html#library-naming) +# However, its not clear that any Unix distribution follows this scheme. +# Furthermore, the boost documentation for unix above uses examples from windows like +# "libboost_regex-vc71-mt-d-x86-1_34.lib", so apparently the abi tags may be more aimed at windows. +# +# Probably we should use the linker search path to decide which libraries to use. This will +# make it possible to find the macports boost libraries without setting BOOST_ROOT, and will +# also mean that it would be possible to use user-installed boost libraries when official +# packages are installed. +# +# We thus follow the following strategy: +# 1. Look for libraries using compiler.find_library( ) +# 1.1 On Linux, just look for boost_<module> +# 1.2 On other systems (e.g. Mac) look for boost_<module>-mt if multithreading. +# 1.3 Otherwise look for boost_<module> +# 2. Fall back to previous approach +# 2.1. Search particular directories. +# 2.2. Find boost libraries with unknown suffixes using file-name globbing. + +# TODO: Unix: Don't assume we know where the boost dir is, rely on -Idir and -Ldir being set. +# TODO: Determine a suffix (e.g. "-mt" or "") and use it. +# TODO: Get_win_link_args( ) and get_link_args( ) +# TODO: Genericize: 'args += ['-L' + dir] => args += self.compiler.get_linker_search_args(dir) +# TODO: Allow user to specify suffix in BOOST_SUFFIX, or add specific options like BOOST_DEBUG for 'd' for debug. +# TODO: fix cross: +# is_windows() -> for_windows(self.want_cross, self.env) +# is_osx() and self.want_cross -> for_darwin(self.want_cross, self.env) + class BoostDependency(ExternalDependency): def __init__(self, environment, kwargs): super().__init__('boost', environment, 'cpp', kwargs) @@ -103,7 +143,7 @@ class BoostDependency(ExternalDependency): else: self.incdir = self.detect_nix_incdir() - if self.incdir is None: + if self.incdir is None and mesonlib.is_windows(): self.log_fail() return @@ -112,7 +152,7 @@ class BoostDependency(ExternalDependency): # previous versions of meson allowed include dirs as modules remove = [] for m in invalid_modules: - if m in os.listdir(os.path.join(self.incdir, 'boost')): + if m in BOOST_DIRS: mlog.warning('Requested boost library', mlog.bold(m), 'that doesn\'t exist. ' 'This will be an error in the future') remove.append(m) @@ -121,7 +161,7 @@ class BoostDependency(ExternalDependency): invalid_modules = [x for x in invalid_modules if x not in remove] if invalid_modules: - mlog.warning('Invalid Boost modules: ' + ', '.join(invalid_modules)) + mlog.log(mlog.red('ERROR:'), 'Invalid Boost modules: ' + ', '.join(invalid_modules)) self.log_fail() return @@ -138,6 +178,7 @@ class BoostDependency(ExternalDependency): else: self.log_fail() + def log_fail(self): module_str = ', '.join(self.requested_modules) mlog.log("Dependency Boost (%s) found:" % module_str, mlog.red('NO')) @@ -172,10 +213,8 @@ class BoostDependency(ExternalDependency): return res def detect_nix_incdir(self): - for root in self.boost_roots: - incdir = os.path.join(root, 'include', 'boost') - if os.path.isdir(incdir): - return os.path.join(root, 'include') + if self.boost_root: + return os.path.join(self.boost_root, 'include') return None # FIXME: Should pick a version that matches the requested version @@ -217,7 +256,7 @@ class BoostDependency(ExternalDependency): return args def get_requested(self, kwargs): - candidates = extract_as_list(kwargs, 'modules') + candidates = mesonlib.extract_as_list(kwargs, 'modules') for c in candidates: if not isinstance(c, str): raise DependencyException('Boost module argument is not a string.') @@ -231,25 +270,30 @@ class BoostDependency(ExternalDependency): def detect_version(self): try: - ifile = open(os.path.join(self.incdir, 'boost', 'version.hpp')) - except FileNotFoundError: + version = self.compiler.get_define('BOOST_LIB_VERSION', '#include <boost/version.hpp>', self.env, self.get_compile_args(), []) + except mesonlib.EnvironmentException: return except TypeError: return - with ifile: - for line in ifile: - if line.startswith("#define") and 'BOOST_LIB_VERSION' in line: - ver = line.split()[-1] - ver = ver[1:-1] - self.version = ver.replace('_', '.') - self.is_found = True - return + # Remove quotes + version = version[1:-1] + # Fix version string + self.version = version.replace('_', '.') + self.is_found = True def detect_lib_modules(self): if mesonlib.is_windows(): return self.detect_lib_modules_win() return self.detect_lib_modules_nix() + def modname_from_filename(self, filename): + modname = os.path.basename(filename) + modname = modname.split('.', 1)[0] + modname = modname.split('-', 1)[0] + if modname.startswith('libboost'): + modname = modname[3:] + return modname + def detect_lib_modules_win(self): arch = detect_cpu_family(self.env.coredata.compilers) comp_ts_version = self.env.detect_cpp_compiler(self.want_cross).get_toolset_version() @@ -291,12 +335,11 @@ class BoostDependency(ExternalDependency): libname = libname + '-gd' libname = libname + "-{}.lib".format(self.version.replace('.', '_')) if os.path.isfile(os.path.join(self.libdir, libname)): - modname = libname.split('-', 1)[0][3:] - self.lib_modules[modname] = libname + self.lib_modules[self.modname_from_filename(libname)] = [libname] else: libname = "lib{}.lib".format(name) if os.path.isfile(os.path.join(self.libdir, libname)): - self.lib_modules[name[3:]] = libname + self.lib_modules[name[3:]] = [libname] # globber1 applies to a layout=system installation # globber2 applies to a layout=versioned installation @@ -309,24 +352,33 @@ class BoostDependency(ExternalDependency): globber2 = globber2 + '-{}'.format(self.version.replace('.', '_')) globber2_matches = glob.glob(os.path.join(self.libdir, globber2 + '.lib')) for entry in globber2_matches: - (_, fname) = os.path.split(entry) - modname = fname.split('-', 1) - if len(modname) > 1: - modname = modname[0] - else: - modname = modname.split('.', 1)[0] - if self.static: - modname = modname[3:] - self.lib_modules[modname] = fname + fname = os.path.basename(entry) + self.lib_modules[self.modname_from_filename(fname)] = [fname] if len(globber2_matches) == 0: for entry in glob.glob(os.path.join(self.libdir, globber1 + '.lib')): - (_, fname) = os.path.split(entry) - modname = fname.split('.', 1)[0] if self.static: - modname = modname[3:] - self.lib_modules[modname] = fname + fname = os.path.basename(entry) + self.lib_modules[self.modname_from_filename(fname)] = [fname] def detect_lib_modules_nix(self): + all_found = True + for module in self.requested_modules: + args = None + libname = 'boost_' + module + if self.is_multithreading and mesonlib.for_darwin(self.want_cross, self.env): + # - Linux leaves off -mt but libraries are multithreading-aware. + # - Mac requires -mt for multithreading, so should not fall back to non-mt libraries. + libname = libname + '-mt' + args = self.compiler.find_library(libname, self.env, self.extra_lib_dirs()) + if args is None: + mlog.debug('Couldn\'t find library "{}" for boost module "{}"'.format(module, libname)) + all_found = False + else: + mlog.debug('Link args for boost module "{}" are {}'.format(module, args)) + self.lib_modules['boost_' + module] = args + if all_found: + return + if self.static: libsuffix = 'a' elif mesonlib.is_osx() and not self.want_cross: @@ -345,21 +397,25 @@ class BoostDependency(ExternalDependency): for name in self.need_static_link: libname = 'lib{}.a'.format(name) if os.path.isfile(os.path.join(libdir, libname)): - self.lib_modules[name] = libname + self.lib_modules[name] = [libname] for entry in glob.glob(os.path.join(libdir, globber)): - lib = os.path.basename(entry) - name = lib.split('.')[0][3:] # I'm not 100% sure what to do here. Some distros # have modules such as thread only as -mt versions. # On debian all packages are built threading=multi # but not suffixed with -mt. # FIXME: implement detect_lib_modules_{debian, redhat, ...} + # FIXME: this wouldn't work with -mt-gd either. -BDR if self.is_multithreading and mesonlib.is_debianlike(): - self.lib_modules[name] = lib + pass elif self.is_multithreading and entry.endswith('-mt.{}'.format(libsuffix)): - self.lib_modules[name] = lib + pass elif not entry.endswith('-mt.{}'.format(libsuffix)): - self.lib_modules[name] = lib + pass + else: + continue + modname = self.modname_from_filename(entry) + if modname not in self.lib_modules: + self.lib_modules[modname] = [entry] def get_win_link_args(self): args = [] @@ -367,26 +423,25 @@ class BoostDependency(ExternalDependency): if self.libdir: args.append('-L' + self.libdir) for lib in self.requested_modules: - args.append(self.lib_modules['boost_' + lib]) + args += self.lib_modules['boost_' + lib] return args + def extra_lib_dirs(self): + dirs = [] + if self.boost_root: + dirs = [os.path.join(self.boost_root, 'lib')] + elif self.libdir: + dirs = [self.libdir] + return dirs + def get_link_args(self): if mesonlib.is_windows(): return self.get_win_link_args() args = [] - if self.boost_root: - args.append('-L' + os.path.join(self.boost_root, 'lib')) - elif self.libdir: - args.append('-L' + self.libdir) + for dir in self.extra_lib_dirs(): + args += ['-L' + dir] for lib in self.requested_modules: - # The compiler's library detector is the most reliable so use that first. - boost_lib = 'boost_' + lib - default_detect = self.compiler.find_library(boost_lib, self.env, []) - if default_detect is not None: - args += default_detect - elif boost_lib in self.lib_modules: - linkcmd = '-l' + boost_lib - args.append(linkcmd) + args += self.lib_modules['boost_' + lib] return args def get_sources(self): @@ -963,3 +1018,116 @@ BOOST_LIBS = [ 'boost_type_erasure', 'boost_wave' ] + +BOOST_DIRS = [ + 'lambda', + 'optional', + 'convert', + 'system', + 'uuid', + 'archive', + 'align', + 'timer', + 'chrono', + 'gil', + 'logic', + 'signals', + 'predef', + 'tr1', + 'multi_index', + 'property_map', + 'multi_array', + 'context', + 'random', + 'endian', + 'circular_buffer', + 'proto', + 'assign', + 'format', + 'math', + 'phoenix', + 'graph', + 'locale', + 'mpl', + 'pool', + 'unordered', + 'core', + 'exception', + 'ptr_container', + 'flyweight', + 'range', + 'typeof', + 'thread', + 'move', + 'spirit', + 'dll', + 'compute', + 'serialization', + 'ratio', + 'msm', + 'config', + 'metaparse', + 'coroutine2', + 'qvm', + 'program_options', + 'concept', + 'detail', + 'hana', + 'concept_check', + 'compatibility', + 'variant', + 'type_erasure', + 'mpi', + 'test', + 'fusion', + 'log', + 'sort', + 'local_function', + 'units', + 'functional', + 'preprocessor', + 'integer', + 'container', + 'polygon', + 'interprocess', + 'numeric', + 'iterator', + 'wave', + 'lexical_cast', + 'multiprecision', + 'utility', + 'tti', + 'asio', + 'dynamic_bitset', + 'algorithm', + 'xpressive', + 'bimap', + 'signals2', + 'type_traits', + 'regex', + 'statechart', + 'parameter', + 'icl', + 'python', + 'lockfree', + 'intrusive', + 'io', + 'pending', + 'geometry', + 'tuple', + 'iostreams', + 'heap', + 'atomic', + 'filesystem', + 'smart_ptr', + 'function', + 'fiber', + 'type_index', + 'accumulators', + 'function_types', + 'coroutine', + 'vmd', + 'date_time', + 'property_tree', + 'bind' +] diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index 0c9a2f3..e5aa43e 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -731,7 +731,7 @@ class Environment: return compilers.LLVMDCompiler(exelist, version, is_cross, full_version=full_version) elif 'gdc' in out: return compilers.GnuDCompiler(exelist, version, is_cross, full_version=full_version) - elif 'Digital Mars' in out: + elif 'The D Language Foundation' in out or 'Digital Mars' in out: return compilers.DmdDCompiler(exelist, version, is_cross, full_version=full_version) raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"') diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index e8fb081..48b8d82 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -1574,7 +1574,7 @@ class Interpreter(InterpreterBase): modname = args[0] if modname.startswith('unstable-'): plainname = modname.split('-', 1)[1] - mlog.warning('Module %s has no backwards or forwards compatibility and might not exist in future releases.' % modname) + mlog.warning('Module %s has no backwards or forwards compatibility and might not exist in future releases' % modname, location=node) modname = 'unstable_' + plainname if modname not in self.environment.coredata.modules: try: @@ -1883,10 +1883,14 @@ to directly access options of other subprojects.''') raise InvalidCode('Second call to project().') if not self.is_subproject() and 'subproject_dir' in kwargs: spdirname = kwargs['subproject_dir'] - if '/' in spdirname or '\\' in spdirname: - raise InterpreterException('Subproject_dir must not contain a path segment.') + if not isinstance(spdirname, str): + raise InterpreterException('Subproject_dir must be a string') + if os.path.isabs(spdirname): + raise InterpreterException('Subproject_dir must not be an absolute path.') if spdirname.startswith('.'): raise InterpreterException('Subproject_dir must not begin with a period.') + if '..' in spdirname: + raise InterpreterException('Subproject_dir must not contain a ".." segment.') self.subproject_dir = spdirname if 'meson_version' in kwargs: @@ -1935,7 +1939,7 @@ to directly access options of other subprojects.''') @noKwargs def func_warning(self, node, args, kwargs): argstr = self.get_message_string_arg(node) - mlog.warning('%s in file %s, line %d' % (argstr, os.path.join(node.subdir, 'meson.build'), node.lineno)) + mlog.warning(argstr, location=node) @noKwargs def func_error(self, node, args, kwargs): @@ -2140,8 +2144,8 @@ to directly access options of other subprojects.''') # Check if we've already searched for and found this dep if identifier in self.coredata.deps: cached_dep = self.coredata.deps[identifier] - mlog.log('Cached dependency', mlog.bold(name), - 'found:', mlog.green('YES')) + mlog.log('Dependency', mlog.bold(name), + 'found:', mlog.green('YES'), '(cached)') else: # Check if exactly the same dep with different version requirements # was found already. @@ -2158,13 +2162,59 @@ to directly access options of other subprojects.''') break return identifier, cached_dep + @staticmethod + def check_subproject_version(wanted, found): + if wanted == 'undefined': + return True + if found == 'undefined' or not mesonlib.version_compare(found, wanted): + return False + return True + + def get_subproject_dep(self, name, dirname, varname, required): + try: + dep = self.subprojects[dirname].get_variable_method([varname], {}) + except KeyError: + if required: + raise DependencyException('Could not find dependency {} in subproject {}' + ''.format(varname, dirname)) + # If the dependency is not required, don't raise an exception + subproj_path = os.path.join(self.subproject_dir, dirname) + mlog.log('Dependency', mlog.bold(name), 'from subproject', + mlog.bold(subproj_path), 'found:', mlog.red('NO')) + return None + if not isinstance(dep, DependencyHolder): + raise InvalidCode('Fetched variable {!r} in the subproject {!r} is ' + 'not a dependency object.'.format(varname, dirname)) + return dep + + def _find_cached_fallback_dep(self, name, dirname, varname, wanted, required): + if dirname not in self.subprojects: + return False + dep = self.get_subproject_dep(name, dirname, varname, required) + if not dep: + return False + found = dep.version_method([], {}) + if self.check_subproject_version(wanted, found): + subproj_path = os.path.join(self.subproject_dir, dirname) + mlog.log('Dependency', mlog.bold(name), 'from subproject', + mlog.bold(subproj_path), 'found:', mlog.green('YES'), '(cached)') + return dep + if required: + raise DependencyException('Version {} of subproject dependency {} already ' + 'cached, requested incompatible version {} for ' + 'dep {}'.format(found, dirname, wanted, name)) + return None + @permittedKwargs(permitted_kwargs['dependency']) def func_dependency(self, node, args, kwargs): self.validate_arguments(args, 1, [str]) + required = kwargs.get('required', True) + if not isinstance(required, bool): + raise DependencyException('Keyword "required" must be a boolean.') name = args[0] if name == '': - if kwargs.get('required', True): + if required: raise InvalidArguments('Dependency is both required and not-found') return DependencyHolder(Dependency('not-found', {})) @@ -2174,7 +2224,7 @@ to directly access options of other subprojects.''') identifier, cached_dep = self._find_cached_dep(name, kwargs) if cached_dep: - if kwargs.get('required', True) and not cached_dep.found(): + if required and not cached_dep.found(): m = 'Dependency {!r} was already checked and was not found' raise DependencyException(m.format(name)) dep = cached_dep @@ -2183,26 +2233,10 @@ to directly access options of other subprojects.''') # a higher level project, try to use it first. if 'fallback' in kwargs: dirname, varname = self.get_subproject_infos(kwargs) - required = kwargs.get('required', True) wanted = kwargs.get('version', 'undefined') - if not isinstance(required, bool): - raise DependencyException('Keyword "required" must be a boolean.') - if dirname in self.subprojects: - found = self.subprojects[dirname].held_object.project_version - valid_version = wanted == 'undefined' or mesonlib.version_compare(found, wanted) - if required and not valid_version: - m = 'Version {} of {} already loaded, requested incompatible version {}' - raise DependencyException(m.format(found, dirname, wanted)) - elif valid_version: - mlog.log('Found a', mlog.green('(cached)'), 'subproject', - mlog.bold(os.path.join(self.subproject_dir, dirname)), 'for', - mlog.bold(name)) - subproject = self.subprojects[dirname] - try: - # Never add fallback deps to self.coredata.deps - return subproject.get_variable_method([varname], {}) - except KeyError: - pass + dep = self._find_cached_fallback_dep(name, dirname, varname, wanted, required) + if dep: + return dep # We need to actually search for this dep exception = None @@ -2292,32 +2326,21 @@ root and issuing %s. mlog.bold(os.path.join(self.subproject_dir, dirname)), 'for the dependency', mlog.bold(name)) return None - try: - dep = self.subprojects[dirname].get_variable_method([varname], {}) - except KeyError: - if kwargs.get('required', True): - m = 'Fallback variable {!r} in the subproject {!r} does not exist' - raise DependencyException(m.format(varname, dirname)) - # If the dependency is not required, don't raise an exception - mlog.log('Also couldn\'t find the dependency', mlog.bold(name), - 'in the fallback subproject', - mlog.bold(os.path.join(self.subproject_dir, dirname))) + dep = self.get_subproject_dep(name, dirname, varname, kwargs.get('required', True)) + if not dep: return None - if not isinstance(dep, DependencyHolder): - raise InvalidCode('Fallback variable {!r} in the subproject {!r} is ' - 'not a dependency object.'.format(varname, dirname)) + subproj_path = os.path.join(self.subproject_dir, dirname) # Check if the version of the declared dependency matches what we want if 'version' in kwargs: wanted = kwargs['version'] found = dep.version_method([], {}) - if found == 'undefined' or not mesonlib.version_compare(found, wanted): - mlog.log('Subproject', mlog.bold(dirname), 'dependency', + if not self.check_subproject_version(wanted, found): + mlog.log('Subproject', mlog.bold(subproj_path), 'dependency', mlog.bold(varname), 'version is', mlog.bold(found), 'but', mlog.bold(wanted), 'is required.') return None - mlog.log('Found a', mlog.green('fallback'), 'subproject', - mlog.bold(os.path.join(self.subproject_dir, dirname)), 'for', - mlog.bold(name)) + mlog.log('Dependency', mlog.bold(name), 'from subproject', + mlog.bold(subproj_path), 'found:', mlog.green('YES')) return dep @permittedKwargs(permitted_kwargs['executable']) @@ -2732,7 +2755,7 @@ root and issuing %s. mlog.warning( "The variable(s) %s in the input file %s are not " "present in the given configuration data" % ( - var_list, inputfile)) + var_list, inputfile), location=node) else: mesonlib.dump_conf_header(ofile_abs, conf.held_object) conf.mark_used() diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py index 91f4bd3..9dc6b0f 100644 --- a/mesonbuild/interpreterbase.py +++ b/mesonbuild/interpreterbase.py @@ -18,7 +18,7 @@ from . import mparser, mesonlib, mlog from . import environment, dependencies -import os, copy, re +import os, copy, re, types from functools import wraps # Decorators for method calls. @@ -63,17 +63,19 @@ class permittedKwargs: def __call__(self, f): @wraps(f) def wrapped(s, node_or_state, args, kwargs): + loc = types.SimpleNamespace() if hasattr(s, 'subdir'): - subdir = s.subdir - lineno = s.current_lineno + loc.subdir = s.subdir + loc.lineno = s.current_lineno elif hasattr(node_or_state, 'subdir'): - subdir = node_or_state.subdir - lineno = node_or_state.current_lineno + loc.subdir = node_or_state.subdir + loc.lineno = node_or_state.current_lineno + else: + loc = None for k in kwargs: if k not in self.permitted: - fname = os.path.join(subdir, environment.build_filename) - mlog.warning('''Passed invalid keyword argument "%s" in %s line %d. -This will become a hard error in the future.''' % (k, fname, lineno)) + mlog.warning('''Passed invalid keyword argument "{}"'''.format(k), location=loc) + mlog.warning('This will become a hard error in the future.') return f(s, node_or_state, args, kwargs) return wrapped diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py index 6bf31db..de83e90 100644 --- a/mesonbuild/mesonlib.py +++ b/mesonbuild/mesonlib.py @@ -25,29 +25,40 @@ from glob import glob def detect_meson_py_location(): c = sys.argv[0] - c_fname = os.path.split(c)[1] - if c_fname == 'meson' or c_fname == 'meson.py': - # $ /foo/meson.py <args> - if os.path.isabs(c): - return c - # $ meson <args> (gets run from /usr/bin/meson) + c_dir, c_fname = os.path.split(c) + + # get the absolute path to the <mesontool> folder + m_dir = None + if os.path.isabs(c): + # $ /foo/<mesontool>.py <args> + m_dir = c_dir + elif c_dir == '': + # $ <mesontool> <args> (gets run from /usr/bin/<mesontool>) in_path_exe = shutil.which(c_fname) if in_path_exe: - # Special case: when run like "./meson.py <opts>" and user has - # period in PATH, we need to expand it out, because, for example, + m_dir, c_fname = os.path.split(in_path_exe) + # Special case: when run like "./meson.py <opts>", + # we need to expand it out, because, for example, # "ninja test" will be run from a different directory. - if '.' in os.environ['PATH'].split(':'): - p, f = os.path.split(in_path_exe) - if p == '' or p == '.': - return os.path.join(os.getcwd(), f) - return in_path_exe - # $ python3 ./meson.py <args> - if os.path.exists(c): - return os.path.join(os.getcwd(), c) - + if m_dir == '.': + m_dir = os.getcwd() + else: + m_dir = os.path.abspath(c_dir) + + # find meson in m_dir + if m_dir is not None: + for fname in ['meson', 'meson.py']: + m_path = os.path.join(m_dir, fname) + if os.path.exists(m_path): + return m_path + + # No meson found, which means that either: + # a) meson is not installed + # b) meson is installed to a non-standard location + # c) the script that invoked mesonlib is not the one of meson tools (e.g. run_unittests.py) # The only thing remaining is to try to find the bundled executable and # pray distro packagers have not moved it. - fname = os.path.join(os.path.dirname(__file__), '..', 'meson.py') + fname = os.path.normpath(os.path.join(os.path.dirname(__file__), '..', 'meson.py')) if not os.path.exists(fname): raise RuntimeError('Could not determine how to run Meson. Please file a bug with details.') return fname @@ -309,6 +320,18 @@ def for_cygwin(is_cross, env): return env.cross_info.config['host_machine']['system'] == 'cygwin' return False +def for_linux(is_cross, env): + """ + Host machine is linux? + + Note: 'host' is the machine on which compiled binaries will run + """ + if not is_cross: + return is_linux() + elif env.cross_info.has_host(): + return env.cross_info.config['host_machine']['system'] == 'linux' + return False + def for_darwin(is_cross, env): """ Host machine is Darwin (iOS/OS X)? @@ -690,31 +713,6 @@ def Popen_safe_legacy(args, write=None, stderr=subprocess.PIPE, **kwargs): e = e.decode(errors='replace').replace('\r\n', '\n') return p, o, e -def commonpath(paths): - ''' - For use on Python 3.4 where os.path.commonpath is not available. - We currently use it everywhere so this receives enough testing. - ''' - # XXX: Replace me with os.path.commonpath when we start requiring Python 3.5 - import pathlib - if not paths: - raise ValueError('arg is an empty sequence') - common = pathlib.PurePath(paths[0]) - for path in paths[1:]: - new = [] - path = pathlib.PurePath(path) - for c, p in zip(common.parts, path.parts): - if c != p: - break - new.append(c) - # Don't convert '' into '.' - if not new: - common = '' - break - new = os.path.join(*new) - common = pathlib.PurePath(new) - return str(common) - def iter_regexin_iter(regexiter, initer): ''' Takes each regular expression in @regexiter and tries to search for it in diff --git a/mesonbuild/mesonmain.py b/mesonbuild/mesonmain.py index 12bbd69..e48122f 100644 --- a/mesonbuild/mesonmain.py +++ b/mesonbuild/mesonmain.py @@ -279,8 +279,8 @@ def run_script_command(args): return cmdfunc(cmdargs) def run(original_args, mainfile=None): - if sys.version_info < (3, 4): - print('Meson works correctly only with python 3.4+.') + if sys.version_info < (3, 5): + print('Meson works correctly only with python 3.5+.') print('You have python %s.' % sys.version) print('Please update your environment') return 1 diff --git a/mesonbuild/mlog.py b/mesonbuild/mlog.py index a0d07ec..aa2ac20 100644 --- a/mesonbuild/mlog.py +++ b/mesonbuild/mlog.py @@ -103,6 +103,13 @@ def log(*args, **kwargs): force_print(*arr, **kwargs) def warning(*args, **kwargs): + from . import environment + + if kwargs.get('location'): + location = kwargs['location'] + del kwargs['location'] + args += ('in file {}, line {}.'.format(os.path.join(location.subdir, environment.build_filename), location.lineno),) + log(yellow('WARNING:'), *args, **kwargs) # Format a list for logging purposes as a string. It separates diff --git a/mesonbuild/mparser.py b/mesonbuild/mparser.py index 782b7a7..eb03393 100644 --- a/mesonbuild/mparser.py +++ b/mesonbuild/mparser.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os, re +import re from .mesonlib import MesonException from . import mlog @@ -368,7 +368,8 @@ class ArgumentNode: def set_kwarg(self, name, value): if name in self.kwargs: - mlog.warning('Keyword argument "%s" defined multiple times in file %s, line %d. This will be an error in future Meson releases.' % (name, os.path.join(self.subdir, 'meson.build'), self.lineno)) + mlog.warning('Keyword argument "{}" defined multiple times'.format(name), location=self) + mlog.warning('This will be an error in future Meson releases.') self.kwargs[name] = value def num_args(self): diff --git a/mesonbuild/wrap/wraptool.py b/mesonbuild/wrap/wraptool.py index 00115cb..0bdc417 100644 --- a/mesonbuild/wrap/wraptool.py +++ b/mesonbuild/wrap/wraptool.py @@ -40,6 +40,7 @@ Commands: update - update the project to its newest available release info - show available versions of a project status - show installed and available versions of your projects + promote - bring a subsubproject up to the master project ''' diff --git a/run_project_tests.py b/run_project_tests.py index 323f9a3..d442dd3 100755 --- a/run_project_tests.py +++ b/run_project_tests.py @@ -185,6 +185,7 @@ def get_relative_files_list_from_dir(fromdir): def platform_fix_name(fname, compiler): if '?lib' in fname: if mesonlib.is_cygwin(): + fname = re.sub(r'lib/\?lib(.*)\.so$', r'bin/cyg\1.dll', fname) fname = re.sub(r'\?lib(.*)\.dll$', r'cyg\1.dll', fname) else: fname = re.sub(r'\?lib', 'lib', fname) @@ -496,7 +497,8 @@ def detect_tests_to_run(): # TODO: Set BOOST_ROOT in .appveyor.yml gathered_tests += [('framework', ['test cases/frameworks/1 boost'], 'BOOST_ROOT' not in os.environ)] elif mesonlib.is_osx() or mesonlib.is_cygwin(): - gathered_tests += [('framework', gather_tests('test cases/frameworks'), True)] + # Just do the BOOST test + gathered_tests += [('framework', ['test cases/frameworks/1 boost'], False)] else: gathered_tests += [('framework', gather_tests('test cases/frameworks'), False)] return gathered_tests diff --git a/run_unittests.py b/run_unittests.py index dc2429a..08ad632 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -191,26 +191,6 @@ class InternalTests(unittest.TestCase): l.append_direct('-lbar') self.assertEqual(l, ['-Lfoodir', '-lfoo', '-Lbardir', '-lbar', '-lbar']) - def test_commonpath(self): - from os.path import sep - commonpath = mesonbuild.mesonlib.commonpath - self.assertRaises(ValueError, commonpath, []) - self.assertEqual(commonpath(['/usr', '/usr']), sep + 'usr') - self.assertEqual(commonpath(['/usr', '/usr/']), sep + 'usr') - self.assertEqual(commonpath(['/usr', '/usr/bin']), sep + 'usr') - self.assertEqual(commonpath(['/usr/', '/usr/bin']), sep + 'usr') - self.assertEqual(commonpath(['/usr/./', '/usr/bin']), sep + 'usr') - self.assertEqual(commonpath(['/usr/bin', '/usr/bin']), sep + 'usr' + sep + 'bin') - self.assertEqual(commonpath(['/usr//bin', '/usr/bin']), sep + 'usr' + sep + 'bin') - self.assertEqual(commonpath(['/usr/./bin', '/usr/bin']), sep + 'usr' + sep + 'bin') - self.assertEqual(commonpath(['/usr/local', '/usr/lib']), sep + 'usr') - self.assertEqual(commonpath(['/usr', '/bin']), sep) - self.assertEqual(commonpath(['/usr', 'bin']), '') - self.assertEqual(commonpath(['blam', 'bin']), '') - prefix = '/some/path/to/prefix' - libdir = '/some/path/to/prefix/libdir' - self.assertEqual(commonpath([prefix, libdir]), str(PurePath(prefix))) - def test_string_templates_substitution(self): dictfunc = mesonbuild.mesonlib.get_filenames_templates_dict substfunc = mesonbuild.mesonlib.substitute_values @@ -1710,10 +1690,16 @@ int main(int argc, char **argv) { def test_warning_location(self): tdir = os.path.join(self.unit_test_dir, '20 warning location') out = self.init(tdir) - self.assertRegex(out, r'WARNING: Keyword argument "link_with" defined multiple times in file meson.build, line 4') - self.assertRegex(out, r'WARNING: Keyword argument "link_with" defined multiple times in file sub' + re.escape(os.path.sep) + r'meson.build, line 3') - self.assertRegex(out, r'WARNING: a warning of some sort in file meson.build, line 6') - self.assertRegex(out, r'WARNING: subdir warning in file sub' + re.escape(os.path.sep) + r'meson.build, line 4') + for expected in [ + r'WARNING: Keyword argument "link_with" defined multiple times in file meson.build, line 4', + r'WARNING: Keyword argument "link_with" defined multiple times in file sub' + os.path.sep + r'meson.build, line 3', + r'WARNING: a warning of some sort in file meson.build, line 6', + r'WARNING: subdir warning in file sub' + os.path.sep + r'meson.build, line 4', + r'WARNING: Module unstable-simd has no backwards or forwards compatibility and might not exist in future releases in file meson.build, line 7', + r"WARNING: The variable(s) 'MISSING' in the input file conf.in are not present in the given configuration data in file meson.build, line 10", + r'WARNING: Passed invalid keyword argument "invalid" in file meson.build, line 1' + ]: + self.assertRegex(out, re.escape(expected)) def test_templates(self): ninja = detect_ninja() @@ -1902,6 +1888,29 @@ class FailureTests(BasePlatformTests): return raise unittest.SkipTest("objc and objcpp found, can't test detection failure") + def test_subproject_variables(self): + ''' + Test that: + 1. The correct message is outputted when a not-required dep is not + found and the fallback subproject is also not found. + 2. A not-found not-required dep with a fallback subproject outputs the + correct message when the fallback subproject is found but the + variable inside it is not. + 3. A fallback dependency is found from the subproject parsed in (2) + 4. A not-required fallback dependency is not found because the + subproject failed to parse. + ''' + tdir = os.path.join(self.unit_test_dir, '20 subproj dep variables') + out = self.init(tdir, inprocess=True) + self.assertRegex(out, r"Also couldn't find a fallback subproject " + "in.*subprojects.*nosubproj.*for the dependency.*somedep") + self.assertRegex(out, r'Dependency.*somenotfounddep.*from subproject.*' + 'subprojects.*somesubproj.*found:.*NO') + self.assertRegex(out, r'Dependency.*zlibproxy.*from subproject.*' + 'subprojects.*somesubproj.*found:.*YES.*(cached)') + self.assertRegex(out, r'Also couldn\'t find a fallback subproject in ' + '.*subprojects.*failingsubproj.*for the dependency.*somedep') + class WindowsTests(BasePlatformTests): ''' diff --git a/test cases/common/171 not-found dependency/meson.build b/test cases/common/171 not-found dependency/meson.build index 7d92f5a..85505ee 100644 --- a/test cases/common/171 not-found dependency/meson.build +++ b/test cases/common/171 not-found dependency/meson.build @@ -1,4 +1,4 @@ -project('dep-test') +project('dep-test', 'c') dep = dependency('', required:false) if dep.found() @@ -6,3 +6,6 @@ if dep.found() endif assert(dep.type_name() == 'not-found', 'dependency should be of type "not-found" not ' + dep.type_name()) + +library('testlib', 'testlib.c', dependencies: [dep]) +subdir('sub', if_found: dep) diff --git a/test cases/common/171 not-found dependency/sub/meson.build b/test cases/common/171 not-found dependency/sub/meson.build new file mode 100644 index 0000000..2a33cae --- /dev/null +++ b/test cases/common/171 not-found dependency/sub/meson.build @@ -0,0 +1 @@ +error('should be disabled by subdir(if_found:)') diff --git a/test cases/common/171 not-found dependency/testlib.c b/test cases/common/171 not-found dependency/testlib.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test cases/common/171 not-found dependency/testlib.c diff --git a/test cases/frameworks/1 boost/extralib.cpp b/test cases/frameworks/1 boost/extralib.cpp index 6a3e9e4..e5ab1b0 100644 --- a/test cases/frameworks/1 boost/extralib.cpp +++ b/test cases/frameworks/1 boost/extralib.cpp @@ -1,3 +1,5 @@ +#define _XOPEN_SOURCE 500 + #include <iostream> #include <boost/log/trivial.hpp> #include <boost/log/expressions.hpp> diff --git a/test cases/frameworks/11 gir subproject/gir/meson.build b/test cases/frameworks/11 gir subproject/gir/meson.build index 48e0a47..fe40dc6 100644 --- a/test cases/frameworks/11 gir subproject/gir/meson.build +++ b/test cases/frameworks/11 gir subproject/gir/meson.build @@ -31,6 +31,9 @@ message('TEST: ' + girsubproject.outdir()) envdata = environment() envdata.append('GI_TYPELIB_PATH', girsubproject.outdir(), 'subprojects/mesongir', separator : ':') envdata.append('LD_LIBRARY_PATH', girsubproject.outdir(), 'subprojects/mesongir') +if ['windows', 'cygwin'].contains(host_machine.system()) + envdata.append('PATH', girsubproject.outdir(), 'subprojects/mesongir') +endif test('gobject introspection/subproject/c', girexe) test('gobject introspection/subproject/py', find_program('prog.py'), diff --git a/test cases/frameworks/11 gir subproject/installed_files.txt b/test cases/frameworks/11 gir subproject/installed_files.txt index 434481e..87d49a1 100644 --- a/test cases/frameworks/11 gir subproject/installed_files.txt +++ b/test cases/frameworks/11 gir subproject/installed_files.txt @@ -2,5 +2,5 @@ usr/lib/girepository-1.0/Meson-1.0.typelib usr/lib/girepository-1.0/MesonSub-1.0.typelib usr/share/gir-1.0/Meson-1.0.gir usr/share/gir-1.0/MesonSub-1.0.gir -usr/lib/libgirsubproject.so -usr/lib/libgirlib.so +usr/lib/?libgirsubproject.so +usr/lib/?libgirlib.so diff --git a/test cases/frameworks/12 multiple gir/installed_files.txt b/test cases/frameworks/12 multiple gir/installed_files.txt index 9fb51bf..a5d16bc 100644 --- a/test cases/frameworks/12 multiple gir/installed_files.txt +++ b/test cases/frameworks/12 multiple gir/installed_files.txt @@ -1,6 +1,6 @@ usr/lib/girepository-1.0/Meson-1.0.typelib usr/lib/girepository-1.0/MesonSub-1.0.typelib -usr/lib/libgirlib.so -usr/lib/libgirsubproject.so +usr/lib/?libgirlib.so +usr/lib/?libgirsubproject.so usr/share/gir-1.0/Meson-1.0.gir usr/share/gir-1.0/MesonSub-1.0.gir diff --git a/test cases/frameworks/7 gnome/gir/meson.build b/test cases/frameworks/7 gnome/gir/meson.build index a91cb97..1771548 100644 --- a/test cases/frameworks/7 gnome/gir/meson.build +++ b/test cases/frameworks/7 gnome/gir/meson.build @@ -41,5 +41,8 @@ gir_paths = ':'.join([girlib.outdir(), dep1lib.outdir(), dep2lib.outdir()]) envdata = environment() envdata.append('GI_TYPELIB_PATH', gir_paths, separator : ':') envdata.append('LD_LIBRARY_PATH', gir_paths) +if ['windows', 'cygwin'].contains(host_machine.system()) + envdata.append('PATH', gir_paths) +endif test('gobject introspection/py', find_program('prog.py'), env : envdata) diff --git a/test cases/frameworks/7 gnome/installed_files.txt b/test cases/frameworks/7 gnome/installed_files.txt index d0d51d5..c7c704f 100644 --- a/test cases/frameworks/7 gnome/installed_files.txt +++ b/test cases/frameworks/7 gnome/installed_files.txt @@ -2,9 +2,9 @@ usr/include/enums.h usr/include/enums2.h usr/include/enums3.h usr/include/marshaller.h -usr/lib/libgir_lib.so -usr/lib/libdep1lib.so -usr/lib/libdep2lib.so +usr/lib/?libgir_lib.so +usr/lib/?libdep1lib.so +usr/lib/?libdep2lib.so usr/lib/girepository-1.0/Meson-1.0.typelib usr/lib/girepository-1.0/MesonDep1-1.0.typelib usr/lib/girepository-1.0/MesonDep2-1.0.typelib diff --git a/test cases/unit/20 subproj dep variables/meson.build b/test cases/unit/20 subproj dep variables/meson.build new file mode 100644 index 0000000..f1622f9 --- /dev/null +++ b/test cases/unit/20 subproj dep variables/meson.build @@ -0,0 +1,13 @@ +project('subproj found dep not found', 'c') + +dependency('somedep', required : false, + fallback : ['nosubproj', 'dep_name']) + +dependency('somedep', required : false, + fallback : ['failingsubproj', 'dep_name']) + +dependency('somenotfounddep', required : false, + fallback : ['somesubproj', 'dep_name']) + +dependency('zlibproxy', required : true, + fallback : ['somesubproj', 'zlibproxy_dep']) diff --git a/test cases/unit/20 subproj dep variables/subprojects/failingsubproj/meson.build b/test cases/unit/20 subproj dep variables/subprojects/failingsubproj/meson.build new file mode 100644 index 0000000..3a84bd2 --- /dev/null +++ b/test cases/unit/20 subproj dep variables/subprojects/failingsubproj/meson.build @@ -0,0 +1,3 @@ +project('failingsubproj', 'c') + +dep_name = declare_dependency('arg') diff --git a/test cases/unit/20 subproj dep variables/subprojects/somesubproj/meson.build b/test cases/unit/20 subproj dep variables/subprojects/somesubproj/meson.build new file mode 100644 index 0000000..dd65c99 --- /dev/null +++ b/test cases/unit/20 subproj dep variables/subprojects/somesubproj/meson.build @@ -0,0 +1,3 @@ +project('dep', 'c') + +zlibproxy_dep = declare_dependency(dependencies : dependency('zlib', required : false)) diff --git a/test cases/unit/20 warning location/conf.in b/test cases/unit/20 warning location/conf.in new file mode 100644 index 0000000..a2903ed --- /dev/null +++ b/test cases/unit/20 warning location/conf.in @@ -0,0 +1 @@ +@MISSING@ diff --git a/test cases/unit/20 warning location/meson.build b/test cases/unit/20 warning location/meson.build index e26c6c9..15295a9 100644 --- a/test cases/unit/20 warning location/meson.build +++ b/test cases/unit/20 warning location/meson.build @@ -1,6 +1,10 @@ -project('duplicate kwarg', 'c') +project('warning location', 'c', invalid: 'cheese') a = library('liba', 'a.c') b = library('libb', 'b.c') executable('main', 'main.c', link_with: a, link_with: b) subdir('sub') warning('a warning of some sort') +import('unstable-simd') + +conf_data = configuration_data() +configure_file(input: 'conf.in' , output: 'conf', configuration: conf_data) diff --git a/test cases/vala/11 generated vapi/installed_files.txt b/test cases/vala/11 generated vapi/installed_files.txt index 5993d01..aeaf2da 100644 --- a/test cases/vala/11 generated vapi/installed_files.txt +++ b/test cases/vala/11 generated vapi/installed_files.txt @@ -1,6 +1,6 @@ usr/bin/vapigen-test -usr/lib/libfoo.so -usr/lib/libbar.so +usr/lib/?libfoo.so +usr/lib/?libbar.so usr/share/vala/vapi/foo-1.0.vapi usr/share/vala/vapi/foo-1.0.deps usr/share/vala/vapi/bar-1.0.vapi diff --git a/test cases/vala/11 generated vapi/libbar/bar.c b/test cases/vala/11 generated vapi/libbar/bar.c index f0f5cb8..3037141 100644 --- a/test cases/vala/11 generated vapi/libbar/bar.c +++ b/test cases/vala/11 generated vapi/libbar/bar.c @@ -1,12 +1,29 @@ #include "bar.h" #include "foo.h" +struct _BarBar +{ + GObject parent_instance; +}; + +G_DEFINE_TYPE (BarBar, bar_bar, G_TYPE_OBJECT) + +static void +bar_bar_class_init (BarBarClass *klass) +{ +} + +static void +bar_bar_init (BarBar *self) +{ +} + /** - * bar_return_success: + * bar_bar_return_success: * * Returns 0 */ -int bar_return_success(void) +int bar_bar_return_success(void) { - return foo_return_success(); + return foo_foo_return_success(); } diff --git a/test cases/vala/11 generated vapi/libbar/bar.h b/test cases/vala/11 generated vapi/libbar/bar.h index 165b104..4ca7270 100644 --- a/test cases/vala/11 generated vapi/libbar/bar.h +++ b/test cases/vala/11 generated vapi/libbar/bar.h @@ -2,4 +2,8 @@ #pragma once -int bar_return_success(void); +#define BAR_TYPE_BAR (bar_bar_get_type()) + +G_DECLARE_FINAL_TYPE (BarBar, bar_bar, BAR, BAR, GObject) + +int bar_bar_return_success(void); diff --git a/test cases/vala/11 generated vapi/libfoo/foo.c b/test cases/vala/11 generated vapi/libfoo/foo.c index 0413ac5..dd2b891 100644 --- a/test cases/vala/11 generated vapi/libfoo/foo.c +++ b/test cases/vala/11 generated vapi/libfoo/foo.c @@ -1,11 +1,28 @@ #include "foo.h" +struct _FooFoo +{ + GObject parent_instance; +}; + +G_DEFINE_TYPE (FooFoo, foo_foo, G_TYPE_OBJECT) + +static void +foo_foo_class_init (FooFooClass *klass) +{ +} + +static void +foo_foo_init (FooFoo *self) +{ +} + /** - * foo_return_success: + * foo_foo_return_success: * * Returns 0 */ -int foo_return_success(void) +int foo_foo_return_success(void) { - return 0; + return 0; } diff --git a/test cases/vala/11 generated vapi/libfoo/foo.h b/test cases/vala/11 generated vapi/libfoo/foo.h index f09256d..e1887d8 100644 --- a/test cases/vala/11 generated vapi/libfoo/foo.h +++ b/test cases/vala/11 generated vapi/libfoo/foo.h @@ -2,4 +2,8 @@ #pragma once -int foo_return_success(void); +#define FOO_TYPE_FOO (foo_foo_get_type()) + +G_DECLARE_FINAL_TYPE (FooFoo, foo_foo, Foo, FOO, GObject) + +int foo_foo_return_success(void); diff --git a/test cases/vala/11 generated vapi/main.vala b/test cases/vala/11 generated vapi/main.vala index 303ab33..d61fba0 100644 --- a/test cases/vala/11 generated vapi/main.vala +++ b/test cases/vala/11 generated vapi/main.vala @@ -3,7 +3,7 @@ using Bar; class Main : GLib.Object { public static int main(string[] args) { - var ignore = Foo.return_success(); - return Bar.return_success(); + var ignore = Foo.Foo.return_success(); + return Bar.Bar.return_success(); } } diff --git a/test cases/vala/7 shared library/installed_files.txt b/test cases/vala/7 shared library/installed_files.txt index f70e439..012b107 100644 --- a/test cases/vala/7 shared library/installed_files.txt +++ b/test cases/vala/7 shared library/installed_files.txt @@ -1,5 +1,5 @@ -usr/lib/libinstalled_vala_lib.so -usr/lib/libinstalled_vala_all.so +usr/lib/?libinstalled_vala_lib.so +usr/lib/?libinstalled_vala_all.so usr/include/installed_vala_all.h usr/include/valah/installed_vala_all_nolib.h usr/include/installed_vala_onlyh.h diff --git a/test cases/vala/9 gir/installed_files.txt b/test cases/vala/9 gir/installed_files.txt index 7a0e055..64bddee 100644 --- a/test cases/vala/9 gir/installed_files.txt +++ b/test cases/vala/9 gir/installed_files.txt @@ -1,2 +1,2 @@ -usr/lib/libfoo.so +usr/lib/?libfoo.so usr/share/gir-1.0/Foo-1.0.gir diff --git a/wraptool.py b/wraptool.py index 5e03efd..a5ee9ef 100755 --- a/wraptool.py +++ b/wraptool.py @@ -17,4 +17,7 @@ from mesonbuild.wrap import wraptool import sys -sys.exit(wraptool.run(sys.argv[1:])) +if __name__ == '__main__': + print('Warning: This executable is deprecated. Use "meson wrap" instead.', + file=sys.stderr) + sys.exit(wraptool.run(sys.argv[1:])) |