diff options
160 files changed, 1457 insertions, 166 deletions
diff --git a/ci/travis_install.sh b/ci/travis_install.sh index 5d191f1..d9d308a 100755 --- a/ci/travis_install.sh +++ b/ci/travis_install.sh @@ -7,9 +7,11 @@ msg() { echo -e "\x1b[1;32mINFO: \x1b[37m$*\x1b[0m"; } if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then msg "Running OSX setup" brew update + # Run one macOS build with pkg-config available (pulled in by qt), and the + # other (unity=on) without pkg-config brew install qt ldc llvm ninja if [[ "$MESON_ARGS" =~ .*unity=on.* ]]; then - which pkg-config || brew install pkg-config + which pkg-config && rm -f $(which pkg-config) fi python3 -m pip install jsonschema elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then diff --git a/data/test.schema.json b/data/test.schema.json index 72f160f..d3b80d0 100644 --- a/data/test.schema.json +++ b/data/test.schema.json @@ -1,5 +1,6 @@ { "type": "object", + "additionalProperties": false, "properties": { "env": { "type": "object", @@ -100,6 +101,30 @@ "prefix" ] } + }, + "tools": { + "type": "object" + }, + "stdout": { + "type": "array", + "items": { + "type": "object", + "properties": { + "line": { + "type": "string" + }, + "match": { + "type": "string", + "enum": [ + "literal", + "re" + ] + } + }, + "required": [ + "line" + ] + } } } } diff --git a/docs/markdown/Contributing.md b/docs/markdown/Contributing.md index 8a24e0b..b16f615 100644 --- a/docs/markdown/Contributing.md +++ b/docs/markdown/Contributing.md @@ -329,10 +329,31 @@ Currently supported values are: #### tools -This section specifies a list of tool requirements in a simple key-value format. +This section specifies a dict of tool requirements in a simple key-value format. If a tool is specified, it has to be present in the environment, and the version -requirement must be fulfilled match. Otherwise, the entire test is skipped -(including every element in the test matrix). +requirement must be fulfilled. Otherwise, the entire test is skipped (including +every element in the test matrix). + +#### stdout + +The `stdout` key contains a list of dicts, describing the expected stdout. + +Each dict contains the following keys: + +- `line` +- `match` (optional) + +Each item in the list is matched, in order, against the remaining actual stdout +lines, after any previous matches. If the actual stdout is exhausted before +every item in the list is matched, the expected output has not been seen, and +the test has failed. + +The `match` element of the dict determines how the `line` element is matched: + +| Type | Description | +| -------- | ----------------------- | +| `literal` | Literal match (default) | +| `re` | regex match | ### Skipping integration tests diff --git a/docs/markdown/Cross-compilation.md b/docs/markdown/Cross-compilation.md index 4c4b7bf..1c53dcf 100644 --- a/docs/markdown/Cross-compilation.md +++ b/docs/markdown/Cross-compilation.md @@ -231,13 +231,10 @@ The main *meson* object provides two functions to determine cross compilation status. ```meson -meson.is_cross_build() # returns true when cross compiling -meson.has_exe_wrapper() # returns true if an exe wrapper has been defined +meson.is_cross_build() # returns true when cross compiling +meson.can_run_host_binaries() # returns true if the host binaries can be run, either with a wrapper or natively ``` -Note that the latter gives undefined return value when doing a native -build. - You can run system checks on both the system compiler or the cross compiler. You just have to specify which one to use. diff --git a/docs/markdown/Dependencies.md b/docs/markdown/Dependencies.md index 17c9991..572a3d1 100644 --- a/docs/markdown/Dependencies.md +++ b/docs/markdown/Dependencies.md @@ -242,6 +242,9 @@ libgcrypt_dep = dependency('libgcrypt', version: '>= 1.8') gpgme_dep = dependency('gpgme', version: '>= 1.0') ``` +*Since 0.55.0* Meson won't search $PATH any more for a config tool binary when +cross compiling if the config tool did not have an entry in the cross file. + ## AppleFrameworks Use the `modules` keyword to list frameworks required, e.g. diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md index 97d3e83..1bd5ff0 100644 --- a/docs/markdown/Reference-manual.md +++ b/docs/markdown/Reference-manual.md @@ -1836,10 +1836,14 @@ the following methods. If `native: false` or not specified, variable is retrieved from the cross-file if cross-compiling, and from the native-file when not cross-compiling. -- `has_exe_wrapper()` returns true when doing a cross build if there - is a wrapper command that can be used to execute cross built - binaries (for example when cross compiling from Linux to Windows, - one can use `wine` as the wrapper). +- `can_run_host_binaries()` returns true if the build machine can run + binaries compiled for the host. This returns true unless you are + cross compiling, need a helper to run host binaries, and don't have one. + For example when cross compiling from Linux to Windows, one can use `wine` + as the helper. *New in 0.55.0* + +- `has_exe_wrapper()` alias of `can_run_host_binaries` + *Deprecated since 0.55.0* - `install_dependency_manifest(output_name)` installs a manifest file containing a list of all subprojects, their versions and license diff --git a/docs/markdown/Reference-tables.md b/docs/markdown/Reference-tables.md index dfae339..c42d608 100644 --- a/docs/markdown/Reference-tables.md +++ b/docs/markdown/Reference-tables.md @@ -81,6 +81,7 @@ set in the cross file. | alpha | DEC Alpha processor | | arc | 32 bit ARC processor | | arm | 32 bit ARM processor | +| avr | Atmel AVR processor | | e2k | MCST Elbrus processor | | c2000 | 32 bit C2000 processor | | ia64 | Itanium processor | diff --git a/docs/markdown/howtox.md b/docs/markdown/howtox.md index 8231d3d..84546b7 100644 --- a/docs/markdown/howtox.md +++ b/docs/markdown/howtox.md @@ -260,3 +260,28 @@ The `cmake_module_path` property is only needed for custom CMake scripts. System wide CMake scripts are found automatically. More information can be found [here](Dependencies.md#cmake) + +## Get a default not-found dependency? + +```meson +null_dep = dependency('', required : false) +``` + +This can be used in cases where you want a default value, but might override it +later. + +```meson +# Not needed on Windows! +my_dep = dependency('', required : false) +if host_machine.system() in ['freebsd', 'netbsd', 'openbsd', 'dragonfly'] + my_dep = dependency('some dep', required : false) +elif host_machine.system() == 'linux' + my_dep = dependency('some other dep', required : false) +endif + +executable( + 'myexe', + my_sources, + deps : [my_dep] +) +``` diff --git a/docs/markdown/snippets/can_run_host_binaries.md b/docs/markdown/snippets/can_run_host_binaries.md new file mode 100644 index 0000000..0108184 --- /dev/null +++ b/docs/markdown/snippets/can_run_host_binaries.md @@ -0,0 +1,5 @@ +## Rename has_exe_wrapper -> can_run_host_binaries + +The old name was confusing as it didn't really match the behavior of the +function. The old name remains as an alias (the behavior hasn't changed), but +is now deprecated. diff --git a/docs/markdown/snippets/config_tool_no_cross_path.md b/docs/markdown/snippets/config_tool_no_cross_path.md new file mode 100644 index 0000000..cec22e4 --- /dev/null +++ b/docs/markdown/snippets/config_tool_no_cross_path.md @@ -0,0 +1,7 @@ +## Config tool based dependencies no longer search PATH for cross compiling + +Before 0.55.0 config tool based dependencies (llvm-config, cups-config, etc), +would search system $PATH if they weren't defined in the cross file. This has +been a source of bugs and has been deprecated. It is now removed, config tool +binaries must be specified in the cross file now or the dependency will not +be found. diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 5649909..9d527cb 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -788,7 +788,7 @@ class Backend: # E.g. an external verifier or simulator program run on a generated executable. # Can always be run without a wrapper. test_for_machine = MachineChoice.BUILD - is_cross = not self.environment.machines.matches_build_machine(test_for_machine) + is_cross = self.environment.is_cross_build(test_for_machine) if is_cross and self.environment.need_exe_wrapper(): exe_wrapper = self.environment.get_exe_wrapper() else: diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 49025f9..7300aaf 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -570,7 +570,7 @@ int dummy; generated_source_files.append(raw_src) elif self.environment.is_object(rel_src): obj_list.append(rel_src) - elif self.environment.is_library(rel_src): + elif self.environment.is_library(rel_src) or modules.is_module_library(rel_src): pass else: # Assume anything not specifically a source file is a header. This is because @@ -585,7 +585,7 @@ int dummy; o = self.generate_llvm_ir_compile(target, src) else: o = self.generate_single_compile(target, src, True, - header_deps=header_deps) + order_deps=header_deps) obj_list.append(o) use_pch = self.environment.coredata.base_options.get('b_pch', False) diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index b5803bf..614d357 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -821,12 +821,12 @@ class Vs2010Backend(backends.Backend): clconf = ET.SubElement(compiles, 'ClCompile') # CRT type; debug or release if vscrt_type.value == 'from_buildtype': - if self.buildtype == 'debug' or self.buildtype == 'debugoptimized': + if self.buildtype == 'debug': ET.SubElement(type_config, 'UseDebugLibraries').text = 'true' ET.SubElement(clconf, 'RuntimeLibrary').text = 'MultiThreadedDebugDLL' else: ET.SubElement(type_config, 'UseDebugLibraries').text = 'false' - ET.SubElement(clconf, 'RuntimeLibrary').text = 'MultiThreaded' + ET.SubElement(clconf, 'RuntimeLibrary').text = 'MultiThreadedDLL' elif vscrt_type.value == 'mdd': ET.SubElement(type_config, 'UseDebugLibraries').text = 'true' ET.SubElement(clconf, 'RuntimeLibrary').text = 'MultiThreadedDebugDLL' diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 7c833a6..360285e 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -497,6 +497,7 @@ class BuildTarget(Target): self.link_targets = [] self.link_whole_targets = [] self.link_depends = [] + self.added_deps = set() self.name_prefix_set = False self.name_suffix_set = False self.filename = 'no_name' @@ -536,6 +537,9 @@ class BuildTarget(Target): repr_str = "<{0} {1}: {2}>" return repr_str.format(self.__class__.__name__, self.get_id(), self.filename) + def __str__(self): + return "{}".format(self.name) + def validate_install(self, environment): if self.for_machine is MachineChoice.BUILD and self.need_install: if environment.is_cross_build(): @@ -1055,6 +1059,8 @@ This will become a hard error in a future Meson release.''') def add_deps(self, deps): deps = listify(deps) for dep in unholder(deps): + if dep in self.added_deps: + continue if isinstance(dep, dependencies.InternalDependency): # Those parts that are internal. self.process_sourcelist(dep.sources) @@ -1093,6 +1099,7 @@ You probably should put it in link_with instead.''') 'either an external dependency (returned by find_library() or ' 'dependency()) or an internal dependency (returned by ' 'declare_dependency()).'.format(type(dep).__name__)) + self.added_deps.add(dep) def get_external_deps(self): return self.external_deps @@ -1109,7 +1116,7 @@ You probably should put it in link_with instead.''') if not isinstance(t, (Target, CustomTargetIndex)): raise InvalidArguments('{!r} is not a target.'.format(t)) if not t.is_linkable_target(): - raise InvalidArguments('Link target {!r} is not linkable.'.format(t)) + raise InvalidArguments("Link target '{!s}' is not linkable.".format(t)) if isinstance(self, SharedLibrary) and isinstance(t, StaticLibrary) and not t.pic: msg = "Can't link non-PIC static library {!r} into shared library {!r}. ".format(t.name, self.name) msg += "Use the 'pic' option to static_library to build with PIC." diff --git a/mesonbuild/cmake/interpreter.py b/mesonbuild/cmake/interpreter.py index 125f18b..35eb17c 100644 --- a/mesonbuild/cmake/interpreter.py +++ b/mesonbuild/cmake/interpreter.py @@ -289,7 +289,17 @@ class ConverterTarget: for j in self.compile_opts[i]: m = ConverterTarget.std_regex.match(j) if m: - self.override_options += ['{}_std={}'.format(i, m.group(2))] + std = m.group(2) + supported = self._all_lang_stds(i) + if std not in supported: + mlog.warning( + 'Unknown {0}_std "{1}" -> Ignoring. Try setting the project-' + 'level {0}_std if build errors occur. Known ' + '{0}_stds are: {2}'.format(i, std, ' '.join(supported)), + once=True + ) + continue + self.override_options += ['{}_std={}'.format(i, std)] elif j in ['-fPIC', '-fpic', '-fPIE', '-fpie']: self.pie = True elif j in blacklist_compiler_flags: @@ -539,6 +549,13 @@ class ConverterTarget: suffixes += [x for x in exts] return suffixes + @lru_cache(maxsize=None) + def _all_lang_stds(self, lang: str) -> T.List[str]: + lang_opts = self.env.coredata.compiler_options.build.get(lang, None) + if not lang_opts or 'std' not in lang_opts: + return [] + return lang_opts['std'].choices + def process_inter_target_dependencies(self): # Move the dependencies from all transfer_dependencies_from to the target to_process = list(self.depends) diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index b2bea26..9575273 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -1136,7 +1136,7 @@ class Compiler: def remove_linkerlike_args(self, args): rm_exact = ('-headerpad_max_install_names',) rm_prefixes = ('-Wl,', '-L',) - rm_next = ('-L',) + rm_next = ('-L', '-framework',) ret = [] iargs = iter(args) for arg in iargs: diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index d30017f..f4bcfa9 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -238,7 +238,9 @@ class EmscriptenCPPCompiler(EmscriptenMixin, LinkerEnvVarsMixin, ClangCPPCompile class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler): def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs): - CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwargs) + CPPCompiler.__init__(self, exelist=exelist, version=version, + for_machine=for_machine, is_cross=is_cross, + info=info, exe_wrapper=exe_wrapper, **kwargs) ArmclangCompiler.__init__(self) default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor'] self.warn_args = {'0': [], diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py index e7bd280..d2d03a3 100644 --- a/mesonbuild/compilers/d.py +++ b/mesonbuild/compilers/d.py @@ -646,7 +646,8 @@ class GnuDCompiler(GnuCompiler, DCompiler): '1': default_warn_args, '2': default_warn_args + ['-Wextra'], '3': default_warn_args + ['-Wextra', '-Wpedantic']} - self.base_options = ['b_colorout', 'b_sanitize', 'b_staticpic', 'b_vscrt', 'b_coverage'] + self.base_options = ['b_colorout', 'b_sanitize', 'b_staticpic', + 'b_vscrt', 'b_coverage', 'b_pgo'] self._has_color_support = version_compare(self.version, '>=4.9') # dependencies were implemented before, but broken - support was fixed in GCC 7.1+ diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py index 01283a1..c155b5b 100644 --- a/mesonbuild/compilers/fortran.py +++ b/mesonbuild/compilers/fortran.py @@ -214,6 +214,18 @@ class GnuFortranCompiler(GnuCompiler, FortranCompiler): def language_stdlib_only_link_flags(self) -> T.List[str]: return ['-lgfortran', '-lm'] + def has_header(self, hname, prefix, env, *, extra_args=None, dependencies=None, disable_cache=False): + ''' + Derived from mixins/clike.py:has_header, but without C-style usage of + __has_include which breaks with GCC-Fortran 10: + https://github.com/mesonbuild/meson/issues/7017 + ''' + fargs = {'prefix': prefix, 'header': hname} + code = '{prefix}\n#include <{header}>' + return self.compiles(code.format(**fargs), env, extra_args=extra_args, + dependencies=dependencies, mode='preprocess', disable_cache=disable_cache) + + class ElbrusFortranCompiler(GnuFortranCompiler, ElbrusCompiler): def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, info: 'MachineInfo', exe_wrapper=None, diff --git a/mesonbuild/compilers/mixins/arm.py b/mesonbuild/compilers/mixins/arm.py index aa5d15d..2e2ed94 100644 --- a/mesonbuild/compilers/mixins/arm.py +++ b/mesonbuild/compilers/mixins/arm.py @@ -27,10 +27,10 @@ if T.TYPE_CHECKING: arm_buildtype_args = { 'plain': [], - 'debug': ['-O0', '--debug'], - 'debugoptimized': ['-O1', '--debug'], - 'release': ['-O3', '-Otime'], - 'minsize': ['-O3', '-Ospace'], + 'debug': [], + 'debugoptimized': [], + 'release': [], + 'minsize': [], 'custom': [], } # type: T.Dict[str, T.List[str]] @@ -38,9 +38,9 @@ arm_optimization_args = { '0': ['-O0'], 'g': ['-g'], '1': ['-O1'], - '2': ['-O2'], - '3': ['-O3'], - 's': [], + '2': [], # Compiler defaults to -O2 + '3': ['-O3', '-Otime'], + 's': ['-O3'], # Compiler defaults to -Ospace } # type: T.Dict[str, T.List[str]] armclang_buildtype_args = { @@ -181,7 +181,7 @@ class ArmclangCompiler: # Override CCompiler.get_dependency_gen_args def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: - return [] + return ['-MD', '-MT', outtarget, '-MF', outfile] def get_optimization_args(self, optimization_level: str) -> T.List[str]: return armclang_optimization_args[optimization_level] diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index 124c49c..e7b0cd2 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -369,7 +369,8 @@ class CLikeCompiler: dependencies=dependencies, mode='link', disable_cache=disable_cache) def run(self, code: str, env, *, extra_args=None, dependencies=None): - if self.is_cross and self.exe_wrapper is None: + need_exe_wrapper = env.need_exe_wrapper(self.for_machine) + if need_exe_wrapper and self.exe_wrapper is None: raise compilers.CrossNoRunException('Can not run test applications in this cross environment.') with self._build_wrapper(code, env, extra_args, dependencies, mode='link', want_output=True) as p: if p.returncode != 0: @@ -377,7 +378,7 @@ class CLikeCompiler: p.input_name, p.returncode)) return compilers.RunResult(False) - if self.is_cross: + if need_exe_wrapper: cmdlist = self.exe_wrapper + [p.output_name] else: cmdlist = p.output_name @@ -658,7 +659,7 @@ class CLikeCompiler: # is not run so we don't care what the return value is. main = '''\nint main(void) {{ void *a = (void*) &{func}; - long b = (long) a; + long long b = (long long) a; return (int) b; }}''' return head, main @@ -727,24 +728,29 @@ class CLikeCompiler: # need to look for them differently. On nice compilers like clang, we # can just directly use the __has_builtin() macro. fargs['no_includes'] = '#include' not in prefix - fargs['__builtin_'] = '' if funcname.startswith('__builtin_') else '__builtin_' + is_builtin = funcname.startswith('__builtin_') + fargs['is_builtin'] = is_builtin + fargs['__builtin_'] = '' if is_builtin else '__builtin_' t = '''{prefix} int main(void) {{ + + /* With some toolchains (MSYS2/mingw for example) the compiler + * provides various builtins which are not really implemented and + * fall back to the stdlib where they aren't provided and fail at + * build/link time. In case the user provides a header, including + * the header didn't lead to the function being defined, and the + * function we are checking isn't a builtin itself we assume the + * builtin is not functional and we just error out. */ + #if !{no_includes:d} && !defined({func}) && !{is_builtin:d} + #error "No definition for {__builtin_}{func} found in the prefix" + #endif + #ifdef __has_builtin #if !__has_builtin({__builtin_}{func}) #error "{__builtin_}{func} not found" #endif #elif ! defined({func}) - /* Check for {__builtin_}{func} only if no includes were added to the - * prefix above, which means no definition of {func} can be found. - * We would always check for this, but we get false positives on - * MSYS2 if we do. Their toolchain is broken, but we can at least - * give them a workaround. */ - #if {no_includes:d} - {__builtin_}{func}; - #else - #error "No definition for {__builtin_}{func} found in the prefix" - #endif + {__builtin_}{func}; #endif return 0; }}''' diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index fcb13f6..8774b80 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -384,8 +384,8 @@ class CoreData: self.compiler_check_cache = OrderedDict() # Only to print a warning if it changes between Meson invocations. self.config_files = self.__load_config_files(options, scratch_dir, 'native') + self.builtin_options_libdir_cross_fixup() self.init_builtins('') - self.libdir_cross_fixup() @staticmethod def __load_config_files(options: argparse.Namespace, scratch_dir: str, ftype: str) -> T.List[str]: @@ -445,12 +445,12 @@ class CoreData: raise MesonException('Cannot find specified {} file: {}'.format(ftype, f)) return real - def libdir_cross_fixup(self): + def builtin_options_libdir_cross_fixup(self): # By default set libdir to "lib" when cross compiling since # getting the "system default" is always wrong on multiarch # platforms as it gets a value like lib/x86_64-linux-gnu. if self.cross_files: - self.builtins['libdir'].value = 'lib' + builtin_options['libdir'].default = 'lib' def sanitize_prefix(self, prefix): prefix = os.path.expanduser(prefix) @@ -491,7 +491,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. - msg = ('The value of the {!r} option is {!r} which must be a ' + msg = ('The value of the {!r} option is \'{!s}\' 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.') # os.path.commonpath doesn't understand case-insensitive filesystems, @@ -682,7 +682,9 @@ class CoreData: if type(oldval) != type(value): self.user_options[name] = value - def is_cross_build(self) -> bool: + def is_cross_build(self, when_building_for: MachineChoice = MachineChoice.HOST) -> bool: + if when_building_for == MachineChoice.BUILD: + return False return len(self.cross_files) > 0 def strip_build_option_names(self, options): diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py index 95a3956..bcb1531 100644 --- a/mesonbuild/dependencies/base.py +++ b/mesonbuild/dependencies/base.py @@ -437,28 +437,11 @@ class ConfigToolDependency(ExternalDependency): """ if not isinstance(versions, list) and versions is not None: versions = listify(versions) - - tool = self.env.lookup_binary_entry(self.for_machine, self.tool_name) - if tool is not None: - tools = [tool] - else: - if not self.env.machines.matches_build_machine(self.for_machine): - mlog.deprecation('No entry for {0} specified in your cross file. ' - 'Falling back to searching PATH. This may find a ' - 'native version of {0}! This will become a hard ' - 'error in a future version of meson'.format(self.tool_name)) - tools = [[t] for t in self.tools] - best_match = (None, None) - for tool in tools: - if len(tool) == 1: - # In some situations the command can't be directly executed. - # For example Shell scripts need to be called through sh on - # Windows (see issue #1423). - potential_bin = ExternalProgram(tool[0], silent=True) - if not potential_bin.found(): - continue - tool = potential_bin.get_command() + for potential_bin in self.search_tool(self.tool_name, self.tool_name, self.tools): + if not potential_bin.found(): + continue + tool = potential_bin.get_command() try: p, out = Popen_safe(tool + [self.version_arg])[:2] except (FileNotFoundError, PermissionError): diff --git a/mesonbuild/dependencies/boost.py b/mesonbuild/dependencies/boost.py index 3262d8b..6e85c53 100644 --- a/mesonbuild/dependencies/boost.py +++ b/mesonbuild/dependencies/boost.py @@ -412,10 +412,19 @@ class BoostDependency(ExternalDependency): break def run_check(self, inc_dirs: T.List[BoostIncludeDir], lib_dirs: T.List[Path]) -> bool: + mlog.debug(' - potential library dirs: {}'.format([x.as_posix() for x in lib_dirs])) + mlog.debug(' - potential include dirs: {}'.format([x.path.as_posix() for x in inc_dirs])) + # 2. Find all boost libraries libs = [] # type: T.List[BoostLibraryFile] for i in lib_dirs: - libs += self.detect_libraries(i) + libs = self.detect_libraries(i) + if libs: + mlog.debug(' - found boost library dir: {}'.format(i)) + # mlog.debug(' - raw library list:') + # for j in libs: + # mlog.debug(' - {}'.format(j)) + break libs = sorted(set(libs)) modules = ['boost_' + x for x in self.modules] @@ -423,9 +432,6 @@ class BoostDependency(ExternalDependency): mlog.debug(' - found boost {} include dir: {}'.format(inc.version, inc.path)) f_libs = self.filter_libraries(libs, inc.version_lib) - # mlog.debug(' - raw library list:') - # for j in libs: - # mlog.debug(' - {}'.format(j)) mlog.debug(' - filtered library list:') for j in f_libs: mlog.debug(' - {}'.format(j)) @@ -500,6 +506,19 @@ class BoostDependency(ExternalDependency): return [self._include_dir_from_version_header(x) for x in candidates] def detect_lib_dirs(self, root: Path) -> T.List[Path]: + # First check the system include paths. Only consider those within the + # given root path + system_dirs_t = self.clib_compiler.get_library_dirs(self.env) + system_dirs = [Path(x) for x in system_dirs_t] + system_dirs = [x.resolve() for x in system_dirs if x.exists()] + system_dirs = [x for x in system_dirs if mesonlib.path_is_in_root(x, root)] + system_dirs = list(mesonlib.OrderedSet(system_dirs)) + + if system_dirs: + return system_dirs + + # No system include paths were found --> fall back to manually looking + # for library dirs in root dirs = [] # type: T.List[Path] subdirs = [] # type: T.List[Path] for i in root.iterdir(): @@ -511,7 +530,25 @@ class BoostDependency(ExternalDependency): for j in i.iterdir(): if j.is_dir() and j.name.endswith('-linux-gnu'): subdirs += [j] - return dirs + subdirs + + # Filter out paths that don't match the target arch to avoid finding + # the wrong libraries. See https://github.com/mesonbuild/meson/issues/7110 + if not self.arch: + return dirs + subdirs + + arch_list_32 = ['32', 'i386'] + arch_list_64 = ['64'] + + raw_list = dirs + subdirs + no_arch = [x for x in raw_list if not any([y in x.name for y in arch_list_32 + arch_list_64])] + + matching_arch = [] # type: T.List[Path] + if '32' in self.arch: + matching_arch = [x for x in raw_list if any([y in x.name for y in arch_list_32])] + elif '64' in self.arch: + matching_arch = [x for x in raw_list if any([y in x.name for y in arch_list_64])] + + return sorted(matching_arch) + sorted(no_arch) def filter_libraries(self, libs: T.List[BoostLibraryFile], lib_vers: str) -> T.List[BoostLibraryFile]: # MSVC is very picky with the library tags @@ -568,6 +605,12 @@ class BoostDependency(ExternalDependency): roots += paths return roots # Do not add system paths if BOOST_ROOT is present + # Add roots from system paths + inc_paths = [Path(x) for x in self.clib_compiler.get_default_include_dirs()] + inc_paths = [x.parent for x in inc_paths if x.exists()] + inc_paths = [x.resolve() for x in inc_paths] + roots += inc_paths + # Add system paths if self.env.machines[self.for_machine].is_windows(): # Where boost built from source actually installs it @@ -589,8 +632,6 @@ class BoostDependency(ExternalDependency): roots += [x for x in candidates if x.name.lower().startswith('boost') and x.is_dir()] else: tmp = [] # type: T.List[Path] - # Add unix paths - tmp += [Path(x).parent for x in self.clib_compiler.get_default_include_dirs()] # Homebrew brew_boost = Path('/usr/local/Cellar/boost') diff --git a/mesonbuild/dependencies/ui.py b/mesonbuild/dependencies/ui.py index 4cec814..741f0b8 100644 --- a/mesonbuild/dependencies/ui.py +++ b/mesonbuild/dependencies/ui.py @@ -406,6 +406,9 @@ class QtBaseDependency(ExternalDependency): if libfile: libfile = libfile[0] else: + mlog.log("Could not find:", module, + self.qtpkgname + module + modules_lib_suffix, + 'in', libdir) self.is_found = False break self.link_args.append(libfile) @@ -426,6 +429,20 @@ class QtBaseDependency(ExternalDependency): if self.env.machines[self.for_machine].is_darwin(): if is_debug: suffix += '_debug' + if mesonlib.version_compare(self.version, '>= 5.14.0'): + if self.env.machines[self.for_machine].is_android(): + cpu_family = self.env.machines[self.for_machine].cpu_family + if cpu_family == 'x86': + suffix += '_x86' + elif cpu_family == 'x86_64': + suffix += '_x86_64' + elif cpu_family == 'arm': + suffix += '_armeabi-v7a' + elif cpu_family == 'aarch64': + suffix += '_arm64-v8a' + else: + mlog.warning('Android target arch {!r} for Qt5 is unknown, ' + 'module detection may not work'.format(cpu_family)) return suffix def _link_with_qtmain(self, is_debug, libdir): diff --git a/mesonbuild/envconfig.py b/mesonbuild/envconfig.py index a4af39a..b74be35 100644 --- a/mesonbuild/envconfig.py +++ b/mesonbuild/envconfig.py @@ -40,6 +40,7 @@ known_cpu_families = ( 'alpha', 'arc', 'arm', + 'avr', 'c2000', 'e2k', 'ia64', diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index 4ced8e0..8fad628 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -635,8 +635,8 @@ class Environment: self.coredata.meson_command = mesonlib.meson_command self.first_invocation = True - def is_cross_build(self) -> bool: - return self.coredata.is_cross_build() + def is_cross_build(self, when_building_for: MachineChoice = MachineChoice.HOST) -> bool: + return self.coredata.is_cross_build(when_building_for) def dump_coredata(self): return coredata.save(self.coredata, self.get_build_dir()) @@ -899,7 +899,7 @@ class Environment: def _detect_c_or_cpp_compiler(self, lang: str, for_machine: MachineChoice) -> Compiler: popen_exceptions = {} compilers, ccache, exe_wrap = self._get_compilers(lang, for_machine) - is_cross = not self.machines.matches_build_machine(for_machine) + is_cross = self.is_cross_build(for_machine) info = self.machines[for_machine] for compiler in compilers: @@ -1152,7 +1152,7 @@ class Environment: def detect_cuda_compiler(self, for_machine): popen_exceptions = {} - is_cross = not self.machines.matches_build_machine(for_machine) + is_cross = self.is_cross_build(for_machine) compilers, ccache, exe_wrap = self._get_compilers('cuda', for_machine) info = self.machines[for_machine] for compiler in compilers: @@ -1192,7 +1192,7 @@ class Environment: def detect_fortran_compiler(self, for_machine: MachineChoice): popen_exceptions = {} compilers, ccache, exe_wrap = self._get_compilers('fortran', for_machine) - is_cross = not self.machines.matches_build_machine(for_machine) + is_cross = self.is_cross_build(for_machine) info = self.machines[for_machine] for compiler in compilers: if isinstance(compiler, str): @@ -1311,7 +1311,7 @@ class Environment: def _detect_objc_or_objcpp_compiler(self, for_machine: MachineInfo, objc: bool) -> 'Compiler': popen_exceptions = {} compilers, ccache, exe_wrap = self._get_compilers('objc' if objc else 'objcpp', for_machine) - is_cross = not self.machines.matches_build_machine(for_machine) + is_cross = self.is_cross_build(for_machine) info = self.machines[for_machine] for compiler in compilers: @@ -1402,7 +1402,7 @@ class Environment: def detect_vala_compiler(self, for_machine): exelist = self.lookup_binary_entry(for_machine, 'vala') - is_cross = not self.machines.matches_build_machine(for_machine) + is_cross = self.is_cross_build(for_machine) info = self.machines[for_machine] if exelist is None: # TODO support fallback @@ -1422,7 +1422,7 @@ class Environment: def detect_rust_compiler(self, for_machine): popen_exceptions = {} compilers, ccache, exe_wrap = self._get_compilers('rust', for_machine) - is_cross = not self.machines.matches_build_machine(for_machine) + is_cross = self.is_cross_build(for_machine) info = self.machines[for_machine] cc = self.detect_c_compiler(for_machine) @@ -1513,7 +1513,7 @@ class Environment: arch = 'x86_mscoff' popen_exceptions = {} - is_cross = not self.machines.matches_build_machine(for_machine) + is_cross = self.is_cross_build(for_machine) results, ccache, exe_wrap = self._get_compilers('d', for_machine) for exelist in results: # Search for a D compiler. @@ -1604,7 +1604,7 @@ class Environment: def detect_swift_compiler(self, for_machine): exelist = self.lookup_binary_entry(for_machine, 'swift') - is_cross = not self.machines.matches_build_machine(for_machine) + is_cross = self.is_cross_build(for_machine) info = self.machines[for_machine] if exelist is None: # TODO support fallback diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index a3e9dee..8c7a82c 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -1873,6 +1873,7 @@ class MesonMain(InterpreterObject): self.methods.update({'get_compiler': self.get_compiler_method, 'is_cross_build': self.is_cross_build_method, 'has_exe_wrapper': self.has_exe_wrapper_method, + 'can_run_host_binaries': self.can_run_host_binaries_method, 'is_unity': self.is_unity_method, 'is_subproject': self.is_subproject_method, 'current_source_dir': self.current_source_dir_method, @@ -2023,9 +2024,16 @@ class MesonMain(InterpreterObject): @noPosargs @permittedKwargs({}) - def has_exe_wrapper_method(self, args, kwargs): - if self.is_cross_build_method(None, None) and \ - self.build.environment.need_exe_wrapper(): + @FeatureDeprecated('meson.has_exe_wrapper', '0.55.0', 'use meson.can_run_host_binaries instead.') + def has_exe_wrapper_method(self, args: T.Tuple[object, ...], kwargs: T.Dict[str, object]) -> bool: + return self.can_run_host_binaries_method(args, kwargs) + + @noPosargs + @permittedKwargs({}) + @FeatureNew('meson.can_run_host_binaries', '0.55.0') + def can_run_host_binaries_method(self, args: T.Tuple[object, ...], kwargs: T.Dict[str, object]) -> bool: + if (self.is_cross_build_method(None, None) and + self.build.environment.need_exe_wrapper()): if self.build.environment.exe_wrapper is None: return False # We return True when exe_wrap is defined, when it's not needed, and @@ -3168,6 +3176,12 @@ external dependencies (including libraries) must go to "dependencies".''') return should def add_languages_for(self, args, required, for_machine: MachineChoice): + langs = set(self.coredata.compilers[for_machine].keys()) + langs.update(args) + if 'vala' in langs: + if 'c' not in langs: + raise InterpreterException('Compiling Vala requires C. Add C to your project languages and rerun Meson.') + success = True for lang in sorted(args, key=compilers.sort_clink): lang = lang.lower() @@ -3205,11 +3219,6 @@ external dependencies (including libraries) must go to "dependencies".''') mlog.bold(' '.join(comp.linker.get_exelist())), comp.linker.id, comp.linker.version) self.build.ensure_static_linker(comp) - langs = self.coredata.compilers[for_machine].keys() - if 'vala' in langs: - if 'c' not in langs: - raise InterpreterException('Compiling Vala requires C. Add C to your project languages and rerun Meson.') - return success def program_from_file_for(self, for_machine, prognames, silent): @@ -3950,7 +3959,7 @@ This will become a hard error in the future.''' % kwargs['input'], location=self absname = os.path.join(self.environment.get_source_dir(), buildfilename) if not os.path.isfile(absname): self.subdir = prev_subdir - raise InterpreterException('Non-existent build file {!r}'.format(buildfilename)) + raise InterpreterException("Non-existent build file '{!s}'".format(buildfilename)) with open(absname, encoding='utf8') as f: code = f.read() assert(isinstance(code, str)) @@ -3998,7 +4007,7 @@ This will become a hard error in the future.''' % kwargs['input'], location=self elif isinstance(s, str): source_strings.append(s) else: - raise InvalidArguments('Argument {!r} must be string or file.'.format(s)) + raise InvalidArguments('Argument must be string or file.') sources += self.source_strings_to_files(source_strings) install_dir = kwargs.get('install_dir', None) if not isinstance(install_dir, (str, type(None))): @@ -4272,8 +4281,9 @@ This will become a hard error in the future.''' % kwargs['input'], location=self for a in incdir_strings: if a.startswith(src_root): - raise InvalidArguments('''Tried to form an absolute path to a source dir. You should not do that but use -relative paths instead. + raise InvalidArguments('Tried to form an absolute path to a source dir. ' + 'You should not do that but use relative paths instead.' + ''' To get include path to any directory relative to the current dir do diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py index 6246a06..af9018b 100644 --- a/mesonbuild/interpreterbase.py +++ b/mesonbuild/interpreterbase.py @@ -18,6 +18,7 @@ from . import mparser, mesonlib, mlog from . import environment, dependencies +import abc import os, copy, re import collections.abc from functools import wraps @@ -212,17 +213,17 @@ class permittedKwargs: return f(*wrapped_args, **wrapped_kwargs) return wrapped -class FeatureCheckBase: +class FeatureCheckBase(metaclass=abc.ABCMeta): "Base class for feature version checks" - # Class variable, shared across all instances - # - # Format: {subproject: {feature_version: set(feature_names)}} + # In python 3.6 we can just forward declare this, but in 3.5 we can't + # This will be overwritten by the subclasses by necessity feature_registry = {} # type: T.ClassVar[T.Dict[str, T.Dict[str, T.Set[str]]]] - def __init__(self, feature_name: str, version: str): + def __init__(self, feature_name: str, version: str, extra_message: T.Optional[str] = None): self.feature_name = feature_name # type: str self.feature_version = version # type: str + self.extra_message = extra_message or '' # type: str @staticmethod def get_target_version(subproject: str) -> str: @@ -231,13 +232,18 @@ class FeatureCheckBase: return '' return mesonlib.project_meson_versions[subproject] + @staticmethod + @abc.abstractmethod + def check_version(target_version: str, feature_Version: str) -> bool: + pass + def use(self, subproject: str) -> None: tv = self.get_target_version(subproject) # No target version if tv == '': return # Target version is new enough - if mesonlib.version_compare_condition_with_min(tv, self.feature_version): + if self.check_version(tv, self.feature_version): return # Feature is too new for target version, register it if subproject not in self.feature_registry: @@ -283,25 +289,57 @@ class FeatureCheckBase: class FeatureNew(FeatureCheckBase): """Checks for new features""" + # Class variable, shared across all instances + # + # Format: {subproject: {feature_version: set(feature_names)}} + feature_registry = {} # type: T.ClassVar[T.Dict[str, T.Dict[str, T.Set[str]]]] + + @staticmethod + def check_version(target_version: str, feature_version: str) -> bool: + return mesonlib.version_compare_condition_with_min(target_version, feature_version) + @staticmethod def get_warning_str_prefix(tv: str) -> str: return 'Project specifies a minimum meson_version \'{}\' but uses features which were added in newer versions:'.format(tv) def log_usage_warning(self, tv: str) -> None: - mlog.warning('Project targeting \'{}\' but tried to use feature introduced ' - 'in \'{}\': {}'.format(tv, self.feature_version, self.feature_name)) + args = [ + 'Project targeting', "'{}'".format(tv), + 'but tried to use feature introduced in', + "'{}':".format(self.feature_version), + '{}.'.format(self.feature_name), + ] + if self.extra_message: + args.append(self.extra_message) + mlog.warning(*args) class FeatureDeprecated(FeatureCheckBase): """Checks for deprecated features""" + # Class variable, shared across all instances + # + # Format: {subproject: {feature_version: set(feature_names)}} + feature_registry = {} # type: T.ClassVar[T.Dict[str, T.Dict[str, T.Set[str]]]] + + @staticmethod + def check_version(target_version: str, feature_version: str) -> bool: + # For deprecatoin checks we need to return the inverse of FeatureNew checks + return not mesonlib.version_compare_condition_with_min(target_version, feature_version) + @staticmethod def get_warning_str_prefix(tv: str) -> str: return 'Deprecated features used:' def log_usage_warning(self, tv: str) -> None: - mlog.deprecation('Project targeting \'{}\' but tried to use feature ' - 'deprecated since \'{}\': {}' - ''.format(tv, self.feature_version, self.feature_name)) + args = [ + 'Project targeting', "'{}'".format(tv), + 'but tried to use feature deprecated since', + "'{}':".format(self.feature_version), + '{}.'.format(self.feature_name), + ] + if self.extra_message: + args.append(self.extra_message) + mlog.warning(*args) class FeatureCheckKwargsBase: diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py index 6c1e466..b901ec9 100644 --- a/mesonbuild/mesonlib.py +++ b/mesonbuild/mesonlib.py @@ -1533,6 +1533,16 @@ def relpath(path: str, start: str) -> str: except (TypeError, ValueError): return path +def path_is_in_root(path: Path, root: Path, resolve: bool = False) -> bool: + # Check wheter a path is within the root directory root + try: + if resolve: + path.resolve().relative_to(root.resolve()) + else: + path.relative_to(root) + except ValueError: + return False + return True class LibType(Enum): diff --git a/mesonbuild/mlog.py b/mesonbuild/mlog.py index 8cbd248..7b8aec7 100644 --- a/mesonbuild/mlog.py +++ b/mesonbuild/mlog.py @@ -40,15 +40,32 @@ def _windows_ansi() -> bool: # original behavior return bool(kernel.SetConsoleMode(stdout, mode.value | 0x4) or os.environ.get('ANSICON')) -def setup_console() -> bool: +def colorize_console() -> bool: + _colorize_console = getattr(sys.stdout, 'colorize_console', None) # type: bool + if _colorize_console is not None: + return _colorize_console + try: if platform.system().lower() == 'windows': - return os.isatty(sys.stdout.fileno()) and _windows_ansi() - return os.isatty(sys.stdout.fileno()) and os.environ.get('TERM') != 'dumb' + _colorize_console = os.isatty(sys.stdout.fileno()) and _windows_ansi() + else: + _colorize_console = os.isatty(sys.stdout.fileno()) and os.environ.get('TERM', 'dumb') != 'dumb' except Exception: - return False + _colorize_console = False + + sys.stdout.colorize_console = _colorize_console # type: ignore[attr-defined] + return _colorize_console + +def setup_console(): + # on Windows, a subprocess might call SetConsoleMode() on the console + # connected to stdout and turn off ANSI escape processing. Call this after + # running a subprocess to ensure we turn it on again. + if platform.system().lower() == 'windows': + try: + delattr(sys.stdout, 'colorize_console') + except AttributeError: + pass -colorize_console = setup_console() log_dir = None # type: T.Optional[str] log_file = None # type: T.Optional[T.TextIO] log_fname = 'meson-log.txt' # type: str @@ -204,7 +221,7 @@ def log(*args: T.Union[str, AnsiDecorator], is_error: bool = False, if log_file is not None: print(*arr, file=log_file, **kwargs) log_file.flush() - if colorize_console: + if colorize_console(): arr = process_markup(args, True) if not log_errors_only or is_error: force_print(*arr, **kwargs) diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py index dc86a1b..47be039 100644 --- a/mesonbuild/modules/__init__.py +++ b/mesonbuild/modules/__init__.py @@ -57,6 +57,17 @@ def get_include_args(include_dirs, prefix='-I'): return dirs_str +def is_module_library(fname): + ''' + Check if the file is a library-like file generated by a module-specific + target, such as GirTarget or TypelibTarget + ''' + if hasattr(fname, 'fname'): + fname = fname.fname + suffix = fname.split('.')[-1] + return suffix in ('gir', 'typelib') + + class ModuleReturnValue: def __init__(self, return_value, new_objects): self.return_value = return_value diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index a97fffa..01acb37 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -695,11 +695,10 @@ class GnomeModule(ExtensionModule): source.get_subdir()) if subdir not in typelib_includes: typelib_includes.append(subdir) - elif isinstance(dep, PkgConfigDependency): - girdir = dep.get_pkgconfig_variable("girdir", {'default': ''}) + if isinstance(dep, Dependency): + girdir = dep.get_variable(pkgconfig='girdir', internal='girdir', default_value='') if girdir and girdir not in typelib_includes: typelib_includes.append(girdir) - return typelib_includes def _get_external_args_for_langs(self, state, langs): @@ -769,7 +768,6 @@ class GnomeModule(ExtensionModule): external_ldflags += list(self._get_scanner_ldflags(dep_external_ldflags)) girtargets_inc_dirs = self._get_gir_targets_inc_dirs(girtargets) inc_dirs = self._scan_inc_dirs(kwargs) - gi_includes.update(gir_inc_dirs + inc_dirs) scan_command = [giscanner] scan_command += ['--no-libtool'] @@ -790,7 +788,7 @@ class GnomeModule(ExtensionModule): scan_command += cflags scan_command += ['--cflags-end'] scan_command += get_include_args(inc_dirs) - scan_command += get_include_args(list(gi_includes), prefix='--add-include-path=') + scan_command += get_include_args(list(gi_includes) + gir_inc_dirs + inc_dirs, prefix='--add-include-path=') scan_command += list(internal_ldflags) scan_command += self._scan_gir_targets(state, girtargets) scan_command += self._scan_langs(state, [lc[0] for lc in langs_compilers]) @@ -804,7 +802,7 @@ class GnomeModule(ExtensionModule): typelib_output = '%s-%s.typelib' % (ns, nsversion) typelib_cmd = [gicompiler, scan_target, '--output', '@OUTPUT@'] - typelib_cmd += get_include_args(list(gi_includes), prefix='--includedir=') + typelib_cmd += get_include_args(gir_inc_dirs, prefix='--includedir=') for incdir in typelib_includes: typelib_cmd += ["--includedir=" + incdir] diff --git a/mesonbuild/scripts/symbolextractor.py b/mesonbuild/scripts/symbolextractor.py index d393f93..41cca26 100644 --- a/mesonbuild/scripts/symbolextractor.py +++ b/mesonbuild/scripts/symbolextractor.py @@ -113,7 +113,10 @@ def gnu_syms(libfilename: str, outfilename: str): continue line_split = line.split() entry = line_split[0:2] - if len(line_split) >= 4: + # Store the size of symbols pointing to data objects so we relink + # when those change, which is needed because of copy relocations + # https://github.com/mesonbuild/meson/pull/7132#issuecomment-628353702 + if line_split[1].upper() in ('B', 'G', 'D') and len(line_split) >= 4: entry += [line_split[3]] result += [' '.join(entry)] write_if_changed('\n'.join(result) + '\n', outfilename) @@ -139,6 +142,23 @@ def osx_syms(libfilename: str, outfilename: str): result += [' '.join(x.split()[0:2]) for x in output.split('\n')] write_if_changed('\n'.join(result) + '\n', outfilename) +def openbsd_syms(libfilename: str, outfilename: str): + # Get the name of the library + output = call_tool('readelf', ['-d', libfilename]) + if not output: + dummy_syms(outfilename) + return + result = [x for x in output.split('\n') if 'SONAME' in x] + assert(len(result) <= 1) + # Get a list of all symbols exported + output = call_tool('nm', ['-D', '-P', '-g', libfilename]) + if not output: + dummy_syms(outfilename) + return + # U = undefined (cope with the lack of --defined-only option) + result += [' '.join(x.split()[0:2]) for x in output.split('\n') if x and not x.endswith('U ')] + write_if_changed('\n'.join(result) + '\n', outfilename) + def cygwin_syms(impfilename: str, outfilename: str): # Get the name of the library output = call_tool('dlltool', ['-I', impfilename]) @@ -234,6 +254,8 @@ def gen_symbols(libfilename: str, impfilename: str, outfilename: str, cross_host gnu_syms(libfilename, outfilename) elif mesonlib.is_osx(): osx_syms(libfilename, outfilename) + elif mesonlib.is_openbsd(): + openbsd_syms(libfilename, outfilename) elif mesonlib.is_windows(): if os.path.isfile(impfilename): windows_syms(impfilename, outfilename) diff --git a/msi/createmsi.py b/msi/createmsi.py index f80d1dc..4d03593 100644 --- a/msi/createmsi.py +++ b/msi/createmsi.py @@ -153,6 +153,7 @@ class PackageGenerator: if os.path.exists(sdir): shutil.rmtree(sdir) main_stage, ninja_stage = self.staging_dirs + dep_data_dir = 'mesonbuild/dependencies/data' modules = self.get_all_modules_from_dir('mesonbuild/modules') modules += self.get_all_modules_from_dir('mesonbuild/scripts') modules += self.get_more_modules() @@ -174,6 +175,7 @@ class PackageGenerator: pyinst_cmd += ['meson.py'] subprocess.check_call(pyinst_cmd) shutil.move(pyinstaller_tmpdir + '/meson', main_stage) + shutil.copytree(dep_data_dir, main_stage + '/mesonbuild/dependencies/data') if not os.path.exists(os.path.join(main_stage, 'meson.exe')): sys.exit('Meson exe missing from staging dir.') os.mkdir(ninja_stage) diff --git a/run_project_tests.py b/run_project_tests.py index 9da67b2..bcfe05c 100755 --- a/run_project_tests.py +++ b/run_project_tests.py @@ -191,6 +191,7 @@ class TestDef: self.env = os.environ.copy() self.installed_files = [] # type: T.List[InstalledFile] self.do_not_set_opts = [] # type: T.List[str] + self.stdout = [] # type: T.List[T.Dict[str, str]] def __repr__(self) -> str: return '<{}: {:<48} [{}: {}] -- {}>'.format(type(self).__name__, str(self.path), self.name, self.args, self.skip) @@ -341,19 +342,19 @@ def log_text_file(logfile, testdir, stdo, stde): def bold(text): - return mlog.bold(text).get_text(mlog.colorize_console) + return mlog.bold(text).get_text(mlog.colorize_console()) def green(text): - return mlog.green(text).get_text(mlog.colorize_console) + return mlog.green(text).get_text(mlog.colorize_console()) def red(text): - return mlog.red(text).get_text(mlog.colorize_console) + return mlog.red(text).get_text(mlog.colorize_console()) def yellow(text): - return mlog.yellow(text).get_text(mlog.colorize_console) + return mlog.yellow(text).get_text(mlog.colorize_console()) def _run_ci_include(args: T.List[str]) -> str: @@ -381,6 +382,55 @@ def run_ci_commands(raw_log: str) -> T.List[str]: res += ['CI COMMAND {}:\n{}\n'.format(cmd[0], ci_commands[cmd[0]](cmd[1:]))] return res +def _compare_output(expected: T.List[T.Dict[str, str]], output: str, desc: str) -> str: + if expected: + i = iter(expected) + + def next_expected(i): + # Get the next expected line + item = next(i) + how = item.get('match', 'literal') + expected = item.get('line') + + # Simple heuristic to automatically convert path separators for + # Windows: + # + # Any '/' appearing before 'WARNING' or 'ERROR' (i.e. a path in a + # filename part of a location) is replaced with '\' (in a re: '\\' + # which matches a literal '\') + # + # (There should probably be a way to turn this off for more complex + # cases which don't fit this) + if mesonlib.is_windows(): + if how != "re": + sub = r'\\' + else: + sub = r'\\\\' + expected = re.sub(r'/(?=.*(WARNING|ERROR))', sub, expected) + + return how, expected + + try: + how, expected = next_expected(i) + for actual in output.splitlines(): + if how == "re": + match = bool(re.match(expected, actual)) + else: + match = (expected == actual) + print(actual) + if match: + how, expected = next_expected(i) + + # reached the end of output without finding expected + return 'expected "{}" not found in {}'.format(expected, desc) + except StopIteration: + # matched all expected lines + pass + + return '' + +def validate_output(test: TestDef, stdo: str, stde: str) -> str: + return _compare_output(test.stdout, stdo, 'stdout') def run_test_inprocess(testdir): old_stdout = sys.stdout @@ -452,6 +502,11 @@ def _run_test(test: TestDef, test_build_dir: str, install_dir: str, extra_args, cicmds = run_ci_commands(mesonlog) testresult = TestResult(cicmds) testresult.add_step(BuildStep.configure, stdo, stde, mesonlog, time.time() - gen_start) + output_msg = validate_output(test, stdo, stde) + testresult.mlog += output_msg + if output_msg: + testresult.fail('Unexpected output while configuring.') + return testresult if should_fail == 'meson': if returncode == 1: return testresult @@ -566,6 +621,9 @@ def gather_tests(testdir: Path) -> T.List[TestDef]: if 'installed' in test_def: installed = [InstalledFile(x) for x in test_def['installed']] + # Handle expected output + stdout = test_def.get('stdout', []) + # Handle the do_not_set_opts list do_not_set_opts = test_def.get('do_not_set_opts', []) # type: T.List[str] @@ -583,6 +641,7 @@ def gather_tests(testdir: Path) -> T.List[TestDef]: t.env.update(env) t.installed_files = installed t.do_not_set_opts = do_not_set_opts + t.stdout = stdout all_tests += [t] continue @@ -653,6 +712,7 @@ def gather_tests(testdir: Path) -> T.List[TestDef]: test.env.update(env) test.installed_files = installed test.do_not_set_opts = do_not_set_opts + test.stdout = stdout all_tests += [test] return sorted(all_tests) diff --git a/run_tests.py b/run_tests.py index 005d9a0..44dcf82 100755 --- a/run_tests.py +++ b/run_tests.py @@ -303,7 +303,7 @@ def run_configure(commandlist, env=None): return run_configure_inprocess(commandlist, env=env) def print_system_info(): - print(mlog.bold('System information.').get_text(mlog.colorize_console)) + print(mlog.bold('System information.').get_text(mlog.colorize_console())) print('Architecture:', platform.architecture()) print('Machine:', platform.machine()) print('Platform:', platform.system()) @@ -377,7 +377,7 @@ def main(): print(flush=True) returncode = 0 else: - print(mlog.bold('Running unittests.').get_text(mlog.colorize_console)) + print(mlog.bold('Running unittests.').get_text(mlog.colorize_console())) print(flush=True) cmd = mesonlib.python_command + ['run_unittests.py', '-v'] if options.failfast: @@ -390,7 +390,7 @@ def main(): else: cross_test_args = mesonlib.python_command + ['run_cross_test.py'] for cf in options.cross: - print(mlog.bold('Running {} cross tests.'.format(cf)).get_text(mlog.colorize_console)) + print(mlog.bold('Running {} cross tests.'.format(cf)).get_text(mlog.colorize_console())) print(flush=True) cmd = cross_test_args + ['cross/' + cf] if options.failfast: diff --git a/run_unittests.py b/run_unittests.py index 8ad64be..b21f785 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -1468,14 +1468,14 @@ class DataTests(unittest.TestCase): class BasePlatformTests(unittest.TestCase): + prefix = '/usr' + libdir = 'lib' def setUp(self): super().setUp() self.maxDiff = None src_root = os.path.dirname(__file__) src_root = os.path.join(os.getcwd(), src_root) self.src_root = src_root - self.prefix = '/usr' - self.libdir = 'lib' # Get the backend # FIXME: Extract this from argv? self.backend = getattr(Backend, os.environ.get('MESON_UNIT_TEST_BACKEND', 'ninja')) @@ -1588,8 +1588,9 @@ class BasePlatformTests(unittest.TestCase): extra_args = [extra_args] args = [srcdir, self.builddir] if default_args: - args += ['--prefix', self.prefix, - '--libdir', self.libdir] + args += ['--prefix', self.prefix] + if self.libdir: + args += ['--libdir', self.libdir] if self.meson_native_file: args += ['--native-file', self.meson_native_file] if self.meson_cross_file: @@ -5325,7 +5326,7 @@ class DarwinTests(BasePlatformTests): def test_removing_unused_linker_args(self): testdir = os.path.join(self.common_test_dir, '108 has arg') - env = {'CFLAGS': '-L/tmp -L /var/tmp -headerpad_max_install_names -Wl,-export_dynamic'} + env = {'CFLAGS': '-L/tmp -L /var/tmp -headerpad_max_install_names -Wl,-export_dynamic -framework Foundation'} self.init(testdir, override_envvars=env) @@ -6720,11 +6721,17 @@ c = ['{0}'] os.unlink(wrap_filename) +class BaseLinuxCrossTests(BasePlatformTests): + # Don't pass --libdir when cross-compiling. We have tests that + # check whether meson auto-detects it correctly. + libdir = None + + def should_run_cross_arm_tests(): return shutil.which('arm-linux-gnueabihf-gcc') and not platform.machine().lower().startswith('arm') @unittest.skipUnless(not is_windows() and should_run_cross_arm_tests(), "requires ability to cross compile to ARM") -class LinuxCrossArmTests(BasePlatformTests): +class LinuxCrossArmTests(BaseLinuxCrossTests): ''' Tests that cross-compilation to Linux/ARM works ''' @@ -6805,7 +6812,7 @@ def should_run_cross_mingw_tests(): return shutil.which('x86_64-w64-mingw32-gcc') and not (is_windows() or is_cygwin()) @unittest.skipUnless(not is_windows() and should_run_cross_mingw_tests(), "requires ability to cross compile with MinGW") -class LinuxCrossMingwTests(BasePlatformTests): +class LinuxCrossMingwTests(BaseLinuxCrossTests): ''' Tests that cross-compilation to Windows/MinGW works ''' diff --git a/test cases/common/36 tryrun/meson.build b/test cases/common/36 tryrun/meson.build index 261adf2..5580974 100644 --- a/test cases/common/36 tryrun/meson.build +++ b/test cases/common/36 tryrun/meson.build @@ -2,7 +2,7 @@ project('tryrun', 'c', 'cpp') # Complex to exercise all code paths. if meson.is_cross_build() - if meson.has_exe_wrapper() + if meson.can_run_host_binaries() compilers = [meson.get_compiler('c', native : false), meson.get_compiler('cpp', native : false)] else compilers = [meson.get_compiler('c', native : true), meson.get_compiler('cpp', native : true)] diff --git a/test cases/common/93 selfbuilt custom/meson.build b/test cases/common/93 selfbuilt custom/meson.build index 3cc3906..b536352 100644 --- a/test cases/common/93 selfbuilt custom/meson.build +++ b/test cases/common/93 selfbuilt custom/meson.build @@ -26,7 +26,7 @@ ctlib = custom_target('ctlib', build_by_default : true, ) -if meson.is_cross_build() and meson.has_exe_wrapper() +if meson.is_cross_build() and meson.can_run_host_binaries() checkarg_host = executable('checkarg_host', 'checkarg.cpp') ctlib_host = custom_target( diff --git a/test cases/failing/1 project not first/test.json b/test cases/failing/1 project not first/test.json new file mode 100644 index 0000000..70f3c41 --- /dev/null +++ b/test cases/failing/1 project not first/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "ERROR: First statement must be a call to project" + } + ] +} diff --git a/test cases/failing/10 out of bounds/test.json b/test cases/failing/10 out of bounds/test.json new file mode 100644 index 0000000..e27d990 --- /dev/null +++ b/test cases/failing/10 out of bounds/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/10 out of bounds/meson.build:4:0: ERROR: Index 0 out of bounds of array of size 0." + } + ] +} diff --git a/test cases/failing/11 object arithmetic/test.json b/test cases/failing/11 object arithmetic/test.json new file mode 100644 index 0000000..5339fac --- /dev/null +++ b/test cases/failing/11 object arithmetic/test.json @@ -0,0 +1,8 @@ +{ + "stdout": [ + { + "match": "re", + "line": "test cases/failing/11 object arithmetic/meson\\.build:3:0: ERROR: Invalid use of addition: .*" + } + ] +} diff --git a/test cases/failing/12 string arithmetic/test.json b/test cases/failing/12 string arithmetic/test.json new file mode 100644 index 0000000..476f9bb --- /dev/null +++ b/test cases/failing/12 string arithmetic/test.json @@ -0,0 +1,8 @@ +{ + "stdout": [ + { + "match": "re", + "line": "test cases/failing/12 string arithmetic/meson\\.build:3:0: ERROR: Invalid use of addition: .*" + } + ] +} diff --git a/test cases/failing/13 array arithmetic/test.json b/test cases/failing/13 array arithmetic/test.json new file mode 100644 index 0000000..55056ce --- /dev/null +++ b/test cases/failing/13 array arithmetic/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/13 array arithmetic/meson.build:3:0: ERROR: Multiplication works only with integers." + } + ] +} diff --git a/test cases/failing/14 invalid option name/test.json b/test cases/failing/14 invalid option name/test.json new file mode 100644 index 0000000..71e685d --- /dev/null +++ b/test cases/failing/14 invalid option name/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/14 invalid option name/meson_options.txt:1:0: ERROR: Option names can only contain letters, numbers or dashes." + } + ] +} diff --git a/test cases/failing/15 kwarg before arg/test.json b/test cases/failing/15 kwarg before arg/test.json new file mode 100644 index 0000000..c7f72c3 --- /dev/null +++ b/test cases/failing/15 kwarg before arg/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/15 kwarg before arg/meson.build:3:0: ERROR: All keyword arguments must be after positional arguments." + } + ] +} diff --git a/test cases/failing/16 extract from subproject/test.json b/test cases/failing/16 extract from subproject/test.json new file mode 100644 index 0000000..78d45a5 --- /dev/null +++ b/test cases/failing/16 extract from subproject/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/16 extract from subproject/meson.build:6:0: ERROR: Tried to extract objects from a subproject target." + } + ] +} diff --git a/test cases/failing/17 same target/test.json b/test cases/failing/17 same target/test.json new file mode 100644 index 0000000..0005ba4 --- /dev/null +++ b/test cases/failing/17 same target/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/17 same target/meson.build:4:0: ERROR: Tried to create target \"foo\", but a target of that name already exists." + } + ] +} diff --git a/test cases/failing/18 wrong plusassign/test.json b/test cases/failing/18 wrong plusassign/test.json new file mode 100644 index 0000000..c698f85 --- /dev/null +++ b/test cases/failing/18 wrong plusassign/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/18 wrong plusassign/meson.build:3:0: ERROR: Plusassignment target must be an id." + } + ] +} diff --git a/test cases/failing/19 target clash/meson.build b/test cases/failing/19 target clash/meson.build index ca09fb5..4fd0934 100644 --- a/test cases/failing/19 target clash/meson.build +++ b/test cases/failing/19 target clash/meson.build @@ -8,7 +8,7 @@ project('clash', 'c') # output location is redirected. if host_machine.system() == 'windows' or host_machine.system() == 'cygwin' - error('This is expected.') + error('MESON_SKIP_TEST test only works on platforms where executables have no suffix.') endif executable('clash', 'clash.c') diff --git a/test cases/failing/19 target clash/test.json b/test cases/failing/19 target clash/test.json new file mode 100644 index 0000000..d22b894 --- /dev/null +++ b/test cases/failing/19 target clash/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "ERROR: Multiple producers for Ninja target \"clash\". Please rename your targets." + } + ] +} diff --git a/test cases/failing/2 missing file/test.json b/test cases/failing/2 missing file/test.json new file mode 100644 index 0000000..b95b8b0 --- /dev/null +++ b/test cases/failing/2 missing file/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/2 missing file/meson.build:3:0: ERROR: File missing.c does not exist." + } + ] +} diff --git a/test cases/failing/20 version/test.json b/test cases/failing/20 version/test.json new file mode 100644 index 0000000..f330624 --- /dev/null +++ b/test cases/failing/20 version/test.json @@ -0,0 +1,8 @@ +{ + "stdout": [ + { + "match": "re", + "line": "test cases/failing/20 version/meson\\.build:1:0: ERROR: Meson version is .* but project requires >100\\.0\\.0" + } + ] +} diff --git a/test cases/failing/21 subver/test.json b/test cases/failing/21 subver/test.json new file mode 100644 index 0000000..f8cfd3a --- /dev/null +++ b/test cases/failing/21 subver/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/21 subver/meson.build:3:0: ERROR: Subproject foo version is 1.0.0 but >1.0.0 required." + } + ] +} diff --git a/test cases/failing/22 assert/test.json b/test cases/failing/22 assert/test.json new file mode 100644 index 0000000..edae999 --- /dev/null +++ b/test cases/failing/22 assert/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/22 assert/meson.build:3:0: ERROR: Assert failed: I am fail." + } + ] +} diff --git a/test cases/failing/23 rel testdir/test.json b/test cases/failing/23 rel testdir/test.json new file mode 100644 index 0000000..ba983ab --- /dev/null +++ b/test cases/failing/23 rel testdir/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/23 rel testdir/meson.build:4:0: ERROR: Workdir keyword argument must be an absolute path." + } + ] +} diff --git a/test cases/failing/24 int conversion/test.json b/test cases/failing/24 int conversion/test.json new file mode 100644 index 0000000..e749928 --- /dev/null +++ b/test cases/failing/24 int conversion/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/24 int conversion/meson.build:3:13: ERROR: String 'notanumber' cannot be converted to int" + } + ] +} diff --git a/test cases/failing/25 badlang/test.json b/test cases/failing/25 badlang/test.json new file mode 100644 index 0000000..0b23fd7 --- /dev/null +++ b/test cases/failing/25 badlang/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/25 badlang/meson.build:3:0: ERROR: Tried to use unknown language \"nonexisting\"." + } + ] +} diff --git a/test cases/failing/26 output subdir/test.json b/test cases/failing/26 output subdir/test.json new file mode 100644 index 0000000..796468d --- /dev/null +++ b/test cases/failing/26 output subdir/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/26 output subdir/meson.build:3:0: ERROR: Output file name must not contain a subdirectory." + } + ] +} diff --git a/test cases/failing/27 noprog use/test.json b/test cases/failing/27 noprog use/test.json new file mode 100644 index 0000000..b84562e --- /dev/null +++ b/test cases/failing/27 noprog use/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/27 noprog use/meson.build:5:0: ERROR: Tried to use not-found external program in \"command\"" + } + ] +} diff --git a/test cases/failing/28 no crossprop/test.json b/test cases/failing/28 no crossprop/test.json new file mode 100644 index 0000000..a186a68 --- /dev/null +++ b/test cases/failing/28 no crossprop/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/28 no crossprop/meson.build:3:0: ERROR: Unknown cross property: nonexisting." + } + ] +} diff --git a/test cases/failing/29 nested ternary/test.json b/test cases/failing/29 nested ternary/test.json new file mode 100644 index 0000000..ba05013 --- /dev/null +++ b/test cases/failing/29 nested ternary/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/29 nested ternary/meson.build:3:12: ERROR: Nested ternary operators are not allowed." + } + ] +} diff --git a/test cases/failing/3 missing subdir/test.json b/test cases/failing/3 missing subdir/test.json new file mode 100644 index 0000000..562de25 --- /dev/null +++ b/test cases/failing/3 missing subdir/test.json @@ -0,0 +1,9 @@ +{ + "stdout": [ + { + "comment": "'missing/meson.build' gets transformed with os.path.sep separators", + "match": "re", + "line": "test cases/failing/3 missing subdir/meson\\.build:3:0: ERROR: Non\\-existent build file 'missing[\\\\/]meson\\.build'" + } + ] +} diff --git a/test cases/failing/30 invalid man extension/test.json b/test cases/failing/30 invalid man extension/test.json new file mode 100644 index 0000000..3f77a04 --- /dev/null +++ b/test cases/failing/30 invalid man extension/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/30 invalid man extension/meson.build:2:0: ERROR: Man file must have a file extension of a number between 1 and 8" + } + ] +} diff --git a/test cases/failing/31 no man extension/test.json b/test cases/failing/31 no man extension/test.json new file mode 100644 index 0000000..6e1f542 --- /dev/null +++ b/test cases/failing/31 no man extension/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/31 no man extension/meson.build:2:0: ERROR: Man file must have a file extension of a number between 1 and 8" + } + ] +} diff --git a/test cases/failing/32 exe static shared/meson.build b/test cases/failing/32 exe static shared/meson.build index b102764..2ae5125 100644 --- a/test cases/failing/32 exe static shared/meson.build +++ b/test cases/failing/32 exe static shared/meson.build @@ -2,7 +2,7 @@ project('statchain', 'c') host_system = host_machine.system() if host_system == 'windows' or host_system == 'darwin' - error('Test only fails on Linux and BSD') + error('MESON_SKIP_TEST test only fails on Linux and BSD') endif statlib = static_library('stat', 'stat.c', pic : false) diff --git a/test cases/failing/32 exe static shared/test.json b/test cases/failing/32 exe static shared/test.json new file mode 100644 index 0000000..51d3804 --- /dev/null +++ b/test cases/failing/32 exe static shared/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/32 exe static shared/meson.build:9:0: ERROR: Can't link non-PIC static library 'stat' into shared library 'shr2'. Use the 'pic' option to static_library to build with PIC." + } + ] +} diff --git a/test cases/failing/33 non-root subproject/test.json b/test cases/failing/33 non-root subproject/test.json new file mode 100644 index 0000000..a14cece --- /dev/null +++ b/test cases/failing/33 non-root subproject/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/33 non-root subproject/some/meson.build:1:0: ERROR: Subproject directory not found and someproj.wrap file not found" + } + ] +} diff --git a/test cases/failing/34 dependency not-required then required/test.json b/test cases/failing/34 dependency not-required then required/test.json new file mode 100644 index 0000000..3cf35f5 --- /dev/null +++ b/test cases/failing/34 dependency not-required then required/test.json @@ -0,0 +1,8 @@ +{ + "stdout": [ + { + "match": "re", + "line": ".*/meson\\.build:4:0: ERROR: (Pkg-config binary for machine MachineChoice\\.HOST not found\\. Giving up\\.|Dependency \"foo\\-bar\\-xyz\\-12\\.3\" not found, tried .*)" + } + ] +} diff --git a/test cases/failing/35 project argument after target/test.json b/test cases/failing/35 project argument after target/test.json new file mode 100644 index 0000000..f5efd9b --- /dev/null +++ b/test cases/failing/35 project argument after target/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/35 project argument after target/meson.build:7:0: ERROR: Tried to use 'add_project_arguments' after a build target has been declared." + } + ] +} diff --git a/test cases/failing/36 pkgconfig dependency impossible conditions/meson.build b/test cases/failing/36 pkgconfig dependency impossible conditions/meson.build index 54d434c..874b581 100644 --- a/test cases/failing/36 pkgconfig dependency impossible conditions/meson.build +++ b/test cases/failing/36 pkgconfig dependency impossible conditions/meson.build @@ -1,3 +1,7 @@ project('impossible-dep-test', 'c', version : '1.0') +if not dependency('zlib', required: false).found() + error('MESON_SKIP_TEST test requires zlib') +endif + dependency('zlib', version : ['>=1.0', '<1.0']) diff --git a/test cases/failing/37 has function external dependency/test.json b/test cases/failing/37 has function external dependency/test.json new file mode 100644 index 0000000..81d6f91 --- /dev/null +++ b/test cases/failing/37 has function external dependency/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/37 has function external dependency/meson.build:8:3: ERROR: Dependencies must be external dependencies" + } + ] +} diff --git a/test cases/failing/38 libdir must be inside prefix/test.json b/test cases/failing/38 libdir must be inside prefix/test.json index 1cd893c..d9256d1 100644 --- a/test cases/failing/38 libdir must be inside prefix/test.json +++ b/test cases/failing/38 libdir must be inside prefix/test.json @@ -1,3 +1,10 @@ { - "do_not_set_opts": ["libdir"] + "do_not_set_opts": [ + "libdir" + ], + "stdout": [ + { + "line": "test cases/failing/38 libdir must be inside prefix/meson.build:1:0: ERROR: The value of the 'libdir' option is '/opt/lib' which must be a subdir of the prefix '/usr'." + } + ] } diff --git a/test cases/failing/39 prefix absolute/test.json b/test cases/failing/39 prefix absolute/test.json index 4e0f6cd..2770243 100644 --- a/test cases/failing/39 prefix absolute/test.json +++ b/test cases/failing/39 prefix absolute/test.json @@ -1,3 +1,11 @@ { - "do_not_set_opts": ["prefix"] + "do_not_set_opts": [ + "prefix" + ], + "stdout": [ + { + "comment": "literal 'some/path/notabs' appears in output, irrespective of os.path.sep, as that's the prefix", + "line": "test cases/failing/39 prefix absolute/meson.build:1:0: ERROR: prefix value 'some/path/notabs' must be an absolute path" + } + ] } diff --git a/test cases/failing/4 missing meson.build/test.json b/test cases/failing/4 missing meson.build/test.json new file mode 100644 index 0000000..3857090 --- /dev/null +++ b/test cases/failing/4 missing meson.build/test.json @@ -0,0 +1,9 @@ +{ + "stdout": [ + { + "match": "re", + "comment": "'subdir/meson.build' gets transformed with os.path.sep separators", + "line": "test cases/failing/4 missing meson\\.build/meson\\.build:3:0: ERROR: Non\\-existent build file 'subdir[\\\\/]meson\\.build'" + } + ] +} diff --git a/test cases/failing/40 kwarg assign/test.json b/test cases/failing/40 kwarg assign/test.json new file mode 100644 index 0000000..671eb3f --- /dev/null +++ b/test cases/failing/40 kwarg assign/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/40 kwarg assign/meson.build:3:0: ERROR: Tried to assign values inside an argument list." + } + ] +} diff --git a/test cases/failing/41 custom target plainname many inputs/test.json b/test cases/failing/41 custom target plainname many inputs/test.json new file mode 100644 index 0000000..8c15cda --- /dev/null +++ b/test cases/failing/41 custom target plainname many inputs/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/41 custom target plainname many inputs/meson.build:5:0: ERROR: Output cannot contain @PLAINNAME@ or @BASENAME@ when there is more than one input (we can't know which to use)" + } + ] +} diff --git a/test cases/failing/42 custom target outputs not matching install_dirs/meson.build b/test cases/failing/42 custom target outputs not matching install_dirs/meson.build index 45bd7b3..765e237 100644 --- a/test cases/failing/42 custom target outputs not matching install_dirs/meson.build +++ b/test cases/failing/42 custom target outputs not matching install_dirs/meson.build @@ -3,7 +3,7 @@ project('outputs not matching install_dirs', 'c') gen = find_program('generator.py') if meson.backend() != 'ninja' - error('Failing manually, test is only for the ninja backend') + error('MESON_SKIP_TEST test is only for the ninja backend') endif custom_target('too-few-install-dirs', diff --git a/test cases/failing/42 custom target outputs not matching install_dirs/test.json b/test cases/failing/42 custom target outputs not matching install_dirs/test.json index e59cb9f..f9e2ba7 100644 --- a/test cases/failing/42 custom target outputs not matching install_dirs/test.json +++ b/test cases/failing/42 custom target outputs not matching install_dirs/test.json @@ -1,10 +1,33 @@ { "installed": [ - {"type": "file", "file": "usr/include/diff.h"}, - {"type": "file", "file": "usr/include/first.h"}, - {"type": "file", "file": "usr/bin/diff.sh"}, - {"type": "file", "file": "usr/bin/second.sh"}, - {"type": "file", "file": "opt/same.h"}, - {"type": "file", "file": "opt/same.sh"} + { + "type": "file", + "file": "usr/include/diff.h" + }, + { + "type": "file", + "file": "usr/include/first.h" + }, + { + "type": "file", + "file": "usr/bin/diff.sh" + }, + { + "type": "file", + "file": "usr/bin/second.sh" + }, + { + "type": "file", + "file": "opt/same.h" + }, + { + "type": "file", + "file": "opt/same.sh" + } + ], + "stdout": [ + { + "line": "ERROR: Target 'too-few-install-dirs' has 3 outputs: ['toofew.h', 'toofew.c', 'toofew.sh'], but only 2 \"install_dir\"s were found." + } ] } diff --git a/test cases/failing/43 project name colon/test.json b/test cases/failing/43 project name colon/test.json new file mode 100644 index 0000000..7a55574 --- /dev/null +++ b/test cases/failing/43 project name colon/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/43 project name colon/meson.build:1:0: ERROR: Project name 'name with :' must not contain ':'" + } + ] +} diff --git a/test cases/failing/44 abs subdir/test.json b/test cases/failing/44 abs subdir/test.json new file mode 100644 index 0000000..0aa56f6 --- /dev/null +++ b/test cases/failing/44 abs subdir/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/44 abs subdir/meson.build:5:0: ERROR: Subdir argument must be a relative path." + } + ] +} diff --git a/test cases/failing/45 abspath to srcdir/test.json b/test cases/failing/45 abspath to srcdir/test.json new file mode 100644 index 0000000..b6a87fe --- /dev/null +++ b/test cases/failing/45 abspath to srcdir/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/45 abspath to srcdir/meson.build:3:0: ERROR: Tried to form an absolute path to a source dir. You should not do that but use relative paths instead." + } + ] +} diff --git a/test cases/failing/46 pkgconfig variables reserved/test.json b/test cases/failing/46 pkgconfig variables reserved/test.json new file mode 100644 index 0000000..b92ee17 --- /dev/null +++ b/test cases/failing/46 pkgconfig variables reserved/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/46 pkgconfig variables reserved/meson.build:8:5: ERROR: Variable \"prefix\" is reserved" + } + ] +} diff --git a/test cases/failing/47 pkgconfig variables zero length/test.json b/test cases/failing/47 pkgconfig variables zero length/test.json new file mode 100644 index 0000000..097fee1 --- /dev/null +++ b/test cases/failing/47 pkgconfig variables zero length/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/47 pkgconfig variables zero length/meson.build:8:5: ERROR: Invalid variable \"=value\". Variables must be in 'name=value' format" + } + ] +} diff --git a/test cases/failing/48 pkgconfig variables zero length value/test.json b/test cases/failing/48 pkgconfig variables zero length value/test.json new file mode 100644 index 0000000..50a35ce --- /dev/null +++ b/test cases/failing/48 pkgconfig variables zero length value/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/48 pkgconfig variables zero length value/meson.build:8:5: ERROR: Invalid variable \"key=\". Variables must be in 'name=value' format" + } + ] +} diff --git a/test cases/failing/49 pkgconfig variables not key value/test.json b/test cases/failing/49 pkgconfig variables not key value/test.json new file mode 100644 index 0000000..cf07e62 --- /dev/null +++ b/test cases/failing/49 pkgconfig variables not key value/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/49 pkgconfig variables not key value/meson.build:8:5: ERROR: Invalid variable \"this_should_be_key_value\". Variables must be in 'name=value' format" + } + ] +} diff --git a/test cases/failing/5 misplaced option/test.json b/test cases/failing/5 misplaced option/test.json new file mode 100644 index 0000000..12afdf0 --- /dev/null +++ b/test cases/failing/5 misplaced option/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/5 misplaced option/meson.build:3:0: ERROR: Tried to call option() in build description file. All options must be in the option file." + } + ] +} diff --git a/test cases/failing/50 executable comparison/test.json b/test cases/failing/50 executable comparison/test.json new file mode 100644 index 0000000..585b382 --- /dev/null +++ b/test cases/failing/50 executable comparison/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/50 executable comparison/meson.build:6:0: ERROR: exe1 can only be compared for equality." + } + ] +} diff --git a/test cases/failing/51 inconsistent comparison/test.json b/test cases/failing/51 inconsistent comparison/test.json new file mode 100644 index 0000000..5867f0a --- /dev/null +++ b/test cases/failing/51 inconsistent comparison/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/51 inconsistent comparison/meson.build:5:0: ERROR: Values of different types (list, str) cannot be compared using <." + } + ] +} diff --git a/test cases/failing/52 slashname/test.json b/test cases/failing/52 slashname/test.json new file mode 100644 index 0000000..180400a --- /dev/null +++ b/test cases/failing/52 slashname/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/52 slashname/meson.build:11:0: ERROR: Problem encountered: Re-enable me once slash in name is finally prohibited." + } + ] +} diff --git a/test cases/failing/53 reserved meson prefix/test.json b/test cases/failing/53 reserved meson prefix/test.json new file mode 100644 index 0000000..502d96a --- /dev/null +++ b/test cases/failing/53 reserved meson prefix/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/53 reserved meson prefix/meson.build:3:0: ERROR: The \"meson-\" prefix is reserved and cannot be used for top-level subdir()." + } + ] +} diff --git a/test cases/failing/54 wrong shared crate type/meson.build b/test cases/failing/54 wrong shared crate type/meson.build index 69ac3da..b9fcad4 100644 --- a/test cases/failing/54 wrong shared crate type/meson.build +++ b/test cases/failing/54 wrong shared crate type/meson.build @@ -1,3 +1,7 @@ -project('test', 'rust') +project('test') + +if not add_languages('rust', required: false) + error('MESON_SKIP_TEST test requires rust compiler') +endif shared_library('test', 'foo.rs', rust_crate_type : 'staticlib') diff --git a/test cases/failing/54 wrong shared crate type/test.json b/test cases/failing/54 wrong shared crate type/test.json new file mode 100644 index 0000000..5cced6f --- /dev/null +++ b/test cases/failing/54 wrong shared crate type/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/54 wrong shared crate type/meson.build:7:0: ERROR: Crate type \"staticlib\" invalid for dynamic libraries; must be \"dylib\" or \"cdylib\"" + } + ] +} diff --git a/test cases/failing/55 wrong static crate type/meson.build b/test cases/failing/55 wrong static crate type/meson.build index c094613..109907f 100644 --- a/test cases/failing/55 wrong static crate type/meson.build +++ b/test cases/failing/55 wrong static crate type/meson.build @@ -1,3 +1,7 @@ -project('test', 'rust') +project('test') + +if not add_languages('rust', required: false) + error('MESON_SKIP_TEST test requires rust compiler') +endif static_library('test', 'foo.rs', rust_crate_type : 'cdylib') diff --git a/test cases/failing/55 wrong static crate type/test.json b/test cases/failing/55 wrong static crate type/test.json new file mode 100644 index 0000000..7073f7b --- /dev/null +++ b/test cases/failing/55 wrong static crate type/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/55 wrong static crate type/meson.build:7:0: ERROR: Crate type \"cdylib\" invalid for static libraries; must be \"rlib\" or \"staticlib\"" + } + ] +} diff --git a/test cases/failing/56 or on new line/test.json b/test cases/failing/56 or on new line/test.json new file mode 100644 index 0000000..c55cee6 --- /dev/null +++ b/test cases/failing/56 or on new line/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/56 or on new line/meson.build:4:8: ERROR: Invalid or clause." + } + ] +} diff --git a/test cases/failing/57 kwarg in module/test.json b/test cases/failing/57 kwarg in module/test.json new file mode 100644 index 0000000..cafb3ab --- /dev/null +++ b/test cases/failing/57 kwarg in module/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/57 kwarg in module/meson.build:3:0: ERROR: Function does not take keyword arguments." + } + ] +} diff --git a/test cases/failing/58 link with executable/test.json b/test cases/failing/58 link with executable/test.json new file mode 100644 index 0000000..d3975c1 --- /dev/null +++ b/test cases/failing/58 link with executable/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/58 link with executable/meson.build:4:0: ERROR: Link target 'prog' is not linkable." + } + ] +} diff --git a/test cases/failing/59 assign custom target index/test.json b/test cases/failing/59 assign custom target index/test.json new file mode 100644 index 0000000..07ecb91 --- /dev/null +++ b/test cases/failing/59 assign custom target index/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/59 assign custom target index/meson.build:24:0: ERROR: Assignment target must be an id." + } + ] +} diff --git a/test cases/failing/6 missing incdir/test.json b/test cases/failing/6 missing incdir/test.json new file mode 100644 index 0000000..172d8a9 --- /dev/null +++ b/test cases/failing/6 missing incdir/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/6 missing incdir/meson.build:3:0: ERROR: Include dir nosuchdir does not exist." + } + ] +} diff --git a/test cases/failing/60 getoption prefix/test.json b/test cases/failing/60 getoption prefix/test.json new file mode 100644 index 0000000..03bf419 --- /dev/null +++ b/test cases/failing/60 getoption prefix/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/60 getoption prefix/meson.build:5:0: ERROR: Having a colon in option name is forbidden, projects are not allowed to directly access options of other subprojects." + } + ] +} diff --git a/test cases/failing/61 bad option argument/test.json b/test cases/failing/61 bad option argument/test.json new file mode 100644 index 0000000..4002005 --- /dev/null +++ b/test cases/failing/61 bad option argument/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/61 bad option argument/meson_options.txt:1:0: ERROR: Invalid kwargs for option \"name\": \"vaule\"" + } + ] +} diff --git a/test cases/failing/62 subproj filegrab/test.json b/test cases/failing/62 subproj filegrab/test.json new file mode 100644 index 0000000..dd0d7bb --- /dev/null +++ b/test cases/failing/62 subproj filegrab/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/62 subproj filegrab/subprojects/a/meson.build:3:0: ERROR: Sandbox violation: Tried to grab file prog.c from a different subproject." + } + ] +} diff --git a/test cases/failing/63 grab subproj/test.json b/test cases/failing/63 grab subproj/test.json new file mode 100644 index 0000000..8147905 --- /dev/null +++ b/test cases/failing/63 grab subproj/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/63 grab subproj/meson.build:7:0: ERROR: Sandbox violation: Tried to grab file sub.c from a different subproject." + } + ] +} diff --git a/test cases/failing/64 grab sibling/test.json b/test cases/failing/64 grab sibling/test.json new file mode 100644 index 0000000..1604d47 --- /dev/null +++ b/test cases/failing/64 grab sibling/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/64 grab sibling/subprojects/a/meson.build:3:0: ERROR: Sandbox violation: Tried to grab file sneaky.c from a different subproject." + } + ] +} diff --git a/test cases/failing/65 string as link target/test.json b/test cases/failing/65 string as link target/test.json new file mode 100644 index 0000000..e212482 --- /dev/null +++ b/test cases/failing/65 string as link target/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/65 string as link target/meson.build:2:0: ERROR: '' is not a target." + } + ] +} diff --git a/test cases/failing/66 dependency not-found and required/test.json b/test cases/failing/66 dependency not-found and required/test.json new file mode 100644 index 0000000..5b13316 --- /dev/null +++ b/test cases/failing/66 dependency not-found and required/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/66 dependency not-found and required/meson.build:2:0: ERROR: Dependency is both required and not-found" + } + ] +} diff --git a/test cases/failing/68 wrong boost module/meson.build b/test cases/failing/68 wrong boost module/meson.build index 7fb3a40..937e587 100644 --- a/test cases/failing/68 wrong boost module/meson.build +++ b/test cases/failing/68 wrong boost module/meson.build @@ -1,5 +1,9 @@ project('boosttest', 'cpp', default_options : ['cpp_std=c++11']) +if not dependency('boost', required: false).found() + error('MESON_SKIP_TEST test requires boost') +endif + # abc doesn't exist linkdep = dependency('boost', modules : ['thread', 'system', 'test', 'abc']) diff --git a/test cases/failing/68 wrong boost module/test.json b/test cases/failing/68 wrong boost module/test.json new file mode 100644 index 0000000..9ef1b0f --- /dev/null +++ b/test cases/failing/68 wrong boost module/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/68 wrong boost module/meson.build:9:0: ERROR: Dependency \"boost\" not found" + } + ] +} diff --git a/test cases/failing/69 install_data rename bad size/test.json b/test cases/failing/69 install_data rename bad size/test.json new file mode 100644 index 0000000..1329fec --- /dev/null +++ b/test cases/failing/69 install_data rename bad size/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/69 install_data rename bad size/meson.build:3:0: ERROR: Size of rename argument is different from number of sources" + } + ] +} diff --git a/test cases/failing/7 go to subproject/test.json b/test cases/failing/7 go to subproject/test.json new file mode 100644 index 0000000..c254757 --- /dev/null +++ b/test cases/failing/7 go to subproject/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/7 go to subproject/meson.build:3:0: ERROR: Must not go into subprojects dir with subdir(), use subproject() instead." + } + ] +} diff --git a/test cases/failing/70 skip only subdir/test.json b/test cases/failing/70 skip only subdir/test.json new file mode 100644 index 0000000..3b40b66 --- /dev/null +++ b/test cases/failing/70 skip only subdir/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/70 skip only subdir/meson.build:8:0: ERROR: File main.cpp does not exist." + } + ] +} diff --git a/test cases/failing/71 dual override/test.json b/test cases/failing/71 dual override/test.json new file mode 100644 index 0000000..66409e6 --- /dev/null +++ b/test cases/failing/71 dual override/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/71 dual override/meson.build:5:6: ERROR: Tried to override executable \"override\" which has already been overridden." + } + ] +} diff --git a/test cases/failing/72 override used/test.json b/test cases/failing/72 override used/test.json new file mode 100644 index 0000000..29a58f1 --- /dev/null +++ b/test cases/failing/72 override used/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/72 override used/meson.build:5:6: ERROR: Tried to override finding of executable \"something.py\" which has already been found." + } + ] +} diff --git a/test cases/failing/73 run_command unclean exit/test.json b/test cases/failing/73 run_command unclean exit/test.json new file mode 100644 index 0000000..beda187 --- /dev/null +++ b/test cases/failing/73 run_command unclean exit/test.json @@ -0,0 +1,8 @@ +{ + "stdout": [ + { + "match": "re", + "line": "test cases/failing/73 run_command unclean exit/meson\\.build:4:0: ERROR: Command \".*[\\\\/]test cases[\\\\/]failing[\\\\/]73 run_command unclean exit[\\\\/]\\.[\\\\/]returncode\\.py 1\" failed with status 1\\." + } + ] +} diff --git a/test cases/failing/74 int literal leading zero/test.json b/test cases/failing/74 int literal leading zero/test.json new file mode 100644 index 0000000..78a735e --- /dev/null +++ b/test cases/failing/74 int literal leading zero/test.json @@ -0,0 +1,8 @@ +{ + "stdout": [ + { + "comment": "this error message is not very informative", + "line": "test cases/failing/74 int literal leading zero/meson.build:5:13: ERROR: Expecting eof got number." + } + ] +} diff --git a/test cases/failing/75 configuration immutable/test.json b/test cases/failing/75 configuration immutable/test.json new file mode 100644 index 0000000..3365aae --- /dev/null +++ b/test cases/failing/75 configuration immutable/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/75 configuration immutable/meson.build:12:16: ERROR: Can not set values on configuration object that has been used." + } + ] +} diff --git a/test cases/failing/76 link with shared module on osx/meson.build b/test cases/failing/76 link with shared module on osx/meson.build index 2c714f9..bf18b36 100644 --- a/test cases/failing/76 link with shared module on osx/meson.build +++ b/test cases/failing/76 link with shared module on osx/meson.build @@ -1,7 +1,7 @@ project('link with shared module', 'c') if host_machine.system() != 'darwin' - error('Test only fails on OSX') + error('MESON_SKIP_TEST test only fails on OSX') endif m = shared_module('mymodule', 'module.c') diff --git a/test cases/failing/76 link with shared module on osx/test.json b/test cases/failing/76 link with shared module on osx/test.json new file mode 100644 index 0000000..4e2856f --- /dev/null +++ b/test cases/failing/76 link with shared module on osx/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/76 link with shared module on osx/meson.build:8:0: ERROR: target links against shared modules." + } + ] +} diff --git a/test cases/failing/77 non ascii in ascii encoded configure file/test.json b/test cases/failing/77 non ascii in ascii encoded configure file/test.json new file mode 100644 index 0000000..e35b95b --- /dev/null +++ b/test cases/failing/77 non ascii in ascii encoded configure file/test.json @@ -0,0 +1,8 @@ +{ + "stdout": [ + { + "match": "re", + "line": "test cases/failing/77 non ascii in ascii encoded configure file/meson\\.build:5:0: ERROR: Could not write output file .*[\\\\/]config9\\.h: 'ascii' codec can't encode character '\\\\u0434' in position 17: ordinal not in range\\(128\\)" + } + ] +} diff --git a/test cases/failing/78 subproj dependency not-found and required/test.json b/test cases/failing/78 subproj dependency not-found and required/test.json new file mode 100644 index 0000000..534b4f4 --- /dev/null +++ b/test cases/failing/78 subproj dependency not-found and required/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/78 subproj dependency not-found and required/meson.build:2:0: ERROR: Subproject directory not found and missing.wrap file not found" + } + ] +} diff --git a/test cases/failing/79 unfound run/test.json b/test cases/failing/79 unfound run/test.json new file mode 100644 index 0000000..6baafc0 --- /dev/null +++ b/test cases/failing/79 unfound run/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/79 unfound run/meson.build:4:0: ERROR: Tried to use non-existing executable 'nonexisting_prog'" + } + ] +} diff --git a/test cases/failing/8 recursive/test.json b/test cases/failing/8 recursive/test.json new file mode 100644 index 0000000..b4c964c --- /dev/null +++ b/test cases/failing/8 recursive/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/8 recursive/subprojects/b/meson.build:3:0: ERROR: Recursive include of subprojects: a => b => a." + } + ] +} diff --git a/test cases/failing/80 framework dependency with version/meson.build b/test cases/failing/80 framework dependency with version/meson.build index 1ead388..b7e04ba 100644 --- a/test cases/failing/80 framework dependency with version/meson.build +++ b/test cases/failing/80 framework dependency with version/meson.build @@ -1,4 +1,8 @@ project('framework dependency with version', 'c') + +if host_machine.system() != 'darwin' + error('MESON_SKIP_TEST test only applicable on darwin') +endif + # do individual frameworks have a meaningful version to test? And multiple frameworks might be listed... -# otherwise we're not on OSX and this will definitely fail dep = dependency('appleframeworks', modules: 'foundation', version: '>0') diff --git a/test cases/failing/80 framework dependency with version/test.json b/test cases/failing/80 framework dependency with version/test.json new file mode 100644 index 0000000..5cbc129 --- /dev/null +++ b/test cases/failing/80 framework dependency with version/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/80 framework dependency with version/meson.build:8:0: ERROR: Unknown version of dependency 'appleframeworks', but need ['>0']." + } + ] +} diff --git a/test cases/failing/81 override exe config/test.json b/test cases/failing/81 override exe config/test.json new file mode 100644 index 0000000..f19785b --- /dev/null +++ b/test cases/failing/81 override exe config/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/81 override exe config/meson.build:6:0: ERROR: Program 'bar' was overridden with the compiled executable 'foo' and therefore cannot be used during configuration" + } + ] +} diff --git a/test cases/failing/82 gl dependency with version/meson.build b/test cases/failing/82 gl dependency with version/meson.build index 3014d43..0127093 100644 --- a/test cases/failing/82 gl dependency with version/meson.build +++ b/test cases/failing/82 gl dependency with version/meson.build @@ -2,7 +2,7 @@ project('gl dependency with version', 'c') host_system = host_machine.system() if host_system != 'windows' and host_system != 'darwin' - error('Test only fails on Windows and OSX') + error('MESON_SKIP_TEST: test only fails on Windows and OSX') endif # gl dependency found via system method doesn't have a meaningful version to check diff --git a/test cases/failing/82 gl dependency with version/test.json b/test cases/failing/82 gl dependency with version/test.json new file mode 100644 index 0000000..2c63a2c --- /dev/null +++ b/test cases/failing/82 gl dependency with version/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/82 gl dependency with version/meson.build:9:0: ERROR: Unknown version of dependency 'gl', but need ['>0']." + } + ] +} diff --git a/test cases/failing/83 threads dependency with version/test.json b/test cases/failing/83 threads dependency with version/test.json new file mode 100644 index 0000000..b131be4 --- /dev/null +++ b/test cases/failing/83 threads dependency with version/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/83 threads dependency with version/meson.build:3:0: ERROR: Unknown version of dependency 'threads', but need ['>0']." + } + ] +} diff --git a/test cases/failing/84 gtest dependency with version/meson.build b/test cases/failing/84 gtest dependency with version/meson.build index 3d90994..b43a047 100644 --- a/test cases/failing/84 gtest dependency with version/meson.build +++ b/test cases/failing/84 gtest dependency with version/meson.build @@ -1,3 +1,8 @@ project('gtest dependency with version', ['c', 'cpp']) + +if not dependency('gtest', method: 'system', required: false).found() + error('MESON_SKIP_TEST test requires gtest') +endif + # discovering gtest version is not yet implemented dep = dependency('gtest', method: 'system', version: '>0') diff --git a/test cases/failing/85 dub libray/meson.build b/test cases/failing/85 dub libray/meson.build index 5b0ccac..306d5b3 100644 --- a/test cases/failing/85 dub libray/meson.build +++ b/test cases/failing/85 dub libray/meson.build @@ -1,3 +1,11 @@ -project('dub', 'd') +project('dub') + +if not add_languages('d', required: false) + error('MESON_SKIP_TEST test requires D compiler') +endif + +if not find_program('dub', required: false).found() + error('MESON_SKIP_TEST test requires dub') +endif dependency('dubtestproject', method: 'dub') # Not library (none) diff --git a/test cases/failing/85 dub libray/test.json b/test cases/failing/85 dub libray/test.json new file mode 100644 index 0000000..a8b3e28 --- /dev/null +++ b/test cases/failing/85 dub libray/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/85 dub libray/meson.build:11:0: ERROR: Dependency \"dubtestproject\" not found" + } + ] +} diff --git a/test cases/failing/86 dub executable/meson.build b/test cases/failing/86 dub executable/meson.build index 63fd631..9a134ea 100644 --- a/test cases/failing/86 dub executable/meson.build +++ b/test cases/failing/86 dub executable/meson.build @@ -1,3 +1,11 @@ -project('dub', 'd') +project('dub') + +if not add_languages('d', required: false) + error('MESON_SKIP_TEST test requires D compiler') +endif + +if not find_program('dub', required: false).found() + error('MESON_SKIP_TEST test requires dub') +endif dependency('dubtestproject:test1', method: 'dub') # Not library (executable) diff --git a/test cases/failing/86 dub executable/test.json b/test cases/failing/86 dub executable/test.json new file mode 100644 index 0000000..f9944af --- /dev/null +++ b/test cases/failing/86 dub executable/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/86 dub executable/meson.build:11:0: ERROR: Dependency \"dubtestproject:test1\" not found" + } + ] +} diff --git a/test cases/failing/87 dub compiler/meson.build b/test cases/failing/87 dub compiler/meson.build index c93ccbc..36f1849 100644 --- a/test cases/failing/87 dub compiler/meson.build +++ b/test cases/failing/87 dub compiler/meson.build @@ -1,4 +1,8 @@ -project('dub', 'd') +project('dub') + +if not add_languages('d', required: false) + error('MESON_SKIP_TEST test requires D compiler') +endif if meson.get_compiler('d').get_id() == 'dmd' if host_machine.system() == 'windows' or host_machine.system() == 'cygwin' @@ -6,4 +10,8 @@ if meson.get_compiler('d').get_id() == 'dmd' endif endif +if not find_program('dub', required: false).found() + error('MESON_SKIP_TEST test requires dub') +endif + dependency('dubtestproject:test2', method: 'dub') # Compiler mismatch diff --git a/test cases/failing/87 dub compiler/test.json b/test cases/failing/87 dub compiler/test.json index acb7da8..f28312f 100644 --- a/test cases/failing/87 dub compiler/test.json +++ b/test cases/failing/87 dub compiler/test.json @@ -2,8 +2,18 @@ "matrix": { "options": { "warning_level": [ - { "val": "1", "skip_on_env": [ "SINGLE_DUB_COMPILER" ] } + { + "val": "1", + "skip_on_env": [ + "SINGLE_DUB_COMPILER" + ] + } ] } - } + }, + "stdout": [ + { + "line": "test cases/failing/87 dub compiler/meson.build:17:0: ERROR: Dependency \"dubtestproject:test2\" not found" + } + ] } diff --git a/test cases/failing/88 subproj not-found dep/test.json b/test cases/failing/88 subproj not-found dep/test.json new file mode 100644 index 0000000..a1c4231 --- /dev/null +++ b/test cases/failing/88 subproj not-found dep/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/88 subproj not-found dep/meson.build:2:0: ERROR: Could not find dependency notfound_dep in subproject somesubproj" + } + ] +} diff --git a/test cases/failing/89 invalid configure file/test.json b/test cases/failing/89 invalid configure file/test.json new file mode 100644 index 0000000..921ce61 --- /dev/null +++ b/test cases/failing/89 invalid configure file/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/89 invalid configure file/meson.build:3:0: ERROR: \"install_dir\" must be specified when \"install\" in a configure_file is true" + } + ] +} diff --git a/test cases/failing/9 missing extra file/test.json b/test cases/failing/9 missing extra file/test.json new file mode 100644 index 0000000..188b6a6 --- /dev/null +++ b/test cases/failing/9 missing extra file/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/9 missing extra file/meson.build:3:0: ERROR: File missing.txt does not exist." + } + ] +} diff --git a/test cases/failing/90 kwarg dupe/test.json b/test cases/failing/90 kwarg dupe/test.json new file mode 100644 index 0000000..a8df75d --- /dev/null +++ b/test cases/failing/90 kwarg dupe/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/90 kwarg dupe/meson.build:5:0: ERROR: Entry \"install\" defined both as a keyword argument and in a \"kwarg\" entry." + } + ] +} diff --git a/test cases/failing/91 missing pch file/test.json b/test cases/failing/91 missing pch file/test.json new file mode 100644 index 0000000..166f627 --- /dev/null +++ b/test cases/failing/91 missing pch file/test.json @@ -0,0 +1,8 @@ +{ + "stdout": [ + { + "comment": "literal 'pch/prog.h' from meson.build appears in output, irrespective of os.path.sep", + "line": "test cases/failing/91 missing pch file/meson.build:2:0: ERROR: File pch/prog.h does not exist." + } + ] +} diff --git a/test cases/failing/92 pch source different folder/test.json b/test cases/failing/92 pch source different folder/test.json new file mode 100644 index 0000000..d94db50 --- /dev/null +++ b/test cases/failing/92 pch source different folder/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/92 pch source different folder/meson.build:4:0: ERROR: PCH files must be stored in the same folder." + } + ] +} diff --git a/test cases/failing/93 vala without c/test.json b/test cases/failing/93 vala without c/test.json new file mode 100644 index 0000000..6185b7e --- /dev/null +++ b/test cases/failing/93 vala without c/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/93 vala without c/meson.build:2:0: ERROR: Compiling Vala requires C. Add C to your project languages and rerun Meson." + } + ] +} diff --git a/test cases/failing/94 unknown config tool/test.json b/test cases/failing/94 unknown config tool/test.json new file mode 100644 index 0000000..a001152 --- /dev/null +++ b/test cases/failing/94 unknown config tool/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/94 unknown config tool/meson.build:2:0: ERROR: Dependency \"no-such-config-tool\" not found" + } + ] +} diff --git a/test cases/failing/95 custom target install data/test.json b/test cases/failing/95 custom target install data/test.json new file mode 100644 index 0000000..64ef530 --- /dev/null +++ b/test cases/failing/95 custom target install data/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/95 custom target install data/meson.build:11:0: ERROR: Argument must be string or file." + } + ] +} diff --git a/test cases/failing/96 add dict non string key/test.json b/test cases/failing/96 add dict non string key/test.json new file mode 100644 index 0000000..5fd4033 --- /dev/null +++ b/test cases/failing/96 add dict non string key/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/96 add dict non string key/meson.build:9:0: ERROR: Key must be a string" + } + ] +} diff --git a/test cases/failing/97 add dict duplicate keys/test.json b/test cases/failing/97 add dict duplicate keys/test.json new file mode 100644 index 0000000..9d01551 --- /dev/null +++ b/test cases/failing/97 add dict duplicate keys/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/97 add dict duplicate keys/meson.build:9:0: ERROR: Duplicate dictionary key: myKey" + } + ] +} diff --git a/test cases/failing/99 no native prop/test.json b/test cases/failing/99 no native prop/test.json new file mode 100644 index 0000000..8c320d9 --- /dev/null +++ b/test cases/failing/99 no native prop/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/99 no native prop/meson.build:3:0: ERROR: Unknown native property: nonexisting." + } + ] +} diff --git a/test cases/frameworks/21 libwmf/meson.build b/test cases/frameworks/21 libwmf/meson.build index 6952bf7..9dbab6a 100644 --- a/test cases/frameworks/21 libwmf/meson.build +++ b/test cases/frameworks/21 libwmf/meson.build @@ -1,7 +1,7 @@ project('libwmf test', 'c') wm = find_program('libwmf-config', required : false) -if not wm.found() +if not wm.found() or meson.is_cross_build() error('MESON_SKIP_TEST: libwmf-config not installed') endif diff --git a/test cases/frameworks/7 gnome/gir/dep1/dep3/dep3.c b/test cases/frameworks/7 gnome/gir/dep1/dep3/dep3.c new file mode 100644 index 0000000..ee5c5e1 --- /dev/null +++ b/test cases/frameworks/7 gnome/gir/dep1/dep3/dep3.c @@ -0,0 +1,124 @@ +#include "dep3.h" + +struct _MesonDep3 +{ + GObject parent_instance; + + gchar *msg; +}; + +G_DEFINE_TYPE (MesonDep3, meson_dep3, G_TYPE_OBJECT) + +enum { + PROP_0, + PROP_MSG, + LAST_PROP +}; + +static GParamSpec *gParamSpecs [LAST_PROP]; + +/** + * meson_dep3_new: + * @msg: The message to set. + * + * Allocates a new #MesonDep3. + * + * Returns: (transfer full): a #MesonDep3. + */ +MesonDep3 * +meson_dep3_new (const gchar *msg) +{ + g_return_val_if_fail (msg != NULL, NULL); + + return g_object_new (MESON_TYPE_DEP3, + "message", msg, + NULL); +} + +static void +meson_dep3_finalize (GObject *object) +{ + MesonDep3 *self = (MesonDep3 *)object; + + g_clear_pointer (&self->msg, g_free); + + G_OBJECT_CLASS (meson_dep3_parent_class)->finalize (object); +} + +static void +meson_dep3_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MesonDep3 *self = MESON_DEP3 (object); + + switch (prop_id) + { + case PROP_MSG: + g_value_set_string (value, self->msg); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meson_dep3_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MesonDep3 *self = MESON_DEP3 (object); + + switch (prop_id) + { + case PROP_MSG: + self->msg = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meson_dep3_class_init (MesonDep3Class *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meson_dep3_finalize; + object_class->get_property = meson_dep3_get_property; + object_class->set_property = meson_dep3_set_property; + + gParamSpecs [PROP_MSG] = + g_param_spec_string ("message", + "Message", + "The message to print.", + NULL, + (G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs); +} + +static void +meson_dep3_init (MesonDep3 *self) +{ +} + +/** + * meson_dep3_return_message: + * @self: a #MesonDep3. + * + * Returns the message. + * + * Returns: (transfer none): a const gchar* + */ +const gchar* +meson_dep3_return_message (MesonDep3 *self) +{ + g_return_val_if_fail (MESON_IS_DEP3 (self), NULL); + + return (const gchar*) self->msg; +} diff --git a/test cases/frameworks/7 gnome/gir/dep1/dep3/dep3.h b/test cases/frameworks/7 gnome/gir/dep1/dep3/dep3.h new file mode 100644 index 0000000..9883d76 --- /dev/null +++ b/test cases/frameworks/7 gnome/gir/dep1/dep3/dep3.h @@ -0,0 +1,21 @@ +#ifndef MESON_DEP3_H +#define MESON_DEP3_H + +#if !defined (MESON_TEST) +#error "MESON_TEST not defined." +#endif + +#include <glib-object.h> + +G_BEGIN_DECLS + +#define MESON_TYPE_DEP3 (meson_dep3_get_type()) + +G_DECLARE_FINAL_TYPE (MesonDep3, meson_dep3, MESON, DEP3, GObject) + +MesonDep3 *meson_dep3_new (const gchar *msg); +const gchar *meson_dep3_return_message (MesonDep3 *self); + +G_END_DECLS + +#endif /* MESON_DEP3_H */ diff --git a/test cases/frameworks/7 gnome/gir/dep1/dep3/meson.build b/test cases/frameworks/7 gnome/gir/dep1/dep3/meson.build new file mode 100644 index 0000000..1ef7765 --- /dev/null +++ b/test cases/frameworks/7 gnome/gir/dep1/dep3/meson.build @@ -0,0 +1,22 @@ +dep3sources = ['dep3.c', 'dep3.h'] + +dep3lib = shared_library( + 'dep3lib', + sources : dep3sources, + dependencies : gobj, + install : true +) + +dep3gir = gnome.generate_gir( + dep3lib, + sources : dep3sources, + nsversion : '1.0', + namespace : 'MesonDep3', + symbol_prefix : 'meson', + identifier_prefix : 'Meson', + includes : ['GObject-2.0'], + install : true +) + +dep3_dep = declare_dependency(link_with : dep3lib, + sources : [dep3gir]) diff --git a/test cases/frameworks/7 gnome/gir/dep1/meson.build b/test cases/frameworks/7 gnome/gir/dep1/meson.build index baa0b1d..2f03ede 100644 --- a/test cases/frameworks/7 gnome/gir/dep1/meson.build +++ b/test cases/frameworks/7 gnome/gir/dep1/meson.build @@ -1,4 +1,5 @@ subdir('dep2') +subdir('dep3') dep1sources = ['dep1.c', 'dep1.h'] @@ -20,11 +21,11 @@ dep1gir = gnome.generate_gir( symbol_prefix : 'meson', identifier_prefix : 'Meson', header: 'dep1.h', - includes : ['GObject-2.0', 'MesonDep2-1.0'], + includes : ['GObject-2.0', 'MesonDep2-1.0', dep3gir[0]], dependencies : [dep2_dep], install : true ) dep1_dep = declare_dependency(link_with : dep1lib, - dependencies : [dep2_dep], + dependencies : [dep2_dep, dep3_dep], sources : [dep1gir]) diff --git a/test cases/frameworks/7 gnome/gir/meson.build b/test cases/frameworks/7 gnome/gir/meson.build index 36bd09c..b1e0fa1 100644 --- a/test cases/frameworks/7 gnome/gir/meson.build +++ b/test cases/frameworks/7 gnome/gir/meson.build @@ -45,7 +45,7 @@ gnome.generate_gir( ) test('gobject introspection/c', girexe) -gir_paths = ':'.join([girlib.outdir(), dep1lib.outdir(), dep2lib.outdir()]) +gir_paths = ':'.join([girlib.outdir(), dep1lib.outdir(), dep2lib.outdir(), dep3lib.outdir()]) envdata = environment() envdata.append('GI_TYPELIB_PATH', gir_paths, separator : ':') envdata.append('LD_LIBRARY_PATH', gir_paths) diff --git a/test cases/frameworks/7 gnome/test.json b/test cases/frameworks/7 gnome/test.json index e69c9f0..badf410 100644 --- a/test cases/frameworks/7 gnome/test.json +++ b/test cases/frameworks/7 gnome/test.json @@ -13,12 +13,16 @@ {"type": "file", "platform": "cygwin", "file": "usr/lib/libdep1lib.dll.a"}, {"type": "expr", "file": "usr/lib/?libdep2lib.so"}, {"type": "file", "platform": "cygwin", "file": "usr/lib/libdep2lib.dll.a"}, + {"type": "expr", "file": "usr/lib/?libdep3lib.so"}, + {"type": "file", "platform": "cygwin", "file": "usr/lib/libdep3lib.dll.a"}, {"type": "file", "file": "usr/lib/girepository-1.0/Meson-1.0.typelib"}, {"type": "file", "file": "usr/lib/girepository-1.0/MesonDep1-1.0.typelib"}, {"type": "file", "file": "usr/lib/girepository-1.0/MesonDep2-1.0.typelib"}, + {"type": "file", "file": "usr/lib/girepository-1.0/MesonDep3-1.0.typelib"}, {"type": "file", "file": "usr/share/gir-1.0/Meson-1.0.gir"}, {"type": "file", "file": "usr/share/gir-1.0/MesonDep1-1.0.gir"}, {"type": "file", "file": "usr/share/gir-1.0/MesonDep2-1.0.gir"}, + {"type": "file", "file": "usr/share/gir-1.0/MesonDep3-1.0.gir"}, {"type": "file", "file": "usr/share/glib-2.0/schemas/com.github.meson.gschema.xml"}, {"type": "file", "file": "usr/share/simple-resources.gresource"}, {"type": "file", "file": "usr/include/enums6.h"}, diff --git a/test cases/unit/36 exe_wrapper behaviour/meson.build b/test cases/unit/36 exe_wrapper behaviour/meson.build index 16a44d5..d0817ba 100644 --- a/test cases/unit/36 exe_wrapper behaviour/meson.build +++ b/test cases/unit/36 exe_wrapper behaviour/meson.build @@ -1,7 +1,7 @@ project('exe wrapper behaviour', 'c') assert(meson.is_cross_build(), 'not setup as cross build') -assert(meson.has_exe_wrapper(), 'exe wrapper not defined?') +assert(meson.has_exe_wrapper(), 'exe wrapper not defined?') # intentionally not changed to can_run_host_binaries, exe = executable('prog', 'prog.c') diff --git a/test cases/warning/1 version for string div/test.json b/test cases/warning/1 version for string div/test.json new file mode 100644 index 0000000..c37931a --- /dev/null +++ b/test cases/warning/1 version for string div/test.json @@ -0,0 +1,8 @@ +{ + "stdout": [ + { + "comment": "literal '/' appears in output, irrespective of os.path.sep, as that's the operator", + "line": "WARNING: Project targeting '>=0.48.0' but tried to use feature introduced in '0.49.0': / with string arguments." + } + ] +} diff --git a/test cases/warning/2 languages missing native/test.json b/test cases/warning/2 languages missing native/test.json new file mode 100644 index 0000000..36da0a7 --- /dev/null +++ b/test cases/warning/2 languages missing native/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/warning/2 languages missing native/meson.build:2: WARNING: add_languages is missing native:, assuming languages are wanted for both host and build." + } + ] +} diff --git a/tools/dircondenser.py b/tools/dircondenser.py index 023c14e..0e28bec 100755 --- a/tools/dircondenser.py +++ b/tools/dircondenser.py @@ -74,6 +74,10 @@ def condense(dirname: str): #print('git mv "%s" "%s"' % (old_name, new_name)) subprocess.check_call(['git', 'mv', old_name, new_name]) replacements.append((old_name, new_name)) + # update any appearances of old_name in expected stdout in test.json + json = os.path.join(new_name, 'test.json') + if os.path.isfile(json): + replace_source(json, [(old_name, new_name)]) os.chdir(curdir) replace_source('run_unittests.py', replacements) replace_source('run_project_tests.py', replacements) |