aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml4
-rw-r--r--ciimage/Dockerfile15
-rw-r--r--cross/ubuntu-armhf.txt4
-rw-r--r--data/shell-completions/zsh/_meson213
-rw-r--r--data/syntax-highlighting/emacs/meson.el (renamed from data/meson.el)0
-rw-r--r--data/syntax-highlighting/vim/README (renamed from syntax-highlighting/vim/README)0
-rw-r--r--data/syntax-highlighting/vim/ftdetect/meson.vim (renamed from syntax-highlighting/vim/ftdetect/meson.vim)0
-rw-r--r--data/syntax-highlighting/vim/indent/meson.vim (renamed from syntax-highlighting/vim/indent/meson.vim)4
-rw-r--r--data/syntax-highlighting/vim/syntax/meson.vim (renamed from syntax-highlighting/vim/syntax/meson.vim)0
-rw-r--r--docs/markdown/Dependencies.md63
-rw-r--r--docs/markdown/Qt5-module.md17
-rw-r--r--docs/markdown/Reference-manual.md14
-rw-r--r--docs/markdown/Subprojects.md2
-rw-r--r--docs/markdown/Syntax.md91
-rw-r--r--docs/markdown/Unit-tests.md6
-rw-r--r--docs/markdown/Using-wraptool.md2
-rw-r--r--docs/markdown/Wrap-dependency-system-manual.md4
-rw-r--r--docs/markdown/i18n-module.md4
-rw-r--r--docs/markdown/snippets/llvm-static-linking.md8
-rw-r--r--docs/markdown/snippets/qt5-moc_extra_arguments.md8
-rw-r--r--docs/markdown/snippets/warning_function6
-rw-r--r--man/meson.16
-rw-r--r--mesonbuild/backend/ninjabackend.py13
-rw-r--r--mesonbuild/build.py37
-rw-r--r--mesonbuild/compilers/compilers.py12
-rw-r--r--mesonbuild/coredata.py13
-rw-r--r--mesonbuild/dependencies/__init__.py3
-rw-r--r--mesonbuild/dependencies/base.py2
-rw-r--r--mesonbuild/dependencies/dev.py107
-rw-r--r--mesonbuild/dependencies/misc.py52
-rw-r--r--mesonbuild/environment.py3
-rw-r--r--mesonbuild/interpreter.py73
-rw-r--r--mesonbuild/mconf.py2
-rw-r--r--mesonbuild/mesonmain.py30
-rw-r--r--mesonbuild/mintro.py3
-rw-r--r--mesonbuild/modules/__init__.py20
-rw-r--r--mesonbuild/modules/gnome.py28
-rw-r--r--mesonbuild/modules/i18n.py8
-rw-r--r--mesonbuild/modules/qt.py14
-rw-r--r--mesonbuild/mtest.py4
-rw-r--r--mesonbuild/optinterpreter.py2
-rw-r--r--mesonbuild/rewriter.py2
-rw-r--r--mesonbuild/scripts/gtkdochelper.py3
-rw-r--r--mesonbuild/scripts/meson_install.py30
-rwxr-xr-xrun_tests.py2
-rw-r--r--test cases/common/163 includedir subproj/meson.build9
-rw-r--r--test cases/common/163 includedir subproj/prog.c4
-rw-r--r--test cases/common/163 includedir subproj/subprojects/inctest/include/incfile.h2
-rw-r--r--test cases/common/163 includedir subproj/subprojects/inctest/meson.build13
-rw-r--r--test cases/common/163 subproject dir name collision/a.c13
-rw-r--r--test cases/common/163 subproject dir name collision/custom_subproject_dir/B/b.c20
-rw-r--r--test cases/common/163 subproject dir name collision/custom_subproject_dir/B/meson.build4
-rw-r--r--test cases/common/163 subproject dir name collision/custom_subproject_dir/C/c.c14
-rw-r--r--test cases/common/163 subproject dir name collision/custom_subproject_dir/C/meson.build2
-rw-r--r--test cases/common/163 subproject dir name collision/meson.build12
-rw-r--r--test cases/common/163 subproject dir name collision/other_subdir/custom_subproject_dir/other.c19
-rw-r--r--test cases/common/163 subproject dir name collision/other_subdir/meson.build1
-rw-r--r--test cases/common/90 identical target name in subproject/meson.build1
-rw-r--r--test cases/common/90 identical target name in subproject/subprojects/foo/meson.build1
-rw-r--r--test cases/d/3 shared library/meson.build4
-rw-r--r--test cases/d/4 library versions/meson.build4
-rw-r--r--test cases/d/7 multilib/meson.build4
-rw-r--r--test cases/failing/66 string as link target/meson.build2
-rw-r--r--test cases/failing/66 string as link target/prog.c1
-rw-r--r--test cases/frameworks/15 llvm/meson.build41
-rwxr-xr-xtest cases/frameworks/17 mpi/is_artful.py9
-rw-r--r--test cases/frameworks/17 mpi/meson.build10
-rw-r--r--test cases/frameworks/21 libwmf/libwmf_prog.c8
-rw-r--r--test cases/frameworks/21 libwmf/meson.build9
-rw-r--r--test cases/frameworks/4 qt/manualinclude.cpp7
-rw-r--r--test cases/frameworks/4 qt/manualinclude.h6
-rw-r--r--test cases/frameworks/4 qt/meson.build1
72 files changed, 903 insertions, 252 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/data/shell-completions/zsh/_meson b/data/shell-completions/zsh/_meson
new file mode 100644
index 0000000..877d700
--- /dev/null
+++ b/data/shell-completions/zsh/_meson
@@ -0,0 +1,213 @@
+#compdef meson mesonconf=meson-configure mesontest=meson-test mesonintrospect=meson-introspect
+
+# vim:ts=2 sw=2
+
+# Copyright (c) 2017 Arseny Maslennikov
+# All rights reserved. Individual authors, whether or not
+# specifically named, retain copyright in all changes; in what follows, they
+# are referred to as `the Meson development team'. This is for convenience
+# only and this body has no legal status. This file is distributed under
+# the following licence.
+#
+# Permission is hereby granted, without written agreement and without
+# licence or royalty fees, to use, copy, modify, and distribute this
+# software and to distribute modified versions of this software for any
+# purpose, provided that the above copyright notice and the following
+# two paragraphs appear in all copies of this software.
+#
+# In no event shall the Meson development team be liable to any party for
+# direct, indirect, special, incidental, or consequential damages arising out
+# of the use of this software and its documentation, even if the Meson
+# development team have been advised of the possibility of such damage.
+#
+# The Meson development team specifically disclaim any warranties, including,
+# but not limited to, the implied warranties of merchantability and fitness
+# for a particular purpose. The software provided hereunder is on an "as is"
+# basis, and the Meson development team have no obligation to provide
+# maintenance, support, updates, enhancements, or modifications.
+
+local curcontext="$curcontext" state line
+local -i ret
+
+local __meson_backends="(ninja xcode ${(j. .)${:-vs{,2010,2015,2017}}})"
+local __meson_build_types="(plain debug debugoptimized minsize release)"
+local __meson_wrap_modes="(WrapMode.{default,nofallback,nodownload})"
+
+local -a meson_commands=(
+'setup:set up a build directory'
+'configure:configure a project'
+'test:run tests'
+'introspect:query project properties'
+'wrap:manage source dependencies'
+)
+
+(( $+functions[__meson_is_build_dir] )) || __meson_is_build_dir() {
+ local mpd="${1:-$PWD}/meson-private"
+ [[ -f "$mpd/build.dat" && -f "$mpd/coredata.dat" ]]
+ return $?
+}
+
+# TODO: implement build option completion
+(( $+functions[__meson_build_options] )) || __meson_build_options() {}
+# TODO: implement target name completion
+(( $+functions[__meson_targets] )) || __meson_targets() {}
+# `meson introspect` currently can provide that information in JSON.
+# We can:
+# 1) pipe its output to python3 -m json.tool | grep "$alovelyregex" | cut <...>
+# 2) teach mintro.py to use a different output format
+# (or perhaps just to select the fields printed)
+
+(( $+functions[__meson_test_names] )) || __meson_test_names() {
+ local rtests
+ if rtests="$(_call_program meson meson test ${opt_args[-C]:+-C "$opt_args[-C]"} --list)";
+ then
+ local -a tests=(${(@f)rtests})
+ _describe -t "tests" "Meson tests" tests
+ else
+ _message -r "current working directory is not a build directory"
+ _message -r 'use -C $build_dir or cd $build_dir'
+ fi
+}
+
+(( $+functions[_meson_commands] )) || _meson_commands() {
+ _describe -t commands "Meson subcommands" meson_commands
+}
+
+(( $+functions[_meson-setup] )) || _meson-setup() {
+ local firstd secondd
+ if [[ -f "meson.build" ]]; then
+ # if there's no second argument on the command line
+ # cwd will implicitly be substituted:
+ # - as the source directory if it has a file with the name "meson.build";
+ # - as the build directory otherwise
+ # more info in mesonbuild/mesonmain.py
+ firstd="build"
+ secondd="source"
+ else
+ firstd="source"
+ secondd="build"
+ fi
+
+ _arguments \
+ '*-D-[set the value of a build option]:build option:__meson_build_options' \
+ '--prefix=[installation prefix]: :_directories' \
+ '--libdir=[library directory]: :_directories' \
+ '--libexecdir=[library executable directory]: :_directories' \
+ '--bindir=[executable directory]: :_directories' \
+ '--sbindir=[system executable directory]: :_directories' \
+ '--includedir=[header file directory]: :_directories' \
+ '--datadir=[data file directory]: :_directories' \
+ '--mandir=[manual page directory]: :_directories' \
+ '--infodir=[info page directory]: :_directories' \
+ '--localedir=[locale data directory]: :_directories' \
+ '--sysconfdir=[system configuration directory]: :_directories' \
+ '--localstatedir=[local state data directory]: :_directories' \
+ '--sharedstatedir=[arch-independent data directory]: :_directories' \
+ '--backend=[backend to use]:Meson backend:'"$__meson_backends" \
+ '--buildtype=[build type to use]:Meson build type:'"$__meson_build_types" \
+ '--strip[strip targets on install]' \
+ '--unity=[unity builds on/off]:whether to do unity builds:(on off subprojects)' \
+ '--werror[treat warnings as errors]' \
+ '--layout=[build directory layout]:build directory layout:(flat mirror)' \
+ '--default-library=[default library type]:default library type:(shared static)' \
+ '--warnlevel=[compiler warning level]:compiler warning level:warning level:(1 2 3)' \
+ '--stdsplit=[split stdout and stderr in test logs]' \
+ '--errorlogs=[prints the logs from failing tests]' \
+ '--cross-file=[cross-compilation environment description]:cross file:_files' \
+ '--wrap-mode=[special wrap mode]:wrap mode:'"$__meson_wrap_modes" \
+ ":$firstd directory:_directories" \
+ "::$secondd directory:_directories" \
+ #
+}
+
+(( $+functions[_meson-configure] )) || _meson-configure() {
+ local curcontext="$curcontext"
+ # TODO: implement 'mesonconf @file'
+ local -a specs=(
+ '--clearcache[clear cached state]'
+ '*-D-[set the value of a build option]:build option:__meson_build_options'
+ '::build directory:_directories'
+ )
+
+ _arguments \
+ '(: -)'{'--help','-h'}'[show a help message and quit]' \
+ "${(@)specs}"
+}
+
+(( $+functions[_meson-test] )) || _meson-test() {
+ local curcontext="$curcontext"
+
+ # TODO: complete test suites
+ local -a specs=(
+ '(--quiet -q)'{'--quiet','-q'}'[produce less output to the terminal]'
+ '(--verbose -v)'{'--verbose','-v'}'[do not redirect stdout and stderr]'
+ '(--timeout-multiplier -t)'{'--timeout-multiplier','-t'}'[a multiplier for test timeouts]:Python floating-point number: '
+ '-C[directory to cd into]: :_directories'
+ '--repeat[number of times to run the tests]:number of times to repeat: '
+ '--no-rebuild[do not rebuild before running tests]'
+ '--gdb[run tests under gdb]'
+ '--list[list available tests]'
+ '(--wrapper --wrap)'{'--wrapper=','--wrap='}'[wrapper to run tests with]:wrapper program:_path_commands'
+ '(--no-suite)--suite[only run tests from this suite]:test suite: '
+ '(--suite)--no-suite[do not run tests from this suite]:test suite: '
+ '--no-stdsplit[do not split stderr and stdout in logs]'
+ '--print-errorlogs[print logs for failing tests]'
+ '--benchmark[run benchmarks instead of tests]'
+ '--logbase[base name for log file]:filename: '
+ '--num-processes[how many threads to use]:number of processes: '
+ '--setup[which test setup to use]:test setup: '
+ '--test-args[arguments to pass to the tests]: : '
+ '*:Meson tests:__meson_test_names'
+ )
+
+ _arguments \
+ '(: -)'{'--help','-h'}'[show a help message and quit]' \
+ "${(@)specs}"
+}
+
+(( $+functions[_meson-introspect] )) || _meson-introspect() {
+ local curcontext="$curcontext"
+ local -a specs=(
+ '--targets[list top level targets]'
+ '--installed[list all installed files and directories]'
+ '--target-files[list source files for a given target]:target:__meson_targets'
+ '--buildsystem-files[list files that belong to the build system]'
+ '--buildoptions[list all build options]'
+ '--tests[list all unit tests]'
+ '--benchmarks[list all benchmarks]'
+ '--dependencies[list external dependencies]'
+ '--projectinfo[show project information]'
+ '::build directory:_directories'
+ )
+_arguments \
+ '(: -)'{'--help','-h'}'[show a help message and quit]' \
+ "${(@)specs}"
+}
+
+(( $+functions[_meson-wrap] )) || _meson-wrap() {
+ # TODO
+}
+
+if [[ $service != meson ]]; then
+ _call_function ret _$service
+ return ret
+fi
+
+_arguments -C -R \
+ '(: -)'{'--help','-h'}'[show a help message and quit]' \
+ '(: -)'{'--version','-v'}'[show version information and quit]' \
+ '(-): :_meson_commands' \
+ '*:: :->post-command' \
+#
+ret=$?
+
+[[ $ret = 300 ]] && case "$state" in
+ post-command)
+ service="meson-$words[1]"
+ curcontext=${curcontext%:*:*}:$service:
+ _call_function ret _$service
+ ;;
+esac
+
+return ret
+
diff --git a/data/meson.el b/data/syntax-highlighting/emacs/meson.el
index 36f7eb9..36f7eb9 100644
--- a/data/meson.el
+++ b/data/syntax-highlighting/emacs/meson.el
diff --git a/syntax-highlighting/vim/README b/data/syntax-highlighting/vim/README
index 1afa243..1afa243 100644
--- a/syntax-highlighting/vim/README
+++ b/data/syntax-highlighting/vim/README
diff --git a/syntax-highlighting/vim/ftdetect/meson.vim b/data/syntax-highlighting/vim/ftdetect/meson.vim
index 84db70c..84db70c 100644
--- a/syntax-highlighting/vim/ftdetect/meson.vim
+++ b/data/syntax-highlighting/vim/ftdetect/meson.vim
diff --git a/syntax-highlighting/vim/indent/meson.vim b/data/syntax-highlighting/vim/indent/meson.vim
index b00c942..8553ec0 100644
--- a/syntax-highlighting/vim/indent/meson.vim
+++ b/data/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/syntax-highlighting/vim/syntax/meson.vim b/data/syntax-highlighting/vim/syntax/meson.vim
index 49921c1..49921c1 100644
--- a/syntax-highlighting/vim/syntax/meson.vim
+++ b/data/syntax-highlighting/vim/syntax/meson.vim
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/Syntax.md b/docs/markdown/Syntax.md
index eaf24cf..88b9bbb 100644
--- a/docs/markdown/Syntax.md
+++ b/docs/markdown/Syntax.md
@@ -4,23 +4,39 @@ short-description: Syntax and structure of Meson files
# Syntax
-The syntax of Meson's specification language has been kept as simple as possible. It is *strongly typed* so no object is ever converted to another under the covers. Variables have no visible type which makes Meson *dynamically typed* (also known as *duck typed*).
-
-The main building blocks of the language are *variables*, *numbers*, *booleans*, *strings*, *arrays*, *function calls*, *method calls*, *if statements* and *includes*.
-
-Usually one Meson statement takes just one line. There is no way to have multiple statements on one line as in e.g. *C*. Function and method calls' argument lists can be split over multiple lines. Meson will autodetect this case and do the right thing. In other cases you can get multi-line statements by ending the line with a `\`. Apart from line ending whitespace has no syntactic meaning.
+The syntax of Meson's specification language has been kept as simple
+as possible. It is *strongly typed* so no object is ever converted to
+another under the covers. Variables have no visible type which makes
+Meson *dynamically typed* (also known as *duck typed*).
+
+The main building blocks of the language are *variables*, *numbers*,
+*booleans*, *strings*, *arrays*, *function calls*, *method calls*, *if
+statements* and *includes*.
+
+Usually one Meson statement takes just one line. There is no way to
+have multiple statements on one line as in e.g. *C*. Function and
+method calls' argument lists can be split over multiple lines. Meson
+will autodetect this case and do the right thing. In other cases you
+can get multi-line statements by ending the line with a `\`. Apart
+from line ending whitespace has no syntactic meaning.
Variables
--
-Variables in Meson work just like in other high level programming languages. A variable can contain a value of any type, such as an integer or a string. Variables don't need to be predeclared, you can just assign to them and they appear. Here's how you would assign values to two different variables.
+Variables in Meson work just like in other high level programming
+languages. A variable can contain a value of any type, such as an
+integer or a string. Variables don't need to be predeclared, you can
+just assign to them and they appear. Here's how you would assign
+values to two different variables.
```meson
var1 = 'hello'
var2 = 102
```
-One important difference in how variables work in Meson is that all variables are immutable. This is different from, for example, how Python works.
+One important difference in how variables work in Meson is that all
+objects are immutable. This is different from, for example, how Python
+works.
```meson
var1 = [1, 2, 3]
@@ -33,7 +49,8 @@ var2 += [4]
Numbers
--
-Meson supports only integer numbers. They are declared simply by writing them out. Basic arithmetic operations are supported.
+Meson supports only integer numbers. They are declared simply by
+writing them out. Basic arithmetic operations are supported.
```meson
x = 1 + 2
@@ -60,13 +77,15 @@ truth = true
Strings
--
-Strings in Meson are declared with single quotes. To enter a literal single quote do it like this:
+Strings in Meson are declared with single quotes. To enter a literal
+single quote do it like this:
```meson
single quote = 'contains a \' character'
```
-Similarly `\n` gets converted to a newline and `\\\\` to a single backslash.
+Similarly `\n` gets converted to a newline and `\\\\` to a single
+backslash.
#### String concatenation
@@ -80,7 +99,8 @@ combined = str1 + '_' + str2 # combined is now abc_xyz
#### Strings running over multiple lines
-Strings running over multiple lines can be declared with three single quotes, like this:
+Strings running over multiple lines can be declared with three single
+quotes, like this:
```meson
multiline_string = '''#include <foo.h>
@@ -89,7 +109,8 @@ int main (int argc, char ** argv) {
}'''
```
-This can also be combined with the string formatting functionality described below.
+This can also be combined with the string formatting functionality
+described below.
#### String formatting
@@ -101,11 +122,13 @@ res = template.format('text', 1, true)
# res now has value 'string: text, number: 1, bool: true'
```
-As can be seen, the formatting works by replacing placeholders of type `@number@` with the corresponding argument.
+As can be seen, the formatting works by replacing placeholders of type
+`@number@` with the corresponding argument.
#### String methods
-Strings also support a number of other methods that return transformed copies.
+Strings also support a number of other methods that return transformed
+copies.
**.strip()**
@@ -226,7 +249,9 @@ my_array += ['something']
my_array += 'else'
```
-Note appending to an array will always create a new array object and assign it to `my_array` instead of modifying the original since all objects in Meson are immutable.
+Note appending to an array will always create a new array object and
+assign it to `my_array` instead of modifying the original since all
+objects in Meson are immutable.
#### Array methods
@@ -239,7 +264,8 @@ The following methods are defined for all arrays:
Function calls
--
-Meson provides a set of usable functions. The most common use case is creating build objects.
+Meson provides a set of usable functions. The most common use case is
+creating build objects.
```meson
executable('progname', 'prog.c')
@@ -248,7 +274,8 @@ executable('progname', 'prog.c')
Method calls
--
-Objects can have methods, which are called with the dot operator. The exact methods it provides depends on the object.
+Objects can have methods, which are called with the dot operator. The
+exact methods it provides depends on the object.
```meson
myobj = some_function()
@@ -279,7 +306,9 @@ endif
## Foreach statements
-To do an operation on all elements of an array, use the `foreach` command. As an example, here's how you would define two executables with corresponding tests.
+To do an operation on all elements of an array, use the `foreach`
+command. As an example, here's how you would define two executables
+with corresponding tests.
```meson
progs = [['prog1', ['prog1.c', 'foo.c']],
@@ -291,7 +320,9 @@ foreach p : progs
endforeach
```
-Note that Meson variables are immutable. Trying to assign a new value to `progs` inside a foreach loop will not affect foreach's control flow.
+Note that Meson variables are immutable. Trying to assign a new value
+to `progs` inside a foreach loop will not affect foreach's control
+flow.
Logical operations
--
@@ -334,12 +365,20 @@ The ternary operator works just like in other languages.
x = condition ? true_value : false_value
```
-The only exception is that nested ternary operators are forbidden to improve legibility. If your branching needs are more complex than this you need to write an `if/else` construct.
+The only exception is that nested ternary operators are forbidden to
+improve legibility. If your branching needs are more complex than this
+you need to write an `if/else` construct.
Includes
--
-Most source trees have multiple subdirectories to process. These can be handled by Meson's `subdir` command. It changes to the given subdirectory and executes the contents of `meson.build` in that subdirectory. All state (variables etc) are passed to and from the subdirectory. The effect is roughly the same as if the contents of the subdirectory's Meson file would have been written where the include command is.
+Most source trees have multiple subdirectories to process. These can
+be handled by Meson's `subdir` command. It changes to the given
+subdirectory and executes the contents of `meson.build` in that
+subdirectory. All state (variables etc) are passed to and from the
+subdirectory. The effect is roughly the same as if the contents of the
+subdirectory's Meson file would have been written where the include
+command is.
```meson
test_data_dir = 'data'
@@ -349,4 +388,12 @@ subdir('tests')
User-defined functions and methods
--
-Meson does not currently support user-defined functions or methods. The addition of user-defined functions would make Meson Turing-complete which would make it harder to reason about and more difficult to integrate with tools like IDEs. More details about this are [in the FAQ](FAQ.md#why-is-meson-not-just-a-python-module-so-i-could-code-my-build-setup-in-python). If because of this limitation you find yourself copying and pasting code a lot you may be able to use a [`foreach` loop instead](#foreach-statements).
+Meson does not currently support user-defined functions or
+methods. The addition of user-defined functions would make Meson
+Turing-complete which would make it harder to reason about and more
+difficult to integrate with tools like IDEs. More details about this
+are [in the
+FAQ](FAQ.md#why-is-meson-not-just-a-python-module-so-i-could-code-my-build-setup-in-python). If
+because of this limitation you find yourself copying and pasting code
+a lot you may be able to use a [`foreach` loop
+instead](#foreach-statements).
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/i18n-module.md b/docs/markdown/i18n-module.md
index 1144e29..8fb650a 100644
--- a/docs/markdown/i18n-module.md
+++ b/docs/markdown/i18n-module.md
@@ -17,21 +17,17 @@ argument which is the name of the gettext module.
* `args`: list of extra arguments to pass to `xgettext` when
generating the pot file
-
* `data_dirs`: (*Added 0.36.0*) list of directories to be set for
`GETTEXTDATADIRS` env var (Requires gettext 0.19.8+), used for local
its files
-
* `languages`: list of languages that are to be generated. As of
0.37.0 this is optional and the
[LINGUAS](https://www.gnu.org/software/gettext/manual/html_node/po_002fLINGUAS.html)
file is read.
-
* `preset`: (*Added 0.37.0*) name of a preset list of arguments,
current option is `'glib'`, see
[source](https://github.com/mesonbuild/meson/blob/master/mesonbuild/modules/i18n.py)
for for their value
-
* `install`: (*Added 0.43.0*) if false, do not install the built translations.
This function also defines targets for maintainers to use:
diff --git a/docs/markdown/snippets/llvm-static-linking.md b/docs/markdown/snippets/llvm-static-linking.md
new file mode 100644
index 0000000..bb72a56
--- /dev/null
+++ b/docs/markdown/snippets/llvm-static-linking.md
@@ -0,0 +1,8 @@
+# LLVM dependency supports both dynamic and static linking
+
+The LLVM dependency has been improved to consistently use dynamic linking.
+Previously recent version (>= 3.9) would link dynamically while older versions
+would link statically.
+
+Now LLVM also accepts the `static` keyword to enable statically linking to LLVM
+modules instead of dynamically linking.
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..5a3c8d1 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -273,7 +273,7 @@ def sanitizer_compile_args(value):
if value == 'none':
return []
args = ['-fsanitize=' + value]
- if value == 'address':
+ if 'address' in value: # For -fsanitize=address,undefined
args.append('-fno-omit-frame-pointer')
return args
@@ -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 ad013d9..e8b23fd 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -30,9 +30,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.
@@ -73,13 +70,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
@@ -110,9 +100,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/dev.py b/mesonbuild/dependencies/dev.py
index 308ae55..257bf7a 100644
--- a/mesonbuild/dependencies/dev.py
+++ b/mesonbuild/dependencies/dev.py
@@ -16,6 +16,7 @@
# development purposes, such as testing, debugging, etc..
import os
+import re
import shlex
import shutil
@@ -116,19 +117,20 @@ class LLVMDependency(ExternalDependency):
# Ordered list of llvm-config binaries to try. Start with base, then try
# newest back to oldest (3.5 is abitrary), and finally the devel version.
- # Please note that llvm-config-5.0 is a development snapshot and it should
+ # Please note that llvm-config-6.0 is a development snapshot and it should
# not be moved to the beginning of the list. The only difference between
- # llvm-config-5.0 and llvm-config-devel is that the former is used by
+ # llvm-config-6.0 and llvm-config-devel is that the former is used by
# Debian and the latter is used by FreeBSD.
llvm_config_bins = [
'llvm-config', # base
- 'llvm-config-4.0', 'llvm-config40', # latest stable release
- 'llvm-config-3.9', 'llvm-config39', # old stable releases
+ 'llvm-config-5.0', 'llvm-config50', # latest stable release
+ 'llvm-config-4.0', 'llvm-config40', # old stable releases
+ 'llvm-config-3.9', 'llvm-config39',
'llvm-config-3.8', 'llvm-config38',
'llvm-config-3.7', 'llvm-config37',
'llvm-config-3.6', 'llvm-config36',
'llvm-config-3.5', 'llvm-config35',
- 'llvm-config-5.0', 'llvm-config-devel', # development snapshot
+ 'llvm-config-6.0', 'llvm-config-devel', # development snapshot
]
__cpp_blacklist = {'-DNDEBUG'}
@@ -136,8 +138,10 @@ class LLVMDependency(ExternalDependency):
# It's necessary for LLVM <= 3.8 to use the C++ linker. For 3.9 and 4.0
# the C linker works fine if only using the C API.
super().__init__('llvm-config', environment, 'cpp', kwargs)
- self.modules = []
+ self.provided_modules = []
+ self.required_modules = set()
self.llvmconfig = None
+ self.static = kwargs.get('static', False)
self.__best_found = None
# FIXME: Support multiple version requirements ala PkgConfigDependency
req_version = kwargs.get('version', None)
@@ -169,31 +173,90 @@ class LLVMDependency(ExternalDependency):
# for users who want the patch version.
self.version = out.strip().rstrip('svn')
- p, out = Popen_safe(
- [self.llvmconfig, '--libs', '--ldflags'])[:2]
+ p, out, err = Popen_safe([self.llvmconfig, '--components'])
if p.returncode != 0:
- raise DependencyException('Could not generate libs for LLVM.')
- self.link_args = strip_system_libdirs(environment, shlex.split(out))
- p, out = Popen_safe([self.llvmconfig, '--cppflags'])[:2]
+ raise DependencyException('Could not generate modules for LLVM:\n' + err)
+ self.provided_modules = shlex.split(out)
+
+ modules = stringlistify(extract_as_list(kwargs, 'modules'))
+ self.check_components(modules)
+ opt_modules = stringlistify(extract_as_list(kwargs, 'optional_modules'))
+ self.check_components(opt_modules, required=False)
+
+ p, out, err = Popen_safe([self.llvmconfig, '--cppflags'])
if p.returncode != 0:
- raise DependencyException('Could not generate includedir for LLVM.')
+ raise DependencyException('Could not generate includedir for LLVM:\n' + err)
cargs = mesonlib.OrderedSet(shlex.split(out))
self.compile_args = list(cargs.difference(self.__cpp_blacklist))
- p, out = Popen_safe([self.llvmconfig, '--components'])[:2]
+ if version_compare(self.version, '>= 3.9'):
+ self._set_new_link_args()
+ else:
+ self._set_old_link_args()
+ self.link_args = strip_system_libdirs(environment, self.link_args)
+
+ def _set_new_link_args(self):
+ """How to set linker args for LLVM versions >= 3.9"""
+ link_args = ['--link-static', '--system-libs'] if self.static else ['--link-shared']
+ p, out, err = Popen_safe(
+ [self.llvmconfig, '--libs', '--ldflags'] + link_args + list(self.required_modules))
if p.returncode != 0:
- raise DependencyException('Could not generate modules for LLVM.')
- self.modules = shlex.split(out)
+ raise DependencyException('Could not generate libs for LLVM:\n' + err)
+ self.link_args = shlex.split(out)
- modules = stringlistify(extract_as_list(kwargs, 'modules'))
+ def _set_old_link_args(self):
+ """Setting linker args for older versions of llvm.
+
+ Old versions of LLVM bring an extra level of insanity with them.
+ llvm-config will provide the correct arguments for static linking, but
+ not for shared-linnking, we have to figure those out ourselves, because
+ of course we do.
+ """
+ if self.static:
+ p, out, err = Popen_safe(
+ [self.llvmconfig, '--libs', '--ldflags', '--system-libs'] + list(self.required_modules))
+ if p.returncode != 0:
+ raise DependencyException('Could not generate libs for LLVM:\n' + err)
+ self.link_args = shlex.split(out)
+ else:
+ # llvm-config will provide arguments for static linking, so we get
+ # to figure out for ourselves what to link with. We'll do that by
+ # checking in the directory provided by --libdir for a library
+ # called libLLVM-<ver>.(so|dylib|dll)
+ p, out, err = Popen_safe([self.llvmconfig, '--libdir'])
+ if p.returncode != 0:
+ raise DependencyException('Could not generate libs for LLVM:\n' + err)
+ libdir = out.strip()
+
+ expected_name = 'libLLVM-{}'.format(self.version)
+ re_name = re.compile(r'{}.(so|dll|dylib)'.format(expected_name))
+
+ for file_ in os.listdir(libdir):
+ if re_name.match(file_):
+ self.link_args = ['-L{}'.format(libdir),
+ '-l{}'.format(os.path.splitext(file_.lstrip('lib'))[0])]
+ break
+ else:
+ raise DependencyException(
+ 'Could not find a dynamically linkable library for LLVM.')
+
+ def check_components(self, modules, required=True):
+ """Check for llvm components (modules in meson terms).
+
+ The required option is whether the module is required, not whether LLVM
+ is required.
+ """
for mod in sorted(set(modules)):
- if mod not in self.modules:
- mlog.log('LLVM module', mod, 'found:', mlog.red('NO'))
- self.is_found = False
- if self.required:
- raise DependencyException(
- 'Could not find required LLVM Component: {}'.format(mod))
+ if mod not in self.provided_modules:
+ mlog.log('LLVM module', mod, 'found:', mlog.red('NO'),
+ '(optional)' if not required else '')
+ if required:
+ self.is_found = False
+ if self.required:
+ raise DependencyException(
+ 'Could not find required LLVM Component: {}'.format(mod))
else:
+ self.required_modules.add(mod)
mlog.log('LLVM module', mod, 'found:', mlog.green('YES'))
def check_llvmconfig(self, version_req):
diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py
index 81bcdcb..c807926 100644
--- a/mesonbuild/dependencies/misc.py
+++ b/mesonbuild/dependencies/misc.py
@@ -66,6 +66,11 @@ class BoostDependency(ExternalDependency):
self.is_multithreading = threading == "multi"
self.requested_modules = self.get_requested(kwargs)
+ invalid_modules = [c for c in self.requested_modules if 'boost_' + c not in BOOST_LIBS]
+ if invalid_modules:
+ mlog.warning('Invalid Boost modules: ' + ', '.join(invalid_modules))
+ self.log_fail()
+ return
self.boost_root = None
self.boost_roots = []
@@ -198,8 +203,6 @@ class BoostDependency(ExternalDependency):
for c in candidates:
if not isinstance(c, str):
raise DependencyException('Boost module argument is not a string.')
- if 'boost_' + c not in BOOST_LIBS:
- raise DependencyException('Dependency {} not found. It is not a valid boost library.'.format(c))
return candidates
def validate_requested(self):
@@ -359,11 +362,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 +764,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',
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..c7a0fb7 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 = '<{} {}: {}>'
@@ -696,7 +696,8 @@ class CompilerHolder(InterpreterObject):
if not isinstance(i, IncludeDirsHolder):
raise InterpreterException('Include directories argument must be an include_directories object.')
for idir in i.held_object.get_incdirs():
- idir = os.path.join(self.environment.get_source_dir(), idir)
+ idir = os.path.join(self.environment.get_source_dir(),
+ i.held_object.get_curdir(), idir)
args += self.compiler.get_include_args(idir, False)
if not nobuiltins:
opts = self.environment.coredata.compiler_options
@@ -1060,10 +1061,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 +1086,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,
@@ -1389,6 +1391,8 @@ class Interpreter(InterpreterBase):
self.subproject_stack = []
self.default_project_options = default_project_options[:] # Passed from the outside, only used in subprojects.
self.build_func_dict()
+ # build_def_files needs to be defined before parse_project is called
+ self.build_def_files = [os.path.join(self.subdir, environment.build_filename)]
self.parse_project()
self.builtin['build_machine'] = BuildMachine(self.coredata.compilers)
if not self.build.environment.is_cross_build():
@@ -1404,7 +1408,6 @@ class Interpreter(InterpreterBase):
self.builtin['target_machine'] = CrossMachineInfo(cross_info.config['target_machine'])
else:
self.builtin['target_machine'] = self.builtin['host_machine']
- self.build_def_files = [os.path.join(self.subdir, environment.build_filename)]
def build_func_dict(self):
self.funcs.update({'add_global_arguments': self.func_add_global_arguments,
@@ -1442,6 +1445,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 +1583,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 +1642,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 +1655,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 +1872,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 +1888,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 +2316,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 +2359,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 +2823,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 +2854,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/mconf.py b/mesonbuild/mconf.py
index ee4dbf8..09b0f12 100644
--- a/mesonbuild/mconf.py
+++ b/mesonbuild/mconf.py
@@ -17,7 +17,7 @@ import pickle
import argparse
from . import coredata, mesonlib
-parser = argparse.ArgumentParser()
+parser = argparse.ArgumentParser(prog='meson configure')
parser.add_argument('-D', action='append', default=[], dest='sets',
help='Set an option to the given value.')
diff --git a/mesonbuild/mesonmain.py b/mesonbuild/mesonmain.py
index 12d8530..8d5fb85 100644
--- a/mesonbuild/mesonmain.py
+++ b/mesonbuild/mesonmain.py
@@ -24,7 +24,7 @@ from .mesonlib import MesonException
from .wrap import WrapMode, wraptool
-parser = argparse.ArgumentParser()
+parser = argparse.ArgumentParser(prog='meson')
default_warning = '1'
@@ -198,23 +198,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/mintro.py b/mesonbuild/mintro.py
index 7356175..568bdfc 100644
--- a/mesonbuild/mintro.py
+++ b/mesonbuild/mintro.py
@@ -25,7 +25,7 @@ import argparse
import sys, os
import pathlib
-parser = argparse.ArgumentParser()
+parser = argparse.ArgumentParser(prog='meson introspect')
parser.add_argument('--targets', action='store_true', dest='list_targets', default=False,
help='List top level targets.')
parser.add_argument('--installed', action='store_true', dest='list_installed', default=False,
@@ -104,6 +104,7 @@ def list_targets(coredata, builddata, installdata):
t['install_filename'] = determine_installed_path(target, installdata)
else:
t['installed'] = False
+ t['build_by_default'] = target.build_by_default
tlist.append(t)
print(json.dumps(tlist))
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 01604f2..7e61242 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)
@@ -650,7 +650,7 @@ class GnomeModule(ExtensionModule):
targetname = 'gsettings-compile'
else:
targetname = 'gsettings-compile-' + state.subdir.replace('/', '_')
- target_g = build.CustomTarget(targetname, state.subdir, kwargs)
+ 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)
@@ -723,7 +723,7 @@ This will become a hard error in the future.''')
@permittedKwargs({'main_xml', 'main_sgml', 'src_dir', 'dependencies', 'install',
'install_dir', 'scan_args', 'scanobjs_args', 'gobject_typesfile',
'fixxref_args', 'html_args', 'html_assets', 'content_files',
- 'mkdb_args', 'ignore_headers'})
+ 'mkdb_args', 'ignore_headers', 'include_directories'})
def gtkdoc(self, state, args, kwargs):
if len(args) != 1:
raise MesonException('Gtkdoc must have one positional argument.')
@@ -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..267e130 100644
--- a/mesonbuild/mtest.py
+++ b/mesonbuild/mtest.py
@@ -58,7 +58,7 @@ def determine_worker_count():
num_workers = 1
return num_workers
-parser = argparse.ArgumentParser()
+parser = argparse.ArgumentParser(prog='meson test')
parser.add_argument('--repeat', default=1, dest='repeat', type=int,
help='Number of times to run the tests.')
parser.add_argument('--no-rebuild', default=False, action='store_true',
@@ -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/rewriter.py b/mesonbuild/rewriter.py
index b88c5ef..0191c30 100644
--- a/mesonbuild/rewriter.py
+++ b/mesonbuild/rewriter.py
@@ -29,7 +29,7 @@ from mesonbuild import mlog
import sys, traceback
import argparse
-parser = argparse.ArgumentParser()
+parser = argparse.ArgumentParser(prog='meson rewrite')
parser.add_argument('--sourcedir', default='.',
help='Path to source directory.')
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/mesonbuild/scripts/meson_install.py b/mesonbuild/scripts/meson_install.py
index 985b0e9..9485967 100644
--- a/mesonbuild/scripts/meson_install.py
+++ b/mesonbuild/scripts/meson_install.py
@@ -20,7 +20,7 @@ from . import destdir_join
from ..mesonlib import is_windows, Popen_safe
install_log_file = None
-use_selinux = True
+selinux_updates = []
class DirMaker:
def __init__(self):
@@ -84,27 +84,24 @@ def set_mode(path, mode):
msg = '{!r}: Unable to set permissions {!r}: {}, ignoring...'
print(msg.format(path, mode.perms_s, e.strerror))
-def restore_selinux_context(to_file):
+def restore_selinux_contexts():
'''
- Restores the SELinux context for @to_file
+ Restores the SELinux context for files in @selinux_updates
'''
- global use_selinux
-
- if not use_selinux:
- return
-
try:
subprocess.check_call(['selinuxenabled'])
- try:
- subprocess.check_call(['restorecon', '-F', to_file], stderr=subprocess.DEVNULL)
- except subprocess.CalledProcessError as e:
- use_selinux = False
- msg = "{!r}: Failed to restore SELinux context, ignoring SELinux context for all remaining files..."
- print(msg.format(to_file, e.returncode))
except (FileNotFoundError, PermissionError, subprocess.CalledProcessError) as e:
# If we don't have selinux or selinuxenabled returned 1, failure
# is ignored quietly.
- use_selinux = False
+ return
+
+ with subprocess.Popen(['restorecon', '-F', '-f-', '-0'],
+ stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc:
+ out, err = proc.communicate(input=b'\0'.join(os.fsencode(f) for f in selinux_updates) + b'\0')
+ if proc.returncode != 0:
+ print('Failed to restore SELinux context of installed files...',
+ 'Standard output:', out.decode(),
+ 'Standard error:', err.decode(), sep='\n')
def append_to_log(line):
install_log_file.write(line)
@@ -126,7 +123,7 @@ def do_copyfile(from_file, to_file):
os.unlink(to_file)
shutil.copyfile(from_file, to_file)
shutil.copystat(from_file, to_file)
- restore_selinux_context(to_file)
+ selinux_updates.append(to_file)
append_to_log(to_file)
def do_copydir(data, src_prefix, src_dir, dst_dir, exclude):
@@ -192,6 +189,7 @@ def do_install(datafilename):
install_headers(d)
install_man(d)
install_data(d)
+ restore_selinux_contexts()
run_install_script(d)
def install_subdirs(d):
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/test cases/common/163 includedir subproj/meson.build b/test cases/common/163 includedir subproj/meson.build
new file mode 100644
index 0000000..b3de5af
--- /dev/null
+++ b/test cases/common/163 includedir subproj/meson.build
@@ -0,0 +1,9 @@
+project('include dir in subproj test', 'c')
+
+
+subproject('inctest')
+
+
+exe = executable('prog', 'prog.c')
+
+test('dummy', exe)
diff --git a/test cases/common/163 includedir subproj/prog.c b/test cases/common/163 includedir subproj/prog.c
new file mode 100644
index 0000000..772681e
--- /dev/null
+++ b/test cases/common/163 includedir subproj/prog.c
@@ -0,0 +1,4 @@
+
+int main(int argc, char **argv) {
+ return 0;
+}
diff --git a/test cases/common/163 includedir subproj/subprojects/inctest/include/incfile.h b/test cases/common/163 includedir subproj/subprojects/inctest/include/incfile.h
new file mode 100644
index 0000000..ec740da
--- /dev/null
+++ b/test cases/common/163 includedir subproj/subprojects/inctest/include/incfile.h
@@ -0,0 +1,2 @@
+
+/* file which is used in the subproject */
diff --git a/test cases/common/163 includedir subproj/subprojects/inctest/meson.build b/test cases/common/163 includedir subproj/subprojects/inctest/meson.build
new file mode 100644
index 0000000..74aabcb
--- /dev/null
+++ b/test cases/common/163 includedir subproj/subprojects/inctest/meson.build
@@ -0,0 +1,13 @@
+
+project('subproj with includedir', 'c')
+
+
+
+compile_check = '''
+#include "incfile.h"
+'''
+
+if not meson.get_compiler('c').compiles(compile_check, name : 'include in subproj',
+ include_directories: include_directories('include'))
+ error('failed')
+endif
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/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/15 llvm/meson.build b/test cases/frameworks/15 llvm/meson.build
index 468094a..5211006 100644
--- a/test cases/frameworks/15 llvm/meson.build
+++ b/test cases/frameworks/15 llvm/meson.build
@@ -1,21 +1,36 @@
project('llvmtest', ['c', 'cpp'], default_options : ['c_std=c99'])
-llvm_dep = dependency(
- 'llvm',
- modules : ['bitwriter', 'asmprinter', 'executionengine', 'target',
- 'mcjit', 'nativecodegen'],
- required : true,
-)
-
d = dependency('llvm', modules : 'not-found', required : false)
assert(d.found() == false, 'not-found llvm module found')
d = dependency('llvm', version : '<0.1', required : false)
assert(d.found() == false, 'ancient llvm module found')
-executable('sum', 'sum.c', dependencies : [
- llvm_dep,
- dependency('zlib'),
- meson.get_compiler('c').find_library('dl', required : false),
- dependency('tinfo'),
- ])
+d = dependency('llvm', optional_modules : 'not-found', required : false)
+assert(d.found() == true, 'optional module stopped llvm from being found.')
+
+dep_tinfo = dependency('tinfo', required : false)
+if not dep_tinfo.found()
+ cpp = meson.get_compiler('cpp')
+ dep_tinfo = cpp.find_library('tinfo')
+endif
+
+foreach static : [true, false]
+ llvm_dep = dependency(
+ 'llvm',
+ modules : ['bitwriter', 'asmprinter', 'executionengine', 'target',
+ 'mcjit', 'nativecodegen'],
+ required : true,
+ static : static,
+ )
+ name = static ? 'static' : 'dynamic'
+ executable(
+ 'sum-@0@'.format(name),
+ 'sum.c',
+ dependencies : [
+ llvm_dep, dep_tinfo,
+ dependency('zlib'),
+ meson.get_compiler('c').find_library('dl', required : false),
+ ]
+ )
+endforeach
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'))