diff options
69 files changed, 506 insertions, 165 deletions
diff --git a/.travis.yml b/.travis.yml index 559b39c..e69cb31 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,13 +33,13 @@ before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install python3; fi # Use a Ninja with QuLogic's patch: https://github.com/ninja-build/ninja/issues/1219 - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then mkdir -p $HOME/tools; curl -L http://nirbheek.in/files/binaries/ninja/macos/ninja -o $HOME/tools/ninja; chmod +x $HOME/tools/ninja; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker pull jpakkane/mesonci:zesty; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker pull jpakkane/mesonci:artful; fi # We need to copy the current checkout inside the Docker container, # because it has the MR id to be tested checked out. script: - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo FROM jpakkane/mesonci:zesty > Dockerfile; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo FROM jpakkane/mesonci:artful > Dockerfile; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo ADD . /root >> Dockerfile; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker build -t withgit .; fi - | diff --git a/ciimage/Dockerfile b/ciimage/Dockerfile index 1c9e8d8..a2e3433 100644 --- a/ciimage/Dockerfile +++ b/ciimage/Dockerfile @@ -1,16 +1,15 @@ -FROM ubuntu:zesty +FROM ubuntu:artful RUN apt-get -y update && apt-get -y upgrade \ && apt-get -y install git wget unzip \ && apt-get -y build-dep meson \ -&& apt-get -y install qt5-default itstool clang libgtk-3-dev \ -&& apt-get -y install pkg-config-arm-linux-gnueabihf g++-6-arm-linux-gnueabihf \ -&& apt-get -y install valgrind doxygen \ -&& apt-get -y install llvm libsdl2-dev \ +&& apt-get -y install qt5-default clang \ +&& apt-get -y install pkg-config-arm-linux-gnueabihf g++-7-arm-linux-gnueabihf \ +&& apt-get -y install doxygen \ && apt-get -y install python3-pip libxml2-dev libxslt1-dev cmake libyaml-dev \ -&& apt-get -y install openmpi-bin libopenmpi-dev \ -&& apt-get -y install libboost-log-dev \ -&& apt-get -y install libvulkan-dev libpcap-dev libcups2-dev \ +&& apt-get -y install libcups2-dev \ && apt-get -y install gcovr lcov \ +&& apt-get -y install fpga-icestorm arachne-pnr yosys \ && apt-get -y install gtk-sharp2 gtk-sharp2-gapi libglib2.0-cil-dev \ +&& apt-get -y install libwmf-dev \ && python3 -m pip install hotdoc codecov diff --git a/cross/ubuntu-armhf.txt b/cross/ubuntu-armhf.txt index d0fce20..367eba3 100644 --- a/cross/ubuntu-armhf.txt +++ b/cross/ubuntu-armhf.txt @@ -1,8 +1,8 @@ [binaries] # we could set exe_wrapper = qemu-arm-static but to test the case # when cross compiled binaries can't be run we don't do that -c = '/usr/bin/arm-linux-gnueabihf-gcc-6' -cpp = '/usr/bin/arm-linux-gnueabihf-g++-6' +c = '/usr/bin/arm-linux-gnueabihf-gcc-7' +cpp = '/usr/bin/arm-linux-gnueabihf-g++-7' ar = '/usr/arm-linux-gnueabihf/bin/ar' strip = '/usr/arm-linux-gnueabihf/bin/strip' pkgconfig = '/usr/bin/arm-linux-gnueabihf-pkg-config' diff --git a/docs/markdown/Cross-compilation.md b/docs/markdown/Cross-compilation.md index e232033..f68b1f5 100644 --- a/docs/markdown/Cross-compilation.md +++ b/docs/markdown/Cross-compilation.md @@ -69,6 +69,7 @@ c = '/usr/bin/i586-mingw32msvc-gcc' cpp = '/usr/bin/i586-mingw32msvc-g++' ar = '/usr/i586-mingw32msvc/bin/ar' strip = '/usr/i586-mingw32msvc/bin/strip' +pkgconfig = '/usr/bin/i586-mingw32msvc-pkg-config' exe_wrapper = 'wine' # A command used to run generated executables. ``` diff --git a/docs/markdown/Dependencies.md b/docs/markdown/Dependencies.md index c3f007f..8e780d6 100644 --- a/docs/markdown/Dependencies.md +++ b/docs/markdown/Dependencies.md @@ -45,7 +45,52 @@ non-found dependencies. The dependency detector works with all libraries that provide a `pkg-config` file. Unfortunately several packages don't provide -pkg-config files. Meson has autodetection support for some of these. +pkg-config files. Meson has autodetection support for some of these, +and they are described later on this page. + +# Declaring your own + +You can declare your own dependency objects that can be used +interchangeably with dependency objects obtained from the system. The +syntax is straightforward: + +```meson +my_inc = include_directories(...) +my_lib = static_library(...) +my_dep = declare_dependency(link_with : my_lib, + include_directories : my_inc) +``` + +This declares a dependency that adds the given include directories and +static library to any target you use it in. + +# Building dependencies as subprojects + +Many platforms do not provide a system package manager. On these +systems dependencies must be compiled from source. Meson's subprojects +make it simple to use system dependencies when they are available and +to build dependencies manually when they are not. + +To make this work, the dependency must have Meson build definitions +and it must declare its own dependency like this: + + foo_dep = declare_dependency(...) + +Then any project that wants to use it can write out the following +declaration in their main `meson.build` file. + + foo_dep = dependency('foo', fallback : ['foo', 'foo_dep']) + +What this declaration means is that first Meson tries to look up the +dependency from the system (such as by using pkg-config). If it is not +available, then it builds subproject named `foo` and from that +extracts a variable `foo_dep`. That means that the return value of +this function is either an external or an internal dependency +object. Since they can be used interchangeably, the rest of the build +definitions do not need to care which one it is. Meson will take care +of all the work behind the scenes to make this work. + +# Dependencies with custom lookup functionality ## Boost @@ -153,18 +198,12 @@ automatically: cups_dep = dependency('cups', version : '>=1.4') ``` -## Declaring your own +## LibWMF -You can declare your own dependency objects that can be used -interchangeably with dependency objects obtained from the system. The -syntax is straightforward: +The libwmf library does not ship with pkg-config at the time or writing +but instead it has its own `libwmf-config` util. Meson will use it +automatically: ```meson -my_inc = include_directories(...) -my_lib = static_library(...) -my_dep = declare_dependency(link_with : my_lib, - include_directories : my_inc) +libwmf_dep = dependency('libwmf', version : '>=0.2.8') ``` - -This declares a dependency that adds the given include directories and -static library to any target you use it in. diff --git a/docs/markdown/Qt5-module.md b/docs/markdown/Qt5-module.md index a8ad73d..aea2ae1 100644 --- a/docs/markdown/Qt5-module.md +++ b/docs/markdown/Qt5-module.md @@ -5,17 +5,22 @@ tools and steps required for Qt. The module has one method. ## preprocess -This method takes five keyword arguments, `moc_headers`, -`moc_sources`, `ui_files` and `qresources` which define the files that -require preprocessing with `moc`, `uic` and `rcc` and 'include_directories' which might be needed by moc. It returns an -opaque object that should be passed to a main build target. A simple -example would look like this: +This method takes the following keyword arguments: + - `moc_headers`, `moc_sources`, `ui_files`, `qresources`, which define the files that require preprocessing with `moc`, `uic` and `rcc` + - `include_directories`, the directories to add to header search path for `moc` (optional) + - `moc_extra_arguments`, any additional arguments to `moc` (optional). Available since v0.44.0. + +It returns an opaque object that should be passed to a main build target. + +A simple example would look like this: ```meson qt5 = import('qt5') qt5_dep = dependency('qt5', modules: ['Core', 'Gui']) inc = include_directories('includes') -moc_files = qt5.preprocess(moc_headers : 'myclass.h', include_directories: inc) +moc_files = qt5.preprocess(moc_headers : 'myclass.h', + moc_extra_arguments: ['-DMAKES_MY_MOC_HEADER_COMPILE'], + include_directories: inc) executable('myprog', 'main.cpp', 'myclass.cpp', moc_files, include_directories: inc, dependencies : qt5_dep) diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md index 42d02e1..eee4405 100644 --- a/docs/markdown/Reference-manual.md +++ b/docs/markdown/Reference-manual.md @@ -95,10 +95,10 @@ the following: - `gdb` if `true`, the tests are also run under `gdb` - `timeout_multiplier` a number to multiply the test timeout with -To use the test setup, run `mesontest --setup=*name*` inside the build dir. +To use the test setup, run `meson test --setup=*name*` inside the build dir. Note that all these options are also available while running the -`mesontest` script for running tests instead of `ninja test` or +`meson test` script for running tests instead of `ninja test` or `msbuild RUN_TESTS.vcxproj`, etc depending on the backend. ### benchmark() @@ -847,6 +847,14 @@ The keyword arguments for this are the same as for [`executable`](#executable) w This function prints its argument to stdout. +### warning() + +``` meson + void warning(text) +``` + +This function prints its argument to stdout prefixed with WARNING:. + ### project() ``` meson @@ -1084,7 +1092,7 @@ arguments are the following. for the test Defined tests can be run in a backend-agnostic way by calling -`mesontest` inside the build dir, or by using backend-specific +`meson test` inside the build dir, or by using backend-specific commands, such as `ninja test` or `msbuild RUN_TESTS.vcxproj`. ### vcs_tag() diff --git a/docs/markdown/Subprojects.md b/docs/markdown/Subprojects.md index 85453e3..923b6a3 100644 --- a/docs/markdown/Subprojects.md +++ b/docs/markdown/Subprojects.md @@ -42,7 +42,7 @@ else l = sp.get_variable('l') endif exe = executable('prog', 'prog.c', include_directories : i, link_with : l, - deps : dep, install : true) + dependencies : dep, install : true) ``` With this setup the system dependency is used when it is available, otherwise we fall back on the bundled version. diff --git a/docs/markdown/Unit-tests.md b/docs/markdown/Unit-tests.md index 6ded714..afbeaa0 100644 --- a/docs/markdown/Unit-tests.md +++ b/docs/markdown/Unit-tests.md @@ -95,7 +95,7 @@ Meson also supports running the tests under GDB. Just doing this: $ meson test --gdb testname ``` -Mesontest will launch `gdb` all set up to run the test. Just type `run` in the GDB command prompt to start the program. +Meson will launch `gdb` all set up to run the test. Just type `run` in the GDB command prompt to start the program. The second use case is a test that segfaults only rarely. In this case you can invoke the following command: @@ -103,8 +103,8 @@ The second use case is a test that segfaults only rarely. In this case you can i $ meson test --gdb --repeat=10000 testname ``` -This runs the test up to 10 000 times under GDB automatically. If the program crashes, GDB will halt and the user can debug the application. Note that testing timeouts are disabled in this case so mesontest will not kill `gdb` while the developer is still debugging it. The downside is that if the test binary freezes, the test runner will wait forever. +This runs the test up to 10 000 times under GDB automatically. If the program crashes, GDB will halt and the user can debug the application. Note that testing timeouts are disabled in this case so `meson test` will not kill `gdb` while the developer is still debugging it. The downside is that if the test binary freezes, the test runner will wait forever. -For further information see the command line help of Mesontest by running `mesontest -h`. +For further information see the command line help of Meson by running `meson test -h`. **NOTE:** If `meson test` does not work for you, you likely have a old version of Meson. In that case you should call `mesontest` instead. If `mesontest` doesn't work either you have a very old version prior to 0.37.0 and should upgrade. diff --git a/docs/markdown/Using-wraptool.md b/docs/markdown/Using-wraptool.md index e000695..8e5f898 100644 --- a/docs/markdown/Using-wraptool.md +++ b/docs/markdown/Using-wraptool.md @@ -53,7 +53,7 @@ To check if your projects are up to date you can issue the `status` command. In this case `zlib` has a newer release available. Updating it is straightforward: - $ wraptool.py update zlib + $ wraptool update zlib Updated zlib to branch 1.2.8 revision 4 Wraptool can do other things besides these. Documentation for these can be found in the command line help, which can be accessed by `wraptool --help`. diff --git a/docs/markdown/Wrap-dependency-system-manual.md b/docs/markdown/Wrap-dependency-system-manual.md index a850896..d97fc9a 100644 --- a/docs/markdown/Wrap-dependency-system-manual.md +++ b/docs/markdown/Wrap-dependency-system-manual.md @@ -52,7 +52,7 @@ are downloaded and automatically applied to the subproject. These files contain a Meson build definition for the given subproject. A wrap file with an additional patch URL would look like this. -``` +```ini [wrap-file] directory = libfoobar-1.0 @@ -83,7 +83,7 @@ packaged files. Sometimes you want to check code out directly from Git. Meson supports this natively. All you need to do is to write a slightly different wrap file. -``` +```ini [wrap-git] directory=samplesubproject url=https://github.com/jpakkane/samplesubproject.git diff --git a/docs/markdown/snippets/qt5-moc_extra_arguments.md b/docs/markdown/snippets/qt5-moc_extra_arguments.md new file mode 100644 index 0000000..957c3c7 --- /dev/null +++ b/docs/markdown/snippets/qt5-moc_extra_arguments.md @@ -0,0 +1,8 @@ +# Adds support for additional Qt5-Module keyword `moc_extra_arguments` + +When `moc`-ing sources, the `moc` tool does not know about any +preprocessor macros. The generated code might not match the input +files when the linking with the moc input sources happens. + +This amendment allows to specify a a list of additional arguments +passed to the `moc` tool. They are called `moc_extra_arguments`.
\ No newline at end of file diff --git a/docs/markdown/snippets/warning_function b/docs/markdown/snippets/warning_function new file mode 100644 index 0000000..537651e --- /dev/null +++ b/docs/markdown/snippets/warning_function @@ -0,0 +1,6 @@ +# Added warning function + +This function prints its argument to the console prefixed by "WARNING:" in +yellow color. A simple example: + +warning('foo is deprecated, please use bar instead') diff --git a/man/meson.1 b/man/meson.1 index 04b56de..1333904 100644 --- a/man/meson.1 +++ b/man/meson.1 @@ -115,12 +115,14 @@ print command line help .SH The test command -Mesontest is a helper tool for running test suites of projects using Meson. +.B meson test +is a helper tool for running test suites of projects using Meson. The default way of running tests is to invoke the default build command: \fBninja [\fR \fItest\fR \fB]\fR -Mesontest provides a richer set of tools for invoking tests. +.B meson test +provides a richer set of tools for invoking tests. .SS "options:" .TP diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index bb281e1..c633daf 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -534,7 +534,7 @@ int dummy; elem.add_item('COMMAND', cmd) elem.add_item('description', desc.format(target.name, cmd_type)) elem.write(outfile) - self.processed_targets[target.name + target.type_suffix()] = True + self.processed_targets[target.get_id()] = True def generate_run_target(self, target, outfile): cmd = self.environment.get_build_command() + ['--internal', 'commandrunner'] @@ -552,7 +552,12 @@ int dummy; arg_strings.append(os.path.join(self.environment.get_build_dir(), relfname)) else: raise AssertionError('Unreachable code in generate_run_target: ' + str(i)) - elem = NinjaBuildElement(self.all_outputs, 'meson-' + target.name, 'CUSTOM_COMMAND', []) + if target.subproject != '': + subproject_prefix = '{}@@'.format(target.subproject) + else: + subproject_prefix = '' + target_name = 'meson-{}{}'.format(subproject_prefix, target.name) + elem = NinjaBuildElement(self.all_outputs, target_name, 'CUSTOM_COMMAND', []) cmd += [self.environment.get_source_dir(), self.environment.get_build_dir(), target.subdir] + self.environment.get_build_command() @@ -588,8 +593,8 @@ int dummy; elem.add_item('pool', 'console') elem.write(outfile) # Alias that runs the target defined above with the name the user specified - self.create_target_alias('meson-' + target.name, outfile) - self.processed_targets[target.name + target.type_suffix()] = True + self.create_target_alias(target_name, outfile) + self.processed_targets[target.get_id()] = True def generate_coverage_rules(self, outfile): e = NinjaBuildElement(self.all_outputs, 'meson-coverage', 'CUSTOM_COMMAND', 'PHONY') diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 2a71b8b..12f4bdb 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -279,7 +279,7 @@ class EnvironmentVariables: return env class Target: - def __init__(self, name, subdir, build_by_default): + def __init__(self, name, subdir, subproject, build_by_default): if '/' in name or '\\' in name: # Fix failing test 53 when this becomes an error. mlog.warning('''Target "%s" has a path separator in its name. @@ -287,6 +287,7 @@ This is not supported, it can cause unexpected failures and will become a hard error in the future.''' % name) self.name = name self.subdir = subdir + self.subproject = subproject self.build_by_default = build_by_default self.install = False self.build_always = False @@ -298,6 +299,15 @@ a hard error in the future.''' % name) def get_subdir(self): return self.subdir + def get_id(self): + # This ID must also be a valid file name on all OSs. + # It should also avoid shell metacharacters for obvious + # reasons. + base = self.name + self.type_suffix() + if self.subproject == '': + return base + return self.subproject + '@@' + base + def process_kwargs(self, kwargs): if 'build_by_default' in kwargs: self.build_by_default = kwargs['build_by_default'] @@ -320,8 +330,7 @@ a hard error in the future.''' % name) class BuildTarget(Target): def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs): - super().__init__(name, subdir, True) - self.subproject = subproject # Can not be calculated from subdir as subproject dirname can be changed per project. + super().__init__(name, subdir, subproject, True) self.is_cross = is_cross unity_opt = environment.coredata.get_builtin_option('unity') self.is_unity = unity_opt == 'on' or (unity_opt == 'subprojects' and subproject != '') @@ -374,15 +383,6 @@ class BuildTarget(Target): if environment.is_cross_build() and not self.is_cross and self.install: raise InvalidArguments('Tried to install a natively built target in a cross build.') - def get_id(self): - # This ID must also be a valid file name on all OSs. - # It should also avoid shell metacharacters for obvious - # reasons. - base = self.name + self.type_suffix() - if self.subproject == '': - return base - return self.subproject + '@@' + base - def check_unknown_kwargs(self, kwargs): # Override this method in derived classes that have more # keywords. @@ -863,6 +863,8 @@ You probably should put it in link_with instead.''') def link(self, target): for t in listify(target, unholder=True): + if not isinstance(t, Target): + 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)) if isinstance(self, SharedLibrary) and isinstance(t, StaticLibrary) and not t.pic: @@ -1509,8 +1511,8 @@ class CustomTarget(Target): 'override_options': True, } - def __init__(self, name, subdir, kwargs, absolute_paths=False): - super().__init__(name, subdir, False) + def __init__(self, name, subdir, subproject, kwargs, absolute_paths=False): + super().__init__(name, subdir, subproject, False) self.dependencies = [] self.extra_depends = [] self.depend_files = [] # Files that this target depends on but are not on the command line. @@ -1687,8 +1689,8 @@ class CustomTarget(Target): raise NotImplementedError class RunTarget(Target): - def __init__(self, name, command, args, dependencies, subdir): - super().__init__(name, subdir, False) + def __init__(self, name, command, args, dependencies, subdir, subproject): + super().__init__(name, subdir, subproject, False) self.command = command self.args = args self.dependencies = dependencies @@ -1700,9 +1702,6 @@ class RunTarget(Target): repr_str = "<{0} {1}: {2}>" return repr_str.format(self.__class__.__name__, self.get_id(), self.command) - def get_id(self): - return self.name + self.type_suffix() - def get_dependencies(self): return self.dependencies diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 3f088b0..bacf478 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -923,11 +923,15 @@ def get_largefile_args(compiler): def gnulike_default_include_dirs(compiler, lang): if lang == 'cpp': lang = 'c++' + env = os.environ.copy() + env["LC_ALL"] = 'C' + cmd = compiler + ['-x{}'.format(lang), '-E', '-v', '-'] p = subprocess.Popen( - compiler + ['-x{}'.format(lang), '-E', '-v', '-'], + cmd, stdin=subprocess.DEVNULL, stderr=subprocess.PIPE, - stdout=subprocess.PIPE + stdout=subprocess.PIPE, + env=env ) stderr = p.stderr.read().decode('utf-8') parse_state = 0 @@ -946,6 +950,8 @@ def gnulike_default_include_dirs(compiler, lang): break else: paths.append(line[1:]) + if len(paths) == 0: + mlog.warning('No include directory found parsing "{cmd}" output'.format(cmd=" ".join(cmd))) return paths class GnuCompiler: diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index cf5f077..ba5d2ac 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -29,9 +29,6 @@ class UserOption: self.choices = choices self.description = description - def parse_string(self, valuestring): - return valuestring - # Check that the input is a valid value and return the # "cleaned" or "native" version. For example the Boolean # option could take the string "true" and return True. @@ -72,13 +69,6 @@ class UserBooleanOption(UserOption): def set_value(self, newvalue): self.value = self.tobool(newvalue) - def parse_string(self, valuestring): - if valuestring == 'false': - return False - if valuestring == 'true': - return True - raise MesonException('Value "%s" for boolean option "%s" is not a boolean.' % (valuestring, self.name)) - def __bool__(self): return self.value @@ -109,9 +99,6 @@ class UserIntegerOption(UserOption): except: raise MesonException('Value string "%s" is not convertable to an integer.' % valuestring) - def parse_string(self, valuestring): - return self.toint(valuestring) - def validate_value(self, value): return self.toint(value) diff --git a/mesonbuild/dependencies/__init__.py b/mesonbuild/dependencies/__init__.py index aa29190..4dc2b27 100644 --- a/mesonbuild/dependencies/__init__.py +++ b/mesonbuild/dependencies/__init__.py @@ -17,7 +17,7 @@ from .base import ( # noqa: F401 ExternalDependency, ExternalLibrary, ExtraFrameworkDependency, InternalDependency, PkgConfigDependency, find_external_dependency, get_dep_identifier, packages, _packages_accept_language) from .dev import GMockDependency, GTestDependency, LLVMDependency, ValgrindDependency -from .misc import (BoostDependency, MPIDependency, Python3Dependency, ThreadDependency, PcapDependency, CupsDependency) +from .misc import (BoostDependency, MPIDependency, Python3Dependency, ThreadDependency, PcapDependency, CupsDependency, LibWmfDependency) from .platform import AppleFrameworks from .ui import GLDependency, GnuStepDependency, Qt4Dependency, Qt5Dependency, SDL2Dependency, WxDependency, VulkanDependency @@ -36,6 +36,7 @@ packages.update({ 'threads': ThreadDependency, 'pcap': PcapDependency, 'cups': CupsDependency, + 'libwmf': LibWmfDependency, # From platform: 'appleframeworks': AppleFrameworks, diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py index 9913a0b..05170ff 100644 --- a/mesonbuild/dependencies/base.py +++ b/mesonbuild/dependencies/base.py @@ -48,6 +48,8 @@ class DependencyMethods(Enum): PCAPCONFIG = 'pcap-config' # Detect using cups-config CUPSCONFIG = 'cups-config' + # Detect using libwmf-config + LIBWMFCONFIG = 'libwmf-config' # This is only supported on OSX - search the frameworks directory by name. EXTRAFRAMEWORK = 'extraframework' # Detect using the sysconfig module. diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py index 562a341..e65675b 100644 --- a/mesonbuild/dependencies/misc.py +++ b/mesonbuild/dependencies/misc.py @@ -359,11 +359,12 @@ class BoostDependency(ExternalDependency): args.append('-L' + self.libdir) for lib in self.requested_modules: # The compiler's library detector is the most reliable so use that first. - default_detect = self.compiler.find_library('boost_' + lib, self.env, []) + boost_lib = 'boost_' + lib + default_detect = self.compiler.find_library(boost_lib, self.env, []) if default_detect is not None: args += default_detect - elif lib in self.lib_modules: - linkcmd = '-l' + lib + elif boost_lib in self.lib_modules: + linkcmd = '-l' + boost_lib args.append(linkcmd) return args @@ -760,6 +761,44 @@ class CupsDependency(ExternalDependency): else: return [DependencyMethods.PKGCONFIG, DependencyMethods.CUPSCONFIG] + +class LibWmfDependency(ExternalDependency): + def __init__(self, environment, kwargs): + super().__init__('libwmf', environment, None, kwargs) + if DependencyMethods.PKGCONFIG in self.methods: + try: + kwargs['required'] = False + pcdep = PkgConfigDependency('libwmf', environment, kwargs) + if pcdep.found(): + self.type_name = 'pkgconfig' + self.is_found = True + self.compile_args = pcdep.get_compile_args() + self.link_args = pcdep.get_link_args() + self.version = pcdep.get_version() + return + except Exception as e: + mlog.debug('LibWmf not found via pkgconfig. Trying next, error was:', str(e)) + if DependencyMethods.LIBWMFCONFIG in self.methods: + libwmfconf = shutil.which('libwmf-config') + if libwmfconf: + stdo = Popen_safe(['libwmf-config', '--cflags'])[1] + self.compile_args = stdo.strip().split() + stdo = Popen_safe(['libwmf-config', '--libs'])[1] + self.link_args = stdo.strip().split() + stdo = Popen_safe(['libwmf-config', '--version'])[1] + self.version = stdo.strip() + self.is_found = True + mlog.log('Dependency', mlog.bold('libwmf'), 'found:', + mlog.green('YES'), '(%s)' % libwmfconf) + return + mlog.debug('Could not find libwmf-config binary, trying next.') + + def get_methods(self): + if mesonlib.is_osx(): + return [DependencyMethods.PKGCONFIG, DependencyMethods.LIBWMFCONFIG, DependencyMethods.EXTRAFRAMEWORK] + else: + return [DependencyMethods.PKGCONFIG, DependencyMethods.LIBWMFCONFIG] + # Generated with boost_names.py BOOST_LIBS = [ 'boost_atomic', @@ -815,6 +854,10 @@ BOOST_LIBS = [ 'boost_math_c99l', 'boost_mpi', 'boost_program_options', + 'boost_python', + 'boost_python3', + 'boost_numpy', + 'boost_numpy3', 'boost_random', 'boost_regex', 'boost_serialization', diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index a746cab..7f07c8d 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -349,10 +349,9 @@ class Environment: def is_cross_build(self): return self.cross_info is not None - def dump_coredata(self, mtime): + def dump_coredata(self): cdf = os.path.join(self.get_build_dir(), Environment.coredata_file) coredata.save(self.coredata, cdf) - os.utime(cdf, times=(mtime, mtime)) return cdf def get_script_dir(self): diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index d9ab733..28cb5ad 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -606,9 +606,9 @@ class CustomTargetHolder(TargetHolder): raise InterpreterException('Cannot delete a member of a CustomTarget') class RunTargetHolder(InterpreterObject, ObjectHolder): - def __init__(self, name, command, args, dependencies, subdir): + def __init__(self, name, command, args, dependencies, subdir, subproject): InterpreterObject.__init__(self) - ObjectHolder.__init__(self, build.RunTarget(name, command, args, dependencies, subdir)) + ObjectHolder.__init__(self, build.RunTarget(name, command, args, dependencies, subdir, subproject)) def __repr__(self): r = '<{} {}: {}>' @@ -1060,10 +1060,10 @@ class CompilerHolder(InterpreterObject): return [] ModuleState = namedtuple('ModuleState', [ - 'build_to_src', 'subdir', 'current_lineno', 'environment', 'project_name', - 'project_version', 'backend', 'compilers', 'targets', 'data', 'headers', - 'man', 'global_args', 'project_args', 'build_machine', 'host_machine', - 'target_machine']) + 'build_to_src', 'subproject', 'subdir', 'current_lineno', 'environment', + 'project_name', 'project_version', 'backend', 'compilers', 'targets', + 'data', 'headers', 'man', 'global_args', 'project_args', 'build_machine', + 'host_machine', 'target_machine']) class ModuleHolder(InterpreterObject, ObjectHolder): def __init__(self, modname, module, interpreter): @@ -1085,6 +1085,7 @@ class ModuleHolder(InterpreterObject, ObjectHolder): state = ModuleState( build_to_src=os.path.relpath(self.interpreter.environment.get_source_dir(), self.interpreter.environment.get_build_dir()), + subproject=self.interpreter.subproject, subdir=self.interpreter.subdir, current_lineno=self.interpreter.current_lineno, environment=self.interpreter.environment, @@ -1442,6 +1443,7 @@ class Interpreter(InterpreterBase): 'join_paths': self.func_join_paths, 'library': self.func_library, 'message': self.func_message, + 'warning': self.func_warning, 'option': self.func_option, 'project': self.func_project, 'run_target': self.func_run_target, @@ -1579,6 +1581,10 @@ class Interpreter(InterpreterBase): if not isinstance(d, (dependencies.Dependency, dependencies.ExternalLibrary, dependencies.InternalDependency)): raise InterpreterException('Dependencies must be external deps') final_deps.append(d) + for l in libs: + if isinstance(l, dependencies.Dependency): + raise InterpreterException('''Entries in "link_with" may only be self-built targets, +external dependencies (including libraries) must go to "dependencies".''') dep = dependencies.InternalDependency(version, incs, compile_args, link_args, libs, sources, final_deps) return DependencyHolder(dep) @@ -1634,6 +1640,9 @@ class Interpreter(InterpreterBase): raise InterpreterException('Program or command {!r} not found' 'or not executable'.format(cmd)) cmd = prog + cmd_path = os.path.relpath(cmd.get_path(), start=srcdir) + if not cmd_path.startswith('..') and cmd_path not in self.build_def_files: + self.build_def_files.append(cmd_path) expanded_args = [] for a in listify(cargs): if isinstance(a, str): @@ -1644,6 +1653,14 @@ class Interpreter(InterpreterBase): expanded_args.append(a.held_object.get_path()) else: raise InterpreterException('Arguments ' + m.format(a)) + for a in expanded_args: + if not os.path.isabs(a): + a = os.path.join(builddir if in_builddir else srcdir, self.subdir, a) + if os.path.exists(a): + a = os.path.relpath(a, start=srcdir) + if not a.startswith('..'): + if a not in self.build_def_files: + self.build_def_files.append(a) return RunProcess(cmd, expanded_args, srcdir, builddir, self.subdir, self.environment.get_build_command() + ['introspect'], in_builddir) @@ -1853,8 +1870,7 @@ to directly access options of other subprojects.''') def func_add_languages(self, node, args, kwargs): return self.add_languages(args, kwargs.get('required', True)) - @noKwargs - def func_message(self, node, args, kwargs): + def get_message_string_arg(self, node): # reduce arguments again to avoid flattening posargs (posargs, _) = self.reduce_arguments(node.args) if len(posargs) != 1: @@ -1870,9 +1886,19 @@ to directly access options of other subprojects.''') else: raise InvalidArguments('Function accepts only strings, integers, lists and lists thereof.') + return argstr + + @noKwargs + def func_message(self, node, args, kwargs): + argstr = self.get_message_string_arg(node) mlog.log(mlog.bold('Message:'), argstr) @noKwargs + def func_warning(self, node, args, kwargs): + argstr = self.get_message_string_arg(node) + mlog.warning(argstr) + + @noKwargs def func_error(self, node, args, kwargs): self.validate_arguments(args, 1, [str]) raise InterpreterException('Error encountered: ' + args[0]) @@ -2288,7 +2314,7 @@ to directly access options of other subprojects.''') if len(args) != 1: raise InterpreterException('custom_target: Only one positional argument is allowed, and it must be a string name') name = args[0] - tg = CustomTargetHolder(build.CustomTarget(name, self.subdir, kwargs), self) + tg = CustomTargetHolder(build.CustomTarget(name, self.subdir, self.subproject, kwargs), self) self.add_target(name, tg.held_object) return tg @@ -2331,7 +2357,7 @@ to directly access options of other subprojects.''') cleaned_deps.append(d) command = cleaned_args[0] cmd_args = cleaned_args[1:] - tg = RunTargetHolder(name, command, cmd_args, cleaned_deps, self.subdir) + tg = RunTargetHolder(name, command, cmd_args, cleaned_deps, self.subdir, self.subproject) self.add_target(name, tg.held_object) return tg @@ -2795,6 +2821,16 @@ different subdirectory. super().run() mlog.log('Build targets in project:', mlog.bold(str(len(self.build.targets)))) + def evaluate_subproject_info(self, path_from_source_root, subproject_dirname): + depth = 0 + subproj_name = '' + segs = path_from_source_root.split(os.path.sep) + while segs and segs[0] == subproject_dirname: + depth += 1 + subproj_name = segs[1] + segs = segs[2:] + return (depth, subproj_name) + # Check that the indicated file is within the same subproject # as we currently are. This is to stop people doing # nasty things like: @@ -2816,17 +2852,16 @@ different subdirectory. return norm = os.path.relpath(norm, self.environment.source_dir) assert(not os.path.isabs(norm)) - segments = norm.split(os.path.sep) - num_sps = segments.count(self.subproject_dir) + (num_sps, sproj_name) = self.evaluate_subproject_info(norm, self.subproject_dir) + plain_filename = os.path.split(norm)[-1] if num_sps == 0: if self.subproject == '': return - raise InterpreterException('Sandbox violation: Tried to grab file %s from a different subproject.' % segments[-1]) + raise InterpreterException('Sandbox violation: Tried to grab file %s from a different subproject.' % plain_filename) if num_sps > 1: - raise InterpreterException('Sandbox violation: Tried to grab file %s from a nested subproject.' % segments[-1]) - sproj_name = segments[segments.index(self.subproject_dir) + 1] + raise InterpreterException('Sandbox violation: Tried to grab file %s from a nested subproject.' % plain_filename) if sproj_name != self.subproject_directory_name: - raise InterpreterException('Sandbox violation: Tried to grab file %s from a different subproject.' % segments[-1]) + raise InterpreterException('Sandbox violation: Tried to grab file %s from a different subproject.' % plain_filename) def source_strings_to_files(self, sources): results = [] diff --git a/mesonbuild/mesonmain.py b/mesonbuild/mesonmain.py index 45e6026..8ecfacd 100644 --- a/mesonbuild/mesonmain.py +++ b/mesonbuild/mesonmain.py @@ -193,23 +193,19 @@ class MesonApp: mlog.log('Build machine cpu family:', mlog.bold(intr.builtin['build_machine'].cpu_family_method([], {}))) mlog.log('Build machine cpu:', mlog.bold(intr.builtin['build_machine'].cpu_method([], {}))) intr.run() - coredata_mtime = time.time() - g.generate(intr) - dumpfile = os.path.join(env.get_scratch_dir(), 'build.dat') - with open(dumpfile, 'wb') as f: - pickle.dump(b, f) - # Write this as late as possible since we use the existence of this - # file to check if we generated the build file successfully, so we - # don't want an error that pops up during generation, etc to cause us to - # incorrectly signal a successful meson run which will cause an error - # about an already-configured build directory when the user tries again. - # - # However, we set the mtime to an earlier value to ensure that doing an - # mtime comparison between the coredata dump and other build files - # shows the build files to be newer, not older. - cdf = env.dump_coredata(coredata_mtime) - # Post-conf scripts must be run after writing coredata or else introspection fails. try: + # We would like to write coredata as late as possible since we use the existence of + # this file to check if we generated the build file successfully. Since coredata + # includes settings, the build files must depend on it and appear newer. However, due + # to various kernel caches, we cannot guarantee that any time in Python is exactly in + # sync with the time that gets applied to any files. Thus, we dump this file as late as + # possible, but before build files, and if any error occurs, delete it. + cdf = env.dump_coredata() + g.generate(intr) + dumpfile = os.path.join(env.get_scratch_dir(), 'build.dat') + with open(dumpfile, 'wb') as f: + pickle.dump(b, f) + # Post-conf scripts must be run after writing coredata or else introspection fails. g.run_postconf_scripts() except: os.unlink(cdf) diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py index 364bc45..bf513fd 100644 --- a/mesonbuild/modules/__init__.py +++ b/mesonbuild/modules/__init__.py @@ -78,21 +78,21 @@ class ModuleReturnValue: self.new_objects = new_objects class GResourceTarget(build.CustomTarget): - def __init__(self, name, subdir, kwargs): - super().__init__(name, subdir, kwargs) + def __init__(self, name, subdir, subproject, kwargs): + super().__init__(name, subdir, subproject, kwargs) class GResourceHeaderTarget(build.CustomTarget): - def __init__(self, name, subdir, kwargs): - super().__init__(name, subdir, kwargs) + def __init__(self, name, subdir, subproject, kwargs): + super().__init__(name, subdir, subproject, kwargs) class GirTarget(build.CustomTarget): - def __init__(self, name, subdir, kwargs): - super().__init__(name, subdir, kwargs) + def __init__(self, name, subdir, subproject, kwargs): + super().__init__(name, subdir, subproject, kwargs) class TypelibTarget(build.CustomTarget): - def __init__(self, name, subdir, kwargs): - super().__init__(name, subdir, kwargs) + def __init__(self, name, subdir, subproject, kwargs): + super().__init__(name, subdir, subproject, kwargs) class VapiTarget(build.CustomTarget): - def __init__(self, name, subdir, kwargs): - super().__init__(name, subdir, kwargs) + def __init__(self, name, subdir, subproject, kwargs): + super().__init__(name, subdir, subproject, kwargs) diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index 31b24c8..4d20cc1 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -192,7 +192,7 @@ class GnomeModule(ExtensionModule): depfile = kwargs['output'] + '.d' kwargs['depfile'] = depfile kwargs['command'] = copy.copy(cmd) + ['--dependency-file', '@DEPFILE@'] - target_c = GResourceTarget(name, state.subdir, kwargs) + target_c = GResourceTarget(name, state.subdir, state.subproject, kwargs) if gresource: # Only one target for .gresource files return ModuleReturnValue(target_c, [target_c]) @@ -210,7 +210,7 @@ class GnomeModule(ExtensionModule): h_kwargs['install'] = install_header h_kwargs['install_dir'] = kwargs.get('install_dir', state.environment.coredata.get_builtin_option('includedir')) - target_h = GResourceHeaderTarget(args[0] + '_h', state.subdir, h_kwargs) + target_h = GResourceHeaderTarget(args[0] + '_h', state.subdir, state.subproject, h_kwargs) rv = [target_c, target_h] return ModuleReturnValue(rv, rv) @@ -612,7 +612,7 @@ class GnomeModule(ExtensionModule): os.path.join(state.environment.get_datadir(), 'gir-1.0')) if 'build_by_default' in kwargs: scankwargs['build_by_default'] = kwargs['build_by_default'] - scan_target = GirTarget(girfile, state.subdir, scankwargs) + scan_target = GirTarget(girfile, state.subdir, state.subproject, scankwargs) typelib_output = '%s-%s.typelib' % (ns, nsversion) typelib_cmd = [gicompiler, scan_target, '--output', '@OUTPUT@'] @@ -630,7 +630,7 @@ class GnomeModule(ExtensionModule): os.path.join(state.environment.get_libdir(), 'girepository-1.0')) if 'build_by_default' in kwargs: typelib_kwargs['build_by_default'] = kwargs['build_by_default'] - typelib_target = TypelibTarget(typelib_output, state.subdir, typelib_kwargs) + typelib_target = TypelibTarget(typelib_output, state.subdir, state.subproject, typelib_kwargs) rv = [scan_target, typelib_target] return ModuleReturnValue(rv, rv) @@ -649,8 +649,8 @@ class GnomeModule(ExtensionModule): if state.subdir == '': targetname = 'gsettings-compile' else: - targetname = 'gsettings-compile-' + state.subdir - target_g = build.CustomTarget(targetname, state.subdir, kwargs) + targetname = 'gsettings-compile-' + state.subdir.replace('/', '_') + target_g = build.CustomTarget(targetname, state.subdir, state.subproject, kwargs) return ModuleReturnValue(target_g, [target_g]) @permittedKwargs({'sources', 'media', 'symlink_media', 'languages'}) @@ -705,7 +705,7 @@ This will become a hard error in the future.''') '--sources=' + source_str, ] pottarget = build.RunTarget('help-' + project_id + '-pot', potargs[0], - potargs[1:], [], state.subdir) + potargs[1:], [], state.subdir, state.subproject) poargs = state.environment.get_build_command() + [ '--internal', 'yelphelper', 'update-po', @@ -715,7 +715,7 @@ This will become a hard error in the future.''') '--langs=' + '@@'.join(langs), ] potarget = build.RunTarget('help-' + project_id + '-update-po', poargs[0], - poargs[1:], [], state.subdir) + poargs[1:], [], state.subdir, state.subproject) rv = [inscript, pottarget, potarget] return ModuleReturnValue(None, rv) @@ -788,7 +788,7 @@ This will become a hard error in the future.''') args += self._unpack_args('--ignore-headers=', 'ignore_headers', kwargs) args += self._unpack_args('--installdir=', 'install_dir', kwargs, state) args += self._get_build_args(kwargs, state) - res = [build.RunTarget(targetname, command[0], command[1:] + args, [], state.subdir)] + res = [build.RunTarget(targetname, command[0], command[1:] + args, [], state.subdir, state.subproject)] if kwargs.get('install', True): res.append(build.RunScript(command, args)) return ModuleReturnValue(None, res) @@ -885,7 +885,7 @@ This will become a hard error in the future.''') } if 'build_by_default' in kwargs: custom_kwargs['build_by_default'] = kwargs['build_by_default'] - ct = build.CustomTarget(target_name, state.subdir, custom_kwargs) + ct = build.CustomTarget(target_name, state.subdir, state.subproject, custom_kwargs) return ModuleReturnValue(ct, [ct]) @permittedKwargs({'sources', 'c_template', 'h_template', 'install_header', 'install_dir', @@ -1101,7 +1101,7 @@ G_END_DECLS''' 'command': cmd } custom_kwargs.update(kwargs) - return build.CustomTarget(output, state.subdir, custom_kwargs, + return build.CustomTarget(output, state.subdir, state.subproject, custom_kwargs, # https://github.com/mesonbuild/meson/issues/973 absolute_paths=True) @@ -1171,7 +1171,7 @@ G_END_DECLS''' # Silence any warnings about missing prototypes custom_kwargs['command'] += ['--include-header', header_file] custom_kwargs['output'] = output + '.c' - body = build.CustomTarget(output + '_c', state.subdir, custom_kwargs) + body = build.CustomTarget(output + '_c', state.subdir, state.subproject, custom_kwargs) custom_kwargs['install'] = install_header if install_dir is not None: @@ -1180,7 +1180,7 @@ G_END_DECLS''' cmd += ['--pragma-once'] custom_kwargs['command'] = cmd + ['--header', '@INPUT@'] custom_kwargs['output'] = header_file - header = build.CustomTarget(output + '_h', state.subdir, custom_kwargs) + header = build.CustomTarget(output + '_h', state.subdir, state.subproject, custom_kwargs) rv = [body, header] return ModuleReturnValue(rv, rv) @@ -1316,7 +1316,7 @@ G_END_DECLS''' # We shouldn't need this locally but we install it deps_target = self._generate_deps(state, library, vapi_packages, install_dir) created_values.append(deps_target) - vapi_target = VapiTarget(vapi_output, state.subdir, custom_kwargs) + vapi_target = VapiTarget(vapi_output, state.subdir, state.subproject, custom_kwargs) # So to try our best to get this to just work we need: # - link with with the correct library diff --git a/mesonbuild/modules/i18n.py b/mesonbuild/modules/i18n.py index c1dd837..6c02fbb 100644 --- a/mesonbuild/modules/i18n.py +++ b/mesonbuild/modules/i18n.py @@ -79,7 +79,7 @@ class I18nModule(ExtensionModule): command.append(datadirs) kwargs['command'] = command - ct = build.CustomTarget(kwargs['output'] + '_merge', state.subdir, kwargs) + ct = build.CustomTarget(kwargs['output'] + '_merge', state.subdir, state.subproject, kwargs) return ModuleReturnValue(ct, [ct]) @permittedKwargs({'po_dir', 'data_dirs', 'type', 'languages', 'args', 'preset', 'install'}) @@ -111,12 +111,12 @@ class I18nModule(ExtensionModule): potargs.append(datadirs) if extra_args: potargs.append(extra_args) - pottarget = build.RunTarget(packagename + '-pot', potargs[0], potargs[1:], [], state.subdir) + pottarget = build.RunTarget(packagename + '-pot', potargs[0], potargs[1:], [], state.subdir, state.subproject) gmoargs = state.environment.get_build_command() + ['--internal', 'gettext', 'gen_gmo'] if lang_arg: gmoargs.append(lang_arg) - gmotarget = build.RunTarget(packagename + '-gmo', gmoargs[0], gmoargs[1:], [], state.subdir) + gmotarget = build.RunTarget(packagename + '-gmo', gmoargs[0], gmoargs[1:], [], state.subdir, state.subproject) updatepoargs = state.environment.get_build_command() + ['--internal', 'gettext', 'update_po', pkg_arg] if lang_arg: @@ -125,7 +125,7 @@ class I18nModule(ExtensionModule): updatepoargs.append(datadirs) if extra_args: updatepoargs.append(extra_args) - updatepotarget = build.RunTarget(packagename + '-update-po', updatepoargs[0], updatepoargs[1:], [], state.subdir) + updatepotarget = build.RunTarget(packagename + '-update-po', updatepoargs[0], updatepoargs[1:], [], state.subdir, state.subproject) targets = [pottarget, gmotarget, updatepotarget] diff --git a/mesonbuild/modules/qt.py b/mesonbuild/modules/qt.py index 2f24740..5800e5c 100644 --- a/mesonbuild/modules/qt.py +++ b/mesonbuild/modules/qt.py @@ -84,10 +84,10 @@ class QtBaseModule: except Exception: return [] - @permittedKwargs({'moc_headers', 'moc_sources', 'include_directories', 'ui_files', 'qresources', 'method'}) + @permittedKwargs({'moc_headers', 'moc_sources', 'moc_extra_arguments', 'include_directories', 'ui_files', 'qresources', 'method'}) def preprocess(self, state, args, kwargs): - rcc_files, ui_files, moc_headers, moc_sources, sources, include_directories \ - = extract_as_list(kwargs, 'qresources', 'ui_files', 'moc_headers', 'moc_sources', 'sources', 'include_directories', pop = True) + rcc_files, ui_files, moc_headers, moc_sources, moc_extra_arguments, sources, include_directories \ + = extract_as_list(kwargs, 'qresources', 'ui_files', 'moc_headers', 'moc_sources', 'moc_extra_arguments', 'sources', 'include_directories', pop = True) sources += args[1:] method = kwargs.get('method', 'auto') self._detect_tools(state.environment, method) @@ -110,7 +110,7 @@ class QtBaseModule: 'output': name + '.cpp', 'command': [self.rcc, '-o', '@OUTPUT@', '@INPUT@'], 'depend_files': qrc_deps} - res_target = build.CustomTarget(name, state.subdir, rcc_kwargs) + res_target = build.CustomTarget(name, state.subdir, state.subproject, rcc_kwargs) sources.append(res_target) if len(ui_files) > 0: if not self.uic.found(): @@ -122,14 +122,16 @@ class QtBaseModule: sources.append(ui_output) inc = get_include_args(include_dirs=include_directories) if len(moc_headers) > 0: + arguments = moc_extra_arguments + inc + ['@INPUT@', '-o', '@OUTPUT@'] moc_kwargs = {'output': 'moc_@BASENAME@.cpp', - 'arguments': inc + ['@INPUT@', '-o', '@OUTPUT@']} + 'arguments': arguments} moc_gen = build.Generator([self.moc], moc_kwargs) moc_output = moc_gen.process_files('Qt{} moc header'.format(self.qt_version), moc_headers, state) sources.append(moc_output) if len(moc_sources) > 0: + arguments = moc_extra_arguments + ['@INPUT@', '-o', '@OUTPUT@'] moc_kwargs = {'output': '@BASENAME@.moc', - 'arguments': ['@INPUT@', '-o', '@OUTPUT@']} + 'arguments': arguments} moc_gen = build.Generator([self.moc], moc_kwargs) moc_output = moc_gen.process_files('Qt{} moc source'.format(self.qt_version), moc_sources, state) sources.append(moc_output) diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py index 4e049a8..cba9fc3 100644 --- a/mesonbuild/mtest.py +++ b/mesonbuild/mtest.py @@ -619,6 +619,6 @@ def run(args): return th.doit() return th.run_special() except TestException as e: - print('Mesontest encountered an error:\n') + print('Meson test encountered an error:\n') print(e) return 1 diff --git a/mesonbuild/optinterpreter.py b/mesonbuild/optinterpreter.py index 4b8e147..01dd036 100644 --- a/mesonbuild/optinterpreter.py +++ b/mesonbuild/optinterpreter.py @@ -180,5 +180,5 @@ class OptionInterpreter: if opt.description == '': opt.description = opt_name if opt_name in self.cmd_line_options: - opt.set_value(opt.parse_string(self.cmd_line_options[opt_name])) + opt.set_value(self.cmd_line_options[opt_name]) self.options[opt_name] = opt diff --git a/mesonbuild/scripts/gtkdochelper.py b/mesonbuild/scripts/gtkdochelper.py index 45ed96b..4406b28 100644 --- a/mesonbuild/scripts/gtkdochelper.py +++ b/mesonbuild/scripts/gtkdochelper.py @@ -112,7 +112,8 @@ def build_gtkdoc(source_root, build_root, doc_subdir, src_subdirs, scanobjs_cmd = ['gtkdoc-scangobj'] + scanobjs_args + ['--types=' + gobject_typesfile, '--module=' + module, '--cflags=' + cflags, - '--ldflags=' + ldflags] + '--ldflags=' + ldflags, + '--ld=' + ld] gtkdoc_run_check(scanobjs_cmd, abs_out) diff --git a/run_tests.py b/run_tests.py index 00c97ca..79c9639 100755 --- a/run_tests.py +++ b/run_tests.py @@ -125,7 +125,7 @@ def get_fake_options(prefix): return opts def should_run_linux_cross_tests(): - return shutil.which('arm-linux-gnueabihf-gcc-6') and not platform.machine().lower().startswith('arm') + return shutil.which('arm-linux-gnueabihf-gcc-7') and not platform.machine().lower().startswith('arm') def run_configure_inprocess(commandlist): old_stdout = sys.stdout diff --git a/syntax-highlighting/vim/indent/meson.vim b/syntax-highlighting/vim/indent/meson.vim index b00c942..8553ec0 100644 --- a/syntax-highlighting/vim/indent/meson.vim +++ b/syntax-highlighting/vim/indent/meson.vim @@ -78,7 +78,7 @@ function GetMesonIndent(lnum) " When inside parenthesis: If at the first line below the parenthesis add - " two 'shiftwidth', otherwise same as previous line. + " a 'shiftwidth', otherwise same as previous line. " i = (a " + b " + c) @@ -97,7 +97,7 @@ function GetMesonIndent(lnum) if pp > 0 return indent(plnum) + (exists("g:pyindent_nested_paren") ? eval(g:pyindent_nested_paren) : shiftwidth()) endif - return indent(plnum) + (exists("g:pyindent_open_paren") ? eval(g:pyindent_open_paren) : (shiftwidth() * 2)) + return indent(plnum) + (exists("g:pyindent_open_paren") ? eval(g:pyindent_open_paren) : shiftwidth()) endif if plnumstart == p return indent(plnum) diff --git a/test cases/common/162 wrap file should not failed/meson.build b/test cases/common/162 wrap file should not failed/meson.build index 64d8d1f..9cf4e9a 100644 --- a/test cases/common/162 wrap file should not failed/meson.build +++ b/test cases/common/162 wrap file should not failed/meson.build @@ -1,3 +1,7 @@ project('mainproj', 'c') subproject('zlib') + +executable('grabprog', files('src/subprojects/prog.c')) +executable('grabprog2', files('src/subprojects/foo/prog2.c')) +subdir('src') diff --git a/test cases/common/162 wrap file should not failed/src/meson.build b/test cases/common/162 wrap file should not failed/src/meson.build new file mode 100644 index 0000000..69f666d --- /dev/null +++ b/test cases/common/162 wrap file should not failed/src/meson.build @@ -0,0 +1,2 @@ +executable('grabprog3', files('subprojects/prog.c')) +executable('grabprog4', files('subprojects/foo/prog2.c')) diff --git a/test cases/common/162 wrap file should not failed/src/subprojects/foo/prog2.c b/test cases/common/162 wrap file should not failed/src/subprojects/foo/prog2.c new file mode 100644 index 0000000..56f61a8 --- /dev/null +++ b/test cases/common/162 wrap file should not failed/src/subprojects/foo/prog2.c @@ -0,0 +1,7 @@ +#include<stdio.h> + +int main(int argc, char **argv) { + printf("Do not have a file layout like this in your own projects.\n"); + printf("This is only to test that this works.\n"); + return 0; +} diff --git a/test cases/common/162 wrap file should not failed/src/subprojects/prog.c b/test cases/common/162 wrap file should not failed/src/subprojects/prog.c new file mode 100644 index 0000000..56f61a8 --- /dev/null +++ b/test cases/common/162 wrap file should not failed/src/subprojects/prog.c @@ -0,0 +1,7 @@ +#include<stdio.h> + +int main(int argc, char **argv) { + printf("Do not have a file layout like this in your own projects.\n"); + printf("This is only to test that this works.\n"); + return 0; +} diff --git a/test cases/common/162 wrap file should not failed/subprojects/zlib-1.2.8/foo.c b/test cases/common/162 wrap file should not failed/subprojects/zlib-1.2.8/foo.c index e69de29..019f2ba 100644 --- a/test cases/common/162 wrap file should not failed/subprojects/zlib-1.2.8/foo.c +++ b/test cases/common/162 wrap file should not failed/subprojects/zlib-1.2.8/foo.c @@ -0,0 +1,3 @@ +int dummy_func() { + return 42; +} diff --git a/test cases/common/163 subproject dir name collision/a.c b/test cases/common/163 subproject dir name collision/a.c new file mode 100644 index 0000000..6ed96fa --- /dev/null +++ b/test cases/common/163 subproject dir name collision/a.c @@ -0,0 +1,13 @@ +#include<assert.h> +char func_b(); +char func_c(); + +int main(int argc, char **argv) { + if(func_b() != 'b') { + return 1; + } + if(func_c() != 'c') { + return 2; + } + return 0; +} diff --git a/test cases/common/163 subproject dir name collision/custom_subproject_dir/B/b.c b/test cases/common/163 subproject dir name collision/custom_subproject_dir/B/b.c new file mode 100644 index 0000000..4c94ee9 --- /dev/null +++ b/test cases/common/163 subproject dir name collision/custom_subproject_dir/B/b.c @@ -0,0 +1,20 @@ +#include<stdlib.h> +char func_c(); + +#if defined _WIN32 || defined __CYGWIN__ +#define DLL_PUBLIC __declspec(dllexport) +#else + #if defined __GNUC__ + #define DLL_PUBLIC __attribute__ ((visibility("default"))) + #else + #pragma message ("Compiler does not support symbol visibility.") + #define DLL_PUBLIC + #endif +#endif + +char DLL_PUBLIC func_b() { + if(func_c() != 'c') { + exit(3); + } + return 'b'; +} diff --git a/test cases/common/163 subproject dir name collision/custom_subproject_dir/B/meson.build b/test cases/common/163 subproject dir name collision/custom_subproject_dir/B/meson.build new file mode 100644 index 0000000..280c60c --- /dev/null +++ b/test cases/common/163 subproject dir name collision/custom_subproject_dir/B/meson.build @@ -0,0 +1,4 @@ +project('B', 'c') +C = subproject('C') +c = C.get_variable('c') +b = shared_library('b', 'b.c', link_with : c) diff --git a/test cases/common/163 subproject dir name collision/custom_subproject_dir/C/c.c b/test cases/common/163 subproject dir name collision/custom_subproject_dir/C/c.c new file mode 100644 index 0000000..eebfb9f --- /dev/null +++ b/test cases/common/163 subproject dir name collision/custom_subproject_dir/C/c.c @@ -0,0 +1,14 @@ +#if defined _WIN32 || defined __CYGWIN__ +#define DLL_PUBLIC __declspec(dllexport) +#else + #if defined __GNUC__ + #define DLL_PUBLIC __attribute__ ((visibility("default"))) + #else + #pragma message ("Compiler does not support symbol visibility.") + #define DLL_PUBLIC + #endif +#endif + +char DLL_PUBLIC func_c() { + return 'c'; +} diff --git a/test cases/common/163 subproject dir name collision/custom_subproject_dir/C/meson.build b/test cases/common/163 subproject dir name collision/custom_subproject_dir/C/meson.build new file mode 100644 index 0000000..abf0b1e --- /dev/null +++ b/test cases/common/163 subproject dir name collision/custom_subproject_dir/C/meson.build @@ -0,0 +1,2 @@ +project('C', 'c') +c = shared_library('c', 'c.c') diff --git a/test cases/common/163 subproject dir name collision/meson.build b/test cases/common/163 subproject dir name collision/meson.build new file mode 100644 index 0000000..5531217 --- /dev/null +++ b/test cases/common/163 subproject dir name collision/meson.build @@ -0,0 +1,12 @@ +project('A', 'c', subproject_dir:'custom_subproject_dir') + +B = subproject('B') +b = B.get_variable('b') + +C = subproject('C') +c = C.get_variable('c') + +subdir('other_subdir') + +a = executable('a', 'a.c', link_with : [b, c]) +test('a test', a) diff --git a/test cases/common/163 subproject dir name collision/other_subdir/custom_subproject_dir/other.c b/test cases/common/163 subproject dir name collision/other_subdir/custom_subproject_dir/other.c new file mode 100644 index 0000000..0c27f84 --- /dev/null +++ b/test cases/common/163 subproject dir name collision/other_subdir/custom_subproject_dir/other.c @@ -0,0 +1,19 @@ +#include<stdlib.h> + +#if defined _WIN32 || defined __CYGWIN__ +#define DLL_PUBLIC __declspec(dllexport) +#else + #if defined __GNUC__ + #define DLL_PUBLIC __attribute__ ((visibility("default"))) + #else + #pragma message ("Compiler does not support symbol visibility.") + #define DLL_PUBLIC + #endif +#endif + +char DLL_PUBLIC func_b() { + if('c' != 'c') { + exit(3); + } + return 'b'; +} diff --git a/test cases/common/163 subproject dir name collision/other_subdir/meson.build b/test cases/common/163 subproject dir name collision/other_subdir/meson.build new file mode 100644 index 0000000..90cb67a --- /dev/null +++ b/test cases/common/163 subproject dir name collision/other_subdir/meson.build @@ -0,0 +1 @@ +other = shared_library('other', 'custom_subproject_dir/other.c') diff --git a/test cases/common/90 identical target name in subproject/meson.build b/test cases/common/90 identical target name in subproject/meson.build index ddb5caf..98e4891 100644 --- a/test cases/common/90 identical target name in subproject/meson.build +++ b/test cases/common/90 identical target name in subproject/meson.build @@ -3,3 +3,4 @@ project('toplevel bar', 'c') subproject('foo') executable('bar', 'bar.c') +run_target('nop', 'true') diff --git a/test cases/common/90 identical target name in subproject/subprojects/foo/meson.build b/test cases/common/90 identical target name in subproject/subprojects/foo/meson.build index 03dd9f3..a7a31b1 100644 --- a/test cases/common/90 identical target name in subproject/subprojects/foo/meson.build +++ b/test cases/common/90 identical target name in subproject/subprojects/foo/meson.build @@ -1,3 +1,4 @@ project('subfoo', 'c') executable('bar', 'bar.c') +run_target('nop', 'true') diff --git a/test cases/d/3 shared library/meson.build b/test cases/d/3 shared library/meson.build index 4ca3137..78ad766 100644 --- a/test cases/d/3 shared library/meson.build +++ b/test cases/d/3 shared library/meson.build @@ -2,8 +2,8 @@ project('D Shared Library', 'd') dc = meson.get_compiler('d') if dc.get_id() == 'gcc' - if dc.version().version_compare('< 7') - error('MESON_SKIP_TEST: GDC < 7.0 can not build shared libraries') + if dc.version().version_compare('< 8') + error('MESON_SKIP_TEST: GDC < 8.0 can not build shared libraries') endif endif diff --git a/test cases/d/4 library versions/meson.build b/test cases/d/4 library versions/meson.build index cba1458..c745b92 100644 --- a/test cases/d/4 library versions/meson.build +++ b/test cases/d/4 library versions/meson.build @@ -2,8 +2,8 @@ project('D library versions', 'd') dc = meson.get_compiler('d') if dc.get_id() == 'gcc' - if dc.version().version_compare('< 7') - error('MESON_SKIP_TEST: GDC < 7.0 can not build shared libraries') + if dc.version().version_compare('< 8') + error('MESON_SKIP_TEST: GDC < 8.0 can not build shared libraries') endif endif diff --git a/test cases/d/7 multilib/meson.build b/test cases/d/7 multilib/meson.build index 1d9a070..1879c08 100644 --- a/test cases/d/7 multilib/meson.build +++ b/test cases/d/7 multilib/meson.build @@ -2,8 +2,8 @@ project('D Multiple Versioned Shared Libraries', 'd') dc = meson.get_compiler('d') if dc.get_id() == 'gcc' - if dc.version().version_compare('< 7') - error('MESON_SKIP_TEST: GDC < 7.0 can not build shared libraries') + if dc.version().version_compare('< 8') + error('MESON_SKIP_TEST: GDC < 8.0 can not build shared libraries') endif endif diff --git a/test cases/failing/63 subproj filegrab/meson.build b/test cases/failing/63 subproj filegrab/meson.build index 6982c78..f38d6c7 100644 --- a/test cases/failing/63 subproj filegrab/meson.build +++ b/test cases/failing/63 subproj filegrab/meson.build @@ -1,3 +1,5 @@ project('mainproj', 'c') +# Try to grab a file from a parent project. + subproject('a') diff --git a/test cases/failing/64 grab subproj/meson.build b/test cases/failing/64 grab subproj/meson.build new file mode 100644 index 0000000..30fc690 --- /dev/null +++ b/test cases/failing/64 grab subproj/meson.build @@ -0,0 +1,7 @@ +project('grabber', 'c') + +# Try to grab a file from a child subproject. + +subproject('foo') + +executable('foo', 'subprojects/foo/sub.c') diff --git a/test cases/failing/64 grab subproj/subprojects/foo/meson.build b/test cases/failing/64 grab subproj/subprojects/foo/meson.build new file mode 100644 index 0000000..b346f6d --- /dev/null +++ b/test cases/failing/64 grab subproj/subprojects/foo/meson.build @@ -0,0 +1,3 @@ +project('foo', 'c') + +message('I do nothing.') diff --git a/test cases/failing/64 grab subproj/subprojects/foo/sub.c b/test cases/failing/64 grab subproj/subprojects/foo/sub.c new file mode 100644 index 0000000..a94b1f5 --- /dev/null +++ b/test cases/failing/64 grab subproj/subprojects/foo/sub.c @@ -0,0 +1,6 @@ +#include<stdio.h> + +int main(int argc, char **argv) { + printf("I am a subproject executable file.\n"); + return 0; +} diff --git a/test cases/failing/65 grab sibling/meson.build b/test cases/failing/65 grab sibling/meson.build new file mode 100644 index 0000000..60b926a --- /dev/null +++ b/test cases/failing/65 grab sibling/meson.build @@ -0,0 +1,3 @@ +project('master', 'c') + +subproject('a') diff --git a/test cases/failing/65 grab sibling/subprojects/a/meson.build b/test cases/failing/65 grab sibling/subprojects/a/meson.build new file mode 100644 index 0000000..6dd9f61 --- /dev/null +++ b/test cases/failing/65 grab sibling/subprojects/a/meson.build @@ -0,0 +1,3 @@ +project('a', 'c') + +executable('sneaky', '../b/sneaky.c') diff --git a/test cases/failing/65 grab sibling/subprojects/b/meson.build b/test cases/failing/65 grab sibling/subprojects/b/meson.build new file mode 100644 index 0000000..7c70fe5 --- /dev/null +++ b/test cases/failing/65 grab sibling/subprojects/b/meson.build @@ -0,0 +1,3 @@ +projecT('b', 'c') + +message('I do nothing.') diff --git a/test cases/failing/65 grab sibling/subprojects/b/sneaky.c b/test cases/failing/65 grab sibling/subprojects/b/sneaky.c new file mode 100644 index 0000000..f1cb916 --- /dev/null +++ b/test cases/failing/65 grab sibling/subprojects/b/sneaky.c @@ -0,0 +1,6 @@ +#include<stdio.h> + +int main(int argc, char **argv) { + printf("I can only come into existance via trickery.\n"); + return 0; +} diff --git a/test cases/failing/66 string as link target/meson.build b/test cases/failing/66 string as link target/meson.build new file mode 100644 index 0000000..cb83fff --- /dev/null +++ b/test cases/failing/66 string as link target/meson.build @@ -0,0 +1,2 @@ +project('string as link argument', 'c') +executable('myprog', 'prog.c', link_with: [ '' ]) diff --git a/test cases/failing/66 string as link target/prog.c b/test cases/failing/66 string as link target/prog.c new file mode 100644 index 0000000..0314ff1 --- /dev/null +++ b/test cases/failing/66 string as link target/prog.c @@ -0,0 +1 @@ +int main(int argc, char **argv) { return 0; } diff --git a/test cases/frameworks/17 mpi/is_artful.py b/test cases/frameworks/17 mpi/is_artful.py new file mode 100755 index 0000000..9d4512d --- /dev/null +++ b/test cases/frameworks/17 mpi/is_artful.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python3 + +# Any exception causes return value to be not zero, which is sufficient. + +import sys + +fc = open('/etc/apt/sources.list').read() +if 'artful' not in fc: + sys.exit(1) diff --git a/test cases/frameworks/17 mpi/meson.build b/test cases/frameworks/17 mpi/meson.build index 5e9bc56..17acd71 100644 --- a/test cases/frameworks/17 mpi/meson.build +++ b/test cases/frameworks/17 mpi/meson.build @@ -23,7 +23,15 @@ if build_machine.system() != 'windows' test('MPI C++', execpp) endif -if add_languages('fortran', required : false) +# OpenMPI is broken with Fortran on Ubuntu Artful. +# Remove this once the following bug has been fixed: +# +# https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1727474 + +ubudetector = find_program('is_artful.py') +uburesult = run_command(ubudetector) + +if uburesult.returncode() != 0 and add_languages('fortran', required : false) mpifort = dependency('mpi', language : 'fortran') exef = executable('exef', 'main.f90', diff --git a/test cases/frameworks/21 libwmf/libwmf_prog.c b/test cases/frameworks/21 libwmf/libwmf_prog.c new file mode 100644 index 0000000..4e6294c --- /dev/null +++ b/test cases/frameworks/21 libwmf/libwmf_prog.c @@ -0,0 +1,8 @@ +#include <libwmf/api.h> + +int +main() +{ + wmf_help(); + return 0; +} diff --git a/test cases/frameworks/21 libwmf/meson.build b/test cases/frameworks/21 libwmf/meson.build new file mode 100644 index 0000000..a7d9263 --- /dev/null +++ b/test cases/frameworks/21 libwmf/meson.build @@ -0,0 +1,9 @@ +project('libwmf test', 'c') + +libwmf_dep = dependency('libwmf', version : '>=3.0') +libwmf_ver = libwmf_dep.version() +assert(libwmf_ver.split('.').length() > 1, 'libwmf version is "@0@"'.format(libwmf_ver)) +message('libwmf version is "@0@"'.format(libwmf_ver)) +e = executable('libwmf_prog', 'libwmf_prog.c', dependencies : libwmf_dep) + +test('libwmftest', e) diff --git a/test cases/frameworks/4 qt/manualinclude.cpp b/test cases/frameworks/4 qt/manualinclude.cpp index 0602882..6c1ac2f 100644 --- a/test cases/frameworks/4 qt/manualinclude.cpp +++ b/test cases/frameworks/4 qt/manualinclude.cpp @@ -6,6 +6,10 @@ ManualInclude::ManualInclude() { } +void ManualInclude::myslot(void) { + ; +} + class MocClass : public QObject { Q_OBJECT }; @@ -13,6 +17,9 @@ class MocClass : public QObject { int main(int argc, char **argv) { ManualInclude mi; MocClass mc; + QObject::connect(&mi, SIGNAL(mysignal(void)), + &mi, SLOT(myslot(void))); + emit mi.mysignal(); return 0; } diff --git a/test cases/frameworks/4 qt/manualinclude.h b/test cases/frameworks/4 qt/manualinclude.h index 4a00b6c..44bb7a7 100644 --- a/test cases/frameworks/4 qt/manualinclude.h +++ b/test cases/frameworks/4 qt/manualinclude.h @@ -8,8 +8,14 @@ class ManualInclude : public QObject { public: ManualInclude(); +#if defined(MOC_EXTRA_FLAG) +public slots: +#endif + void myslot(void); +#if defined(MOC_EXTRA_FLAG) signals: +#endif int mysignal(); }; diff --git a/test cases/frameworks/4 qt/meson.build b/test cases/frameworks/4 qt/meson.build index 39be19f..b817228 100644 --- a/test cases/frameworks/4 qt/meson.build +++ b/test cases/frameworks/4 qt/meson.build @@ -61,6 +61,7 @@ foreach qt : ['qt4', 'qt5'] # headers but the user must manually include moc # files from sources. manpreprocessed = qtmodule.preprocess( + moc_extra_arguments : ['-DMOC_EXTRA_FLAG'], # This is just a random macro to test `moc_extra_arguments` moc_sources : 'manualinclude.cpp', moc_headers : 'manualinclude.h', method : get_option('method')) diff --git a/tools/boost_names.py b/tools/boost_names.py index f9f1f11..d381162 100755 --- a/tools/boost_names.py +++ b/tools/boost_names.py @@ -129,6 +129,9 @@ def get_modules(init=extra): def get_modules_2(): modules = [] + # The python module uses an older build system format and is not easily parseable. + # We add the python module libraries manually. + modules.append(Module('python', 'Python', ['boost_python', 'boost_python3', 'boost_numpy', 'boost_numpy3'])) for (root, dirs, files) in os.walk(LIBS): for f in files: if f == "libraries.json": |