aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Gnome-module.md9
-rw-r--r--docs/markdown/Python-module.md40
-rw-r--r--docs/markdown/Reference-manual.md13
-rw-r--r--docs/markdown/Release-notes-for-0.46.0.md315
-rw-r--r--docs/markdown/Release-notes-for-0.47.0.md23
-rw-r--r--docs/markdown/Syntax.md3
-rw-r--r--docs/markdown/Users.md1
-rw-r--r--docs/markdown/Wrap-dependency-system-manual.md6
-rw-r--r--docs/markdown/snippets/altered-logging.md5
-rw-r--r--docs/markdown/snippets/armcc-cross.md15
-rw-r--r--docs/markdown/snippets/both-libraries.md9
-rw-r--r--docs/markdown/snippets/compiler-object-run_command.md10
-rw-r--r--docs/markdown/snippets/d-options-for-meson-setup.md6
-rw-r--r--docs/markdown/snippets/declare_dependency-link_whole.md4
-rw-r--r--docs/markdown/snippets/del-old-names.md7
-rw-r--r--docs/markdown/snippets/find-override.md37
-rw-r--r--docs/markdown/snippets/has-link-argument.md9
-rw-r--r--docs/markdown/snippets/improved-help.md6
-rw-r--r--docs/markdown/snippets/improved-meson-init.md19
-rw-r--r--docs/markdown/snippets/install_data-rename.md11
-rw-r--r--docs/markdown/snippets/lcc.md23
-rw-r--r--docs/markdown/snippets/more-escape-sequences.md17
-rw-r--r--docs/markdown/snippets/new-wrap-mode.md3
-rw-r--r--docs/markdown/snippets/non-unique-target-names.md9
-rw-r--r--docs/markdown/snippets/openmp-dependency.md6
-rw-r--r--docs/markdown/snippets/partial-dependencies.md25
-rw-r--r--docs/markdown/snippets/pkg-config-fix-static-only.md12
-rw-r--r--docs/markdown/snippets/pkgconfig-generator.md14
-rw-r--r--docs/markdown/snippets/pkgconfig-requires-non-string.md5
-rw-r--r--docs/markdown/snippets/python-module.md6
-rw-r--r--docs/sitemap.txt1
-rw-r--r--man/meson.12
-rw-r--r--man/mesonconf.12
-rw-r--r--man/mesonintrospect.12
-rw-r--r--man/mesontest.12
-rw-r--r--man/wraptool.12
-rw-r--r--manual tests/2 multiwrap/subprojects/libpng.wrap14
-rw-r--r--mesonbuild/backend/backends.py67
-rw-r--r--mesonbuild/backend/ninjabackend.py24
-rw-r--r--mesonbuild/backend/vs2010backend.py2
-rw-r--r--mesonbuild/build.py57
-rw-r--r--mesonbuild/compilers/c.py2
-rw-r--r--mesonbuild/coredata.py2
-rw-r--r--mesonbuild/dependencies/__init__.py2
-rw-r--r--mesonbuild/dependencies/base.py8
-rw-r--r--mesonbuild/interpreter.py224
-rw-r--r--mesonbuild/interpreterbase.py59
-rw-r--r--mesonbuild/mlog.py5
-rw-r--r--mesonbuild/modules/gnome.py27
-rw-r--r--mesonbuild/modules/pkgconfig.py2
-rw-r--r--mesonbuild/modules/python.py52
-rw-r--r--mesonbuild/mparser.py16
-rwxr-xr-xrun_project_tests.py40
-rwxr-xr-xrun_unittests.py68
-rw-r--r--test cases/common/132 dependency file generation/meson.build2
-rw-r--r--test cases/common/196 same target name/file.c (renamed from test cases/common/183 same target name/file.c)0
-rw-r--r--test cases/common/196 same target name/meson.build (renamed from test cases/common/183 same target name/meson.build)0
-rw-r--r--test cases/common/196 same target name/sub/file2.c (renamed from test cases/common/183 same target name/sub/file2.c)0
-rw-r--r--test cases/common/196 same target name/sub/meson.build (renamed from test cases/common/183 same target name/sub/meson.build)0
-rwxr-xr-xtest cases/common/197 test depends/gen.py13
-rw-r--r--test cases/common/197 test depends/main.c1
-rw-r--r--test cases/common/197 test depends/meson.build26
-rwxr-xr-xtest cases/common/197 test depends/test.py20
-rw-r--r--test cases/common/22 header in file list/meson.build2
-rw-r--r--test cases/common/32 multiline string/meson.build10
-rw-r--r--test cases/common/33 try compile/meson.build4
-rw-r--r--test cases/common/39 tryrun/meson.build4
-rw-r--r--test cases/common/42 string operations/meson.build12
-rw-r--r--test cases/common/64 custom header generator/meson.build2
-rw-r--r--test cases/common/88 extract all/meson.build10
-rw-r--r--test cases/frameworks/7 gnome/gdbus/meson.build3
-rw-r--r--test cases/unit/27 forcefallback/meson.build3
-rw-r--r--test cases/unit/30 mixed command line args/meson.build1
-rw-r--r--test cases/unit/30 mixed command line args/meson_options.txt10
74 files changed, 954 insertions, 519 deletions
diff --git a/docs/markdown/Gnome-module.md b/docs/markdown/Gnome-module.md
index 3db6cc0..1bf333f 100644
--- a/docs/markdown/Gnome-module.md
+++ b/docs/markdown/Gnome-module.md
@@ -227,9 +227,11 @@ useful when running the application locally for example during tests.
### gnome.gdbus_codegen()
Compiles the given XML schema into gdbus source code. Takes two
-positional arguments, the first one specifies the name of the source
-files and the second specifies the XML file name.
+positional arguments, the first one specifies the base name to use
+while creating the output source and header and the second specifies
+one XML file.
+* `sources`: list of XML files
* `interface_prefix`: prefix for the interface
* `namespace`: namespace of the interface
* `object_manager`: *(Added 0.40.0)* if true generates object manager code
@@ -257,7 +259,8 @@ Example:
gnome = import('gnome')
# The returned source would be passed to another target
-gdbus_src = gnome.gdbus_codegen('example-interface', 'com.example.Sample.xml',
+gdbus_src = gnome.gdbus_codegen('example-interface',
+ sources: 'com.example.Sample.xml',
interface_prefix : 'com.example.',
namespace : 'Sample',
annotations : [
diff --git a/docs/markdown/Python-module.md b/docs/markdown/Python-module.md
index cad74c9..51721f0 100644
--- a/docs/markdown/Python-module.md
+++ b/docs/markdown/Python-module.md
@@ -142,7 +142,7 @@ This function expects no arguments or keyword arguments.
#### `get_path()`
``` meson
-string py_installation.get_path(path_name)
+string py_installation.get_path(path_name, fallback)
```
Get a path as defined by the `sysconfig` module.
@@ -153,15 +153,28 @@ For example:
purelib = py_installation.get_path('purelib')
```
-This function accepts a single argument, `path_name`, which is expected to
-be a non-empty string.
+This function requires at least one argument, `path_name`,
+which is expected to be a non-empty string.
+
+If `fallback` is specified, it will be returned if no path
+with the given name exists. Otherwise, attempting to read
+a non-existing path will cause a fatal error.
**Returns**: A string
+#### `has_path()`
+
+``` meson
+ bool py_installation.has_path(path_name)
+```
+
+**Returns**: true if a path named `path_name` can be retrieved with
+[][`get_path()`], false otherwise.
+
#### `get_variable()`
``` meson
-string py_installation.get_variable(variable_name)
+string py_installation.get_variable(variable_name, fallback)
```
Get a variable as defined by the `sysconfig` module.
@@ -169,14 +182,27 @@ Get a variable as defined by the `sysconfig` module.
For example:
``` meson
-py_bindir = py_installation.get_variable('BINDIR')
+py_bindir = py_installation.get_variable('BINDIR', '')
```
-This function accepts a single argument, `variable_name`, which is expected to
-be a non-empty string.
+This function requires at least one argument, `variable_name`,
+which is expected to be a non-empty string.
+
+If `fallback` is specified, it will be returned if no variable
+with the given name exists. Otherwise, attempting to read
+a non-existing variable will cause a fatal error.
**Returns**: A string
+#### `has_variable()`
+
+``` meson
+ bool py_installation.has_variable(variable_name)
+```
+
+**Returns**: true if a variable named `variable_name` can be retrieved with
+[][`get_variable()`], false otherwise.
+
## `python_dependency` object
This [dependency object] subclass will try various methods to obtain the
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index 74e7ff2..776703c 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -1256,6 +1256,13 @@ Keyword arguments are the following:
- `workdir` absolute path that will be used as the working directory
for the test
+- `depends` specifies that this test depends on the specified
+ target(s), even though it does not take any of them as a command
+ line argument. This is meant for cases where test finds those
+ targets internally, e.g. plugins or globbing. Those targets are built
+ before test is executed even if they have `build_by_default : false`.
+ Since 0.46.0
+
Defined tests can be run in a backend-agnostic way by calling
`meson test` inside the build dir, or by using backend-specific
commands, such as `ninja test` or `msbuild RUN_TESTS.vcxproj`.
@@ -1729,7 +1736,11 @@ A build target is either an [executable](#executable),
[shared module](#shared_module).
- `extract_all_objects()` is same as `extract_objects` but returns all
- object files generated by this target
+ object files generated by this target. Since 0.46.0 keyword argument
+ `recursive` must be set to `true` to also return objects passed to the
+ `object` argument of this target. By default only objects built for this
+ target are returned to maintain backward compatibility with previous versions.
+ The default will eventually be changed to `true` in a future version.
- `extract_objects()` returns an opaque value representing the
generated object files of arguments, usually used to take single
diff --git a/docs/markdown/Release-notes-for-0.46.0.md b/docs/markdown/Release-notes-for-0.46.0.md
index e062459..c9f9bbd 100644
--- a/docs/markdown/Release-notes-for-0.46.0.md
+++ b/docs/markdown/Release-notes-for-0.46.0.md
@@ -1,23 +1,316 @@
---
title: Release 0.46
-short-description: Release notes for 0.46 (preliminary)
+short-description: Release notes for 0.46
...
# New features
-This page is a placeholder for the eventual release notes.
-
-Notable new features should come with release note updates. This is
-done by creating a file snippet called `snippets/featurename.md` and
-whose contents should look like this:
-
- ## Feature name
-
- A short description explaining the new feature and how it should be used.
-
## Allow early return from a script
Added the function `subdir_done()`. Its invocation exits the current script at
the point of invocation. All previously invoked build targets and commands are
build/executed. All following ones are ignored. If the current script was
invoked via `subdir()` the parent script continues normally.
+
+## Log output slightly changed
+
+The format of some human-readable diagnostic messages has changed in
+minor ways. In case you are parsing these messages, you may need to
+adjust your code.
+
+## ARM compiler for C and CPP
+
+Cross-compilation is now supported for ARM targets using ARM compiler - ARMCC.
+The current implementation does not support shareable libraries.
+The default extension of the output is .axf.
+The environment path should be set properly for the ARM compiler executables.
+The '--cpu' option with the appropriate target type should be mentioned
+in the cross file as shown in the snippet below.
+
+```ini
+[properties]
+c_args = ['--cpu=Cortex-M0plus']
+cpp_args = ['--cpu=Cortex-M0plus']
+
+```
+
+## Building both shared and static libraries
+
+A new function `both_libraries()` has been added to build both shared and static
+libraries at the same time. Source files will be compiled only once and object
+files will be reused to build both shared and static libraries, unless
+`b_staticpic` user option or `pic:` keyword argument are set to false in which
+case sources will be compiled twice.
+
+The returned `buildtarget` object always represents the shared library.
+
+## Compiler object can now be passed to run_command()
+
+This can be used to run the current compiler with the specified arguments
+to obtain additional information from it.
+One of the use cases is to get the location of development files for the
+GCC plugins:
+
+```meson
+cc = meson.get_compiler('c')
+result = run_command(cc, '-print-file-name=plugin')
+plugin_dev_path = result.stdout().strip()
+```
+
+## declare_dependency() now supports `link_whole:`
+
+`declare_dependency()` now supports the `link_whole:` keyword argument which
+transparently works for build targets which use that dependency.
+
+## Old command names are now errors
+
+The old executable names `mesonintrospect`, `mesonconf`, `mesonrewriter`
+and `mesontest` have been deprecated for a long time. Starting from
+this version they no longer do anything but instead always error
+out. All functionality is available as subcommands in the main `meson`
+binary.
+
+## Meson and meson configure now accept the same arguments
+
+Previously meson required that builtin arguments (like prefix) be passed as
+`--prefix` to `meson` and `-Dprefix` to `meson configure`. `meson` now accepts -D
+form like `meson configure` has. `meson configure` also accepts the `--prefix`
+form, like `meson` has.
+
+## Recursively extract objects
+
+The `recursive:` keyword argument has been added to `extract_all_objects()`. When set
+to `true` it will also return objects passed to the `objects:` argument of this
+target. By default only objects built for this target are returned to maintain
+backward compatibility with previous versions. The default will eventually be
+changed to `true` in a future version.
+
+```meson
+lib1 = static_library('a', 'source.c', objects : 'prebuilt.o')
+lib2 = static_library('b', objects : lib1.extract_all_objects(recursive : true))
+```
+
+## Can override find_program()
+
+It is now possible to override the result of `find_program` to point
+to a custom program you want. The overriding is global and applies to
+every subproject from there on. Here is how you would use it.
+
+In master project
+
+```meson
+subproject('mydep')
+```
+
+In the called subproject:
+
+```meson
+prog = find_program('my_custom_script')
+meson.override_find_program('mycodegen', prog)
+```
+
+In master project (or, in fact, any subproject):
+
+```meson
+genprog = find_program('mycodegen')
+```
+
+Now `genprog` points to the custom script. If the dependency had come
+from the system, then it would point to the system version.
+
+You can also use the return value of `configure_file()` to override
+a program in the same way as above:
+
+```meson
+prog_script = configure_file(input : 'script.sh.in',
+ output : 'script.sh',
+ configuration : cdata)
+meson.override_find_program('mycodegen', prog_script)
+```
+
+## New functions: has_link_argument() and friends
+
+A new set of methods has been added to [compiler objects](Reference-manual.md#compiler-object)
+to test if the linker supports given arguments.
+
+- `has_link_argument()`
+- `has_multi_link_arguments()`
+- `get_supported_link_arguments()`
+- `first_supported_link_argument()`
+
+## "meson help" now shows command line help
+
+Command line parsing is now less surprising. "meson help" is now
+equivalent to "meson --help" and "meson help <subcommand>" is
+equivalent to "meson <subcommand> --help", instead of creating a build
+directory called "help" in these cases.
+
+## Autogeneration of simple meson.build files
+
+A feature to generate a meson.build file compiling given C/C++ source
+files into a single executable has been added to "meson init". By
+default, it will take all recognizable source files in the current
+directory. You can also specify a list of dependencies with the -d
+flag and automatically invoke a build with the -b flag to check if the
+code builds with those dependencies.
+
+For example,
+
+```meson
+meson init -fbd sdl2,gl
+```
+
+will look for C or C++ files in the current directory, generate a
+meson.build for them with the dependencies of sdl2 and gl and
+immediately try to build it, overwriting any previous meson.build and
+build directory.
+
+## install_data() supports `rename:`
+
+The `rename:` keyword argument is used to change names of the installed
+files. Here's how you install and rename the following files:
+
+- `file1.txt` into `share/myapp/dir1/data.txt`
+- `file2.txt` into `share/myapp/dir2/data.txt`
+
+```meson
+install_data(['file1.txt', 'file2.txt'],
+ rename : ['dir1/data.txt', 'dir2/data.txt'],
+ install_dir : 'share/myapp')
+```
+
+## Support for lcc compiler for e2k (Elbrus) architecture
+
+In this version, a support for lcc compiler for Elbrus processors
+based on [e2k microarchitecture](https://en.wikipedia.org/wiki/Elbrus_2000)
+has been added.
+
+Examples of such CPUs:
+* [Elbrus-8S](https://en.wikipedia.org/wiki/Elbrus-8S);
+* Elbrus-4S;
+* [Elbrus-2S+](https://en.wikipedia.org/wiki/Elbrus-2S%2B).
+
+Such compiler have a similar behavior as gcc (basic option compatibility),
+but, in is not strictly compatible with gcc as of current version.
+
+Major differences as of version 1.21.22:
+* it does not support LTO and PCH;
+* it suffers from the same dependency file creation error as icc;
+* it has minor differences in output, especially version output;
+* it differently reacts to lchmod() detection;
+* some backend messages are produced in ru_RU.KOI8-R even if LANG=C;
+* its preprocessor treats some characters differently.
+
+So every noted difference is properly handled now in meson.
+
+## String escape character sequence update
+
+Single-quoted strings in meson have been taught the same set of escape
+sequences as in Python. It is therefore now possible to use arbitrary bytes in
+strings, like for example `NUL` (`\0`) and other ASCII control characters. See
+the chapter about [*Strings* in *Syntax*](Syntax.md#strings) for more
+details.
+
+Potential backwards compatibility issue: Any valid escape sequence according to
+the new rules will be interpreted as an escape sequence instead of the literal
+characters. Previously only the following escape sequences were supported in
+single-quote strings: `\'`, `\\` and `\n`.
+
+Note that the behaviour of triple-quoted (multiline) strings has not changed.
+They behave like raw strings and do not support any escape sequences.
+
+## New `forcefallback` wrap mode
+
+A new wrap mode was added, `--wrap-mode=forcefallback`. When this is set,
+dependencies for which a fallback was provided will always use it, even
+if an external dependency exists and satisfies the version requirements.
+
+## Relaxing of target name requirements
+
+In earlier versions of Meson you could only have one target of a given name for each type.
+For example you could not have two executables named `foo`. This requirement is now
+relaxed so that you can have multiple targets with the same name, as long as they are in
+different subdirectories.
+
+Note that projects that have multiple targets with the same name can not be built with
+the `flat` layout or any backend that writes outputs in the same directory.
+
+## Addition of OpenMP dependency
+
+An OpenMP dependency (`openmp`) has been added that encapsulates the various
+flags used by compilers to enable OpenMP and checks for the existence of the
+`omp.h` header. The `language` keyword may be passed to force the use of a
+specific compiler for the checks.
+
+## Added new partial_dependency method to dependencies and libraries
+
+It is now possible to use only part of a dependency in a target. This allows,
+for example, to only use headers with convenience libraries to avoid linking
+to the same library multiple times.
+
+```meson
+dep = dependency('xcb')
+
+helper = static_library(
+ 'helper',
+ ['helper1.c', 'helper2.c'],
+ dependencies : dep.partial_dependency(includes : true),
+]
+
+final = shared_library(
+ 'final',
+ ['final.c'],
+ dependencyes : dep,
+)
+```
+
+A partial dependency will have the same name version as the full dependency it
+is derived from, as well as any values requested.
+
+## Improved generation of pkg-config files for static only libraries.
+
+Previously pkg-config files generated by the pkgconfig modules for static libraries
+with dependencies could only be used in a dependencies with `static: true`.
+
+Now the generated file contains the needed dependencies libraries directly within
+`Requires` and `Libs` for build static libraries passed via the `libraries` keyword
+argument.
+
+Projects that install both a static and a shared version of a library should use
+the result of [`both_libraries()`](Reference-manual.md#both_libraries) to the
+pkg-config file generator or use [`configure_file()`](Reference-manual.md#configure_file)
+for more complicated setups.
+
+## Improvements to pkgconfig module
+
+A `StaticLibrary` or `SharedLibrary` object can optionally be passed
+as first positional argument of the `generate()` method. If one is provided a
+default value will be provided for all required fields of the pc file:
+- `install_dir` is set to `pkgconfig` folder in the same location than the provided library.
+- `description` is set to the project's name followed by the library's name.
+- `name` is set to the library's name.
+
+Generating a .pc file is now as simple as:
+
+```
+pkgconfig.generate(mylib)
+```
+
+## pkgconfig.generate() requires parameters non-string arguments
+
+`pkgconfig.generate()` `requires:` and `requires_private:` keyword arguments
+now accept pkgconfig-dependencies and libraries that pkgconfig-files were
+generated for.
+
+## Generic python module
+
+Meson now has is a revamped and generic (python 2 and 3) version of the python3
+module. With [this new interface](Python-module.md), projects can now fully
+specify the version of python they want to build against / install sources to,
+and can do so against multiple major or minor versions in parallel.
+
+## test() now supports the `depends:` keyword argument
+
+Build targets and custom targets can be listed in the `depends:` keyword argument
+of test function. These targets will be built before test is run even if they have
+`build_by_default : false`.
diff --git a/docs/markdown/Release-notes-for-0.47.0.md b/docs/markdown/Release-notes-for-0.47.0.md
new file mode 100644
index 0000000..58d47ee
--- /dev/null
+++ b/docs/markdown/Release-notes-for-0.47.0.md
@@ -0,0 +1,23 @@
+---
+title: Release 0.47
+short-description: Release notes for 0.46 (preliminary)
+...
+
+# New features
+
+This page is a placeholder for the eventual release notes.
+
+Notable new features should come with release note updates. This is
+done by creating a file snippet called `snippets/featurename.md` and
+whose contents should look like this:
+
+ ## Feature name
+
+ A short description explaining the new feature and how it should be used.
+
+## Allow early return from a script
+
+Added the function `subdir_done()`. Its invocation exits the current script at
+the point of invocation. All previously invoked build targets and commands are
+build/executed. All following ones are ignored. If the current script was
+invoked via `subdir()` the parent script continues normally.
diff --git a/docs/markdown/Syntax.md b/docs/markdown/Syntax.md
index 01c8c6e..30eedf8 100644
--- a/docs/markdown/Syntax.md
+++ b/docs/markdown/Syntax.md
@@ -131,7 +131,8 @@ int main (int argc, char ** argv) {
}'''
```
-This can also be combined with the string formatting functionality
+These are raw strings that do not support the escape sequences listed above.
+These strings can also be combined with the string formatting functionality
described below.
#### String formatting
diff --git a/docs/markdown/Users.md b/docs/markdown/Users.md
index 558378c..0a30d9c 100644
--- a/docs/markdown/Users.md
+++ b/docs/markdown/Users.md
@@ -9,6 +9,7 @@ listed in the [`meson` GitHub topic](https://github.com/topics/meson).
- [AQEMU](https://github.com/tobimensch/aqemu), a Qt GUI for QEMU virtual machines, since version 0.9.3
- [Arduino sample project](https://github.com/jpakkane/mesonarduino)
+ - [bolt](https://gitlab.freedesktop.org/bolt/bolt) Userpsace daemon to enable security levels for Thunderboltâ„¢ 3 on Linux
- [Budgie Desktop](https://github.com/budgie-desktop/budgie-desktop), a desktop environment built on GNOME technologies
- [casync](https://github.com/systemd/casync), Content-Addressable Data Synchronization Tool
- [cinnamon-desktop](https://github.com/linuxmint/cinnamon-desktop), the cinnamon desktop library
diff --git a/docs/markdown/Wrap-dependency-system-manual.md b/docs/markdown/Wrap-dependency-system-manual.md
index d97fc9a..38e1ab2 100644
--- a/docs/markdown/Wrap-dependency-system-manual.md
+++ b/docs/markdown/Wrap-dependency-system-manual.md
@@ -93,9 +93,9 @@ revision=head
The format is straightforward. The only thing to note is the revision
element that can have one of two values. The first is `head` which
will cause Meson to track the master head (doing a repull whenever the
-build definition is altered). The second type is a commit hash. In
-this case Meson will use the commit specified (with `git checkout
-[hash id]`).
+build definition is altered). The second type is a commit hash or a
+tag. In this case Meson will use the commit specified (with `git
+checkout [hash/tag id]`).
Note that in this case you cannot specify an extra patch file to
use. The git repo must contain all necessary Meson build definitions.
diff --git a/docs/markdown/snippets/altered-logging.md b/docs/markdown/snippets/altered-logging.md
deleted file mode 100644
index 4ff9bb0..0000000
--- a/docs/markdown/snippets/altered-logging.md
+++ /dev/null
@@ -1,5 +0,0 @@
-## Log output slightly changed
-
-The format of some human-readable diagnostic messages has changed in
-minor ways. In case you are parsing these messages, you may need to
-adjust your code.
diff --git a/docs/markdown/snippets/armcc-cross.md b/docs/markdown/snippets/armcc-cross.md
deleted file mode 100644
index 668f0ab..0000000
--- a/docs/markdown/snippets/armcc-cross.md
+++ /dev/null
@@ -1,15 +0,0 @@
-## ARM compiler for C and CPP
-
-Cross-compilation is now supported for ARM targets using ARM compiler - ARMCC.
-The current implementation does not support shareable libraries.
-The default extension of the output is .axf.
-The environment path should be set properly for the ARM compiler executables.
-The '--cpu' option with the appropriate target type should be mentioned
-in the cross file as shown in the snippet below.
-
-```
-[properties]
-c_args = ['--cpu=Cortex-M0plus']
-cpp_args = ['--cpu=Cortex-M0plus']
-
-```
diff --git a/docs/markdown/snippets/both-libraries.md b/docs/markdown/snippets/both-libraries.md
deleted file mode 100644
index 1632f63..0000000
--- a/docs/markdown/snippets/both-libraries.md
+++ /dev/null
@@ -1,9 +0,0 @@
-## Building both shared and static libraries
-
-A new function `both_libraries()` has been added to build both shared and static
-libraries at the same time. Source files will be compiled only once and object
-files will be reused to build both shared and static libraries, unless
-`b_staticpic` user option or `pic` argument are set to false in which case
-sources will be compiled twice.
-
-The returned `buildtarget` object always represents the shared library.
diff --git a/docs/markdown/snippets/compiler-object-run_command.md b/docs/markdown/snippets/compiler-object-run_command.md
deleted file mode 100644
index 0308416..0000000
--- a/docs/markdown/snippets/compiler-object-run_command.md
+++ /dev/null
@@ -1,10 +0,0 @@
-## Compiler object can now be passed to run_command()
-
-This can be used to run the current compiler with the specified arguments
-to obtain additional information from it.
-One of the use cases is to get the location of development files for the
-GCC plugins:
-
- cc = meson.get_compiler('c')
- result = run_command(cc, '-print-file-name=plugin')
- plugin_dev_path = result.stdout().strip()
diff --git a/docs/markdown/snippets/d-options-for-meson-setup.md b/docs/markdown/snippets/d-options-for-meson-setup.md
deleted file mode 100644
index 37afbe0..0000000
--- a/docs/markdown/snippets/d-options-for-meson-setup.md
+++ /dev/null
@@ -1,6 +0,0 @@
-## Meson and meson configure now accept the same arguments
-
-Previously meson required that builtin arguments (like prefix) be passed as
-`--prefix` to `meson` and `-Dprefix` to `meson configure`. `meson` now accepts -D
-form like `meson configure` has. `meson configure` also accepts the `--prefix`
-form, like `meson` has.
diff --git a/docs/markdown/snippets/declare_dependency-link_whole.md b/docs/markdown/snippets/declare_dependency-link_whole.md
deleted file mode 100644
index 827b1f6..0000000
--- a/docs/markdown/snippets/declare_dependency-link_whole.md
+++ /dev/null
@@ -1,4 +0,0 @@
-## declare_dependency() supports link_whole
-
-`declare_dependency()` supports `link_whole` parameter.
-`link_whole` propagates to build target that uses dependency.
diff --git a/docs/markdown/snippets/del-old-names.md b/docs/markdown/snippets/del-old-names.md
deleted file mode 100644
index 5ac5873..0000000
--- a/docs/markdown/snippets/del-old-names.md
+++ /dev/null
@@ -1,7 +0,0 @@
-## Old command names are now errors
-
-Old executable names `mesonintrospect`, `mesonconf`, `mesonrewriter`
-and `mesontest` have been deprecated for a long time. Starting from
-this version they no longer do anything but instead always error
-out. All functionality is available as subcommands in the main `meson`
-binary.
diff --git a/docs/markdown/snippets/find-override.md b/docs/markdown/snippets/find-override.md
deleted file mode 100644
index ef3a4a2..0000000
--- a/docs/markdown/snippets/find-override.md
+++ /dev/null
@@ -1,37 +0,0 @@
-## Can override find_program
-
-It is now possible to override the result of `find_program` to point
-to a custom program you want. The overriding is global and applies to
-every subproject from there on. Here is how you would use it.
-
-In master project
-
-```meson
-subproject('mydep')
-```
-
-In the called subproject:
-
-```meson
-prog = find_program('my_custom_script')
-meson.override_find_program('mycodegen', prog)
-```
-
-In master project (or, in fact, any subproject):
-
-```meson
-genprog = find_program('mycodegen')
-```
-
-Now `genprog` points to the custom script. If the dependency had come
-from the system, then it would point to the system version.
-
-You can also use the return value of `configure_file()` to override
-a program in the same way as above:
-
-```meson
-prog_script = configure_file(input : 'script.sh.in',
- output : 'script.sh',
- configuration : cdata)
-meson.override_find_program('mycodegen', prog_script)
-```
diff --git a/docs/markdown/snippets/has-link-argument.md b/docs/markdown/snippets/has-link-argument.md
deleted file mode 100644
index 7beda63..0000000
--- a/docs/markdown/snippets/has-link-argument.md
+++ /dev/null
@@ -1,9 +0,0 @@
-## has_link_argument() and friends
-
-A new set of methods has been added on compiler objects to test if the linker
-supports given arguments.
-
-- `has_link_argument()`
-- `has_multi_link_arguments()`
-- `get_supported_link_arguments()`
-- `first_supported_link_argument()`
diff --git a/docs/markdown/snippets/improved-help.md b/docs/markdown/snippets/improved-help.md
deleted file mode 100644
index db7e852..0000000
--- a/docs/markdown/snippets/improved-help.md
+++ /dev/null
@@ -1,6 +0,0 @@
-## "meson help" now shows command line help
-
-Command line parsing is now less surprising. "meson help" is now
-equivalent to "meson --help" and "meson help <subcommand>" is
-equivalent to "meson <subcommand> --help", instead of creating a build
-directory called "help" in these cases.
diff --git a/docs/markdown/snippets/improved-meson-init.md b/docs/markdown/snippets/improved-meson-init.md
deleted file mode 100644
index ec17bc4..0000000
--- a/docs/markdown/snippets/improved-meson-init.md
+++ /dev/null
@@ -1,19 +0,0 @@
-## Autogeneration of simple meson.build files
-
-A feature to generate a meson.build file compiling given C/C++ source
-files into a single executable has been added to "meson init". By
-default, it will take all recognizable source files in the current
-directory. You can also specify a list of dependencies with the -d
-flag and automatically invoke a build with the -b flag to check if the
-code builds with those dependencies.
-
-For example,
-
-```meson
-meson init -fbd sdl2,gl
-```
-
-will look for C or C++ files in the current directory, generate a
-meson.build for them with the dependencies of sdl2 and gl and
-immediately try to build it, overwriting any previous meson.build and
-build directory.
diff --git a/docs/markdown/snippets/install_data-rename.md b/docs/markdown/snippets/install_data-rename.md
deleted file mode 100644
index 6378d0f..0000000
--- a/docs/markdown/snippets/install_data-rename.md
+++ /dev/null
@@ -1,11 +0,0 @@
-## install_data() supports rename
-
-`rename` parameter is used to change names of the installed files.
-In order to install
-- `file1.txt` into `share/myapp/dir1/data.txt`
-- `file2.txt` into `share/myapp/dir2/data.txt`
-```meson
-install_data(['file1.txt', 'file2.txt'],
- rename : ['dir1/data.txt', 'dir2/data.txt'],
- install_dir : 'share/myapp')
-```
diff --git a/docs/markdown/snippets/lcc.md b/docs/markdown/snippets/lcc.md
deleted file mode 100644
index 2ce300d..0000000
--- a/docs/markdown/snippets/lcc.md
+++ /dev/null
@@ -1,23 +0,0 @@
-## Support for lcc compiler for e2k (Elbrus) architecture
-
-In this version, a support for lcc compiler for Elbrus processors
-based on [e2k microarchitecture](https://en.wikipedia.org/wiki/Elbrus_2000)
-has been added.
-
-Examples of such CPUs:
-* [Elbrus-8S](https://en.wikipedia.org/wiki/Elbrus-8S);
-* Elbrus-4S;
-* [Elbrus-2S+](https://en.wikipedia.org/wiki/Elbrus-2S%2B).
-
-Such compiler have a similar behavior as gcc (basic option compatibility),
-but, in is not strictly compatible with gcc as of current version.
-
-Major differences as of version 1.21.22:
-* it does not support LTO and PCH;
-* it suffers from the same dependency file creation error as icc;
-* it has minor differences in output, especially version output;
-* it differently reacts to lchmod() detection;
-* some backend messages are produced in ru_RU.KOI8-R even if LANG=C;
-* its preprocessor treats some characters differently.
-
-So every noted difference is properly handled now in meson. \ No newline at end of file
diff --git a/docs/markdown/snippets/more-escape-sequences.md b/docs/markdown/snippets/more-escape-sequences.md
deleted file mode 100644
index 2894079..0000000
--- a/docs/markdown/snippets/more-escape-sequences.md
+++ /dev/null
@@ -1,17 +0,0 @@
-## String escape character update
-
-The strings (both single-quoted and triple-quoted) in meson has been taught the
-same set of escape sequences as in Python. It is therefore now possible to use
-arbitrary bytes in strings, like for example NUL (`\0`) and other ASCII control
-characters. See the chapter about *Strings* in *Syntax* for more details.
-
-Potential backwards compatibility issue: Any valid escape sequence according to
-the new rules will be interpreted as an escape sequence instead of the literal
-characters. Previously only single-quote strings supported escape sequences and
-the supported sequences were `\'`, `\\` and `\n`.
-
-The most likely breakage is usage of backslash-n in triple-quoted strings. It
-is now written in the same way as in single-quoted strings: `\\n` instead of
-`\n`. In general it is now recommended to escape any usage of backslash.
-However, backslash-c (`\c`), for example, is still backslash-c because it isn't
-a valid escape sequence.
diff --git a/docs/markdown/snippets/new-wrap-mode.md b/docs/markdown/snippets/new-wrap-mode.md
deleted file mode 100644
index e33dd83..0000000
--- a/docs/markdown/snippets/new-wrap-mode.md
+++ /dev/null
@@ -1,3 +0,0 @@
-A new wrap mode was added, `--wrap-mode=forcefallback`. When this is set,
-dependencies for which a fallback was provided will always use it, even
-if an external dependency exists and satisfies the version requirements.
diff --git a/docs/markdown/snippets/non-unique-target-names.md b/docs/markdown/snippets/non-unique-target-names.md
deleted file mode 100644
index 9b3f917..0000000
--- a/docs/markdown/snippets/non-unique-target-names.md
+++ /dev/null
@@ -1,9 +0,0 @@
-## Relaxing of target name requirements
-
-In earlier versions of Meson you could only have one target of a given name for each type.
-For example you could not have two executables named `foo`. This requirement is now
-relaxed so that you can have multiple targets with the same name, as long as they are in
-different subdirectories.
-
-Note that projects that have multiple targets with the same name can not be built with
-the `flat` layout or any backend that writes outputs in the same directory.
diff --git a/docs/markdown/snippets/openmp-dependency.md b/docs/markdown/snippets/openmp-dependency.md
deleted file mode 100644
index ad70011..0000000
--- a/docs/markdown/snippets/openmp-dependency.md
+++ /dev/null
@@ -1,6 +0,0 @@
-## Addition of OpenMP dependency
-
-An OpenMP dependency (`openmp`) has been added that encapsulates the various
-flags used by compilers to enable OpenMP and checks for the existence of the
-`omp.h` header. The `language` keyword may be passed to force the use of a
-specific compiler for the checks.
diff --git a/docs/markdown/snippets/partial-dependencies.md b/docs/markdown/snippets/partial-dependencies.md
deleted file mode 100644
index 8d2136a..0000000
--- a/docs/markdown/snippets/partial-dependencies.md
+++ /dev/null
@@ -1,25 +0,0 @@
-## Added new partial_dependency method to dependencies and libraries
-
-It is now possible to use only part of a dependency in a target. This allows,
-for example, to only use headers with convenience libraries to avoid linking
-to the same library multiple times.
-
-```meson
-
-dep = dependency('xcb')
-
-helper = static_library(
- 'helper',
- ['helper1.c', 'helper2.c'],
- dependencies : dep.partial_dependency(includes : true),
-]
-
-final = shared_library(
- 'final',
- ['final.c'],
- dependencyes : dep,
-)
-```
-
-A partial dependency will have the same name version as the full dependency it
-is derived from, as well as any values requested.
diff --git a/docs/markdown/snippets/pkg-config-fix-static-only.md b/docs/markdown/snippets/pkg-config-fix-static-only.md
deleted file mode 100644
index 31cd389..0000000
--- a/docs/markdown/snippets/pkg-config-fix-static-only.md
+++ /dev/null
@@ -1,12 +0,0 @@
-## Improved generation of pkg-config files for static only libraries.
-
-Previously pkg-config files generated by the pkgconfig modules for static libraries
-with dependencies could only be used in a dependencies with `static: true`.
-
-Now the generated file contains the needed dependencies libraries directly within
-`Requires` and `Libs` for build static libraries passed via the `libraries` keyword
-argument.
-
-Projects that install both a static and a shared version of a library should use
-the result of `both_libraries` to the pkg config file generator or use
-configure_file for more complicated setups.
diff --git a/docs/markdown/snippets/pkgconfig-generator.md b/docs/markdown/snippets/pkgconfig-generator.md
deleted file mode 100644
index 93920d3..0000000
--- a/docs/markdown/snippets/pkgconfig-generator.md
+++ /dev/null
@@ -1,14 +0,0 @@
-## Improvements to pkgconfig module
-
-A `StaticLibrary` or `SharedLibrary` object can optionally be passed
-as first positional argument of the `generate()` method. If one is provided a
-default value will be provided for all required fields of the pc file:
-- `install_dir` is set to `pkgconfig` folder in the same location than the provided library.
-- `description` is set to the project's name followed by the library's name.
-- `name` is set to the library's name.
-
-Generating a .pc file is now as simple as:
-
-```
-pkgconfig.generate(mylib)
-```
diff --git a/docs/markdown/snippets/pkgconfig-requires-non-string.md b/docs/markdown/snippets/pkgconfig-requires-non-string.md
deleted file mode 100644
index abf85b0..0000000
--- a/docs/markdown/snippets/pkgconfig-requires-non-string.md
+++ /dev/null
@@ -1,5 +0,0 @@
-## pkgconfig.generate() requires parameters non-string arguments
-
-`pkgconfig.generate()` `requires` and `requires_private` parameters
-accept pkgconfig-dependencies and libraries that pkgconfig-files were
-generated for.
diff --git a/docs/markdown/snippets/python-module.md b/docs/markdown/snippets/python-module.md
deleted file mode 100644
index c2e8138..0000000
--- a/docs/markdown/snippets/python-module.md
+++ /dev/null
@@ -1,6 +0,0 @@
-## Generic python module
-
-This is a revamped and generic (python 2 and 3) version of the python3
-module. With this new interface, projects can now fully specify the version
-of python they want to build against / install sources to, and can do so
-against multiple major or minor versions in parallel.
diff --git a/docs/sitemap.txt b/docs/sitemap.txt
index b439b69..46b3b6a 100644
--- a/docs/sitemap.txt
+++ b/docs/sitemap.txt
@@ -66,6 +66,7 @@ index.md
Shipping-prebuilt-binaries-as-wraps.md
fallback-wraptool.md
Release-notes.md
+ Release-notes-for-0.47.0.md
Release-notes-for-0.46.0.md
Release-notes-for-0.45.0.md
Release-notes-for-0.44.0.md
diff --git a/man/meson.1 b/man/meson.1
index 19ad737..b6f09de 100644
--- a/man/meson.1
+++ b/man/meson.1
@@ -1,4 +1,4 @@
-.TH MESON "1" "March 2018" "meson 0.45.0" "User Commands"
+.TH MESON "1" "April 2018" "meson 0.46.0" "User Commands"
.SH NAME
meson - a high productivity build system
.SH DESCRIPTION
diff --git a/man/mesonconf.1 b/man/mesonconf.1
index b189663..9ead6ae 100644
--- a/man/mesonconf.1
+++ b/man/mesonconf.1
@@ -1,4 +1,4 @@
-.TH MESONCONF "1" "March 2018" "mesonconf 0.45.0" "User Commands"
+.TH MESONCONF "1" "April 2018" "mesonconf 0.46.0" "User Commands"
.SH NAME
mesonconf - a tool to configure Meson builds
.SH DESCRIPTION
diff --git a/man/mesonintrospect.1 b/man/mesonintrospect.1
index 61aa381..3251299 100644
--- a/man/mesonintrospect.1
+++ b/man/mesonintrospect.1
@@ -1,4 +1,4 @@
-.TH MESONINTROSPECT "1" "March 2017" "mesonintrospect 0.45.0" "User Commands"
+.TH MESONINTROSPECT "1" "April 2018" "mesonintrospect 0.46.0" "User Commands"
.SH NAME
mesonintrospect - a tool to extract information about a Meson build
.SH DESCRIPTION
diff --git a/man/mesontest.1 b/man/mesontest.1
index 9a9f743..97f8f0e 100644
--- a/man/mesontest.1
+++ b/man/mesontest.1
@@ -1,4 +1,4 @@
-.TH MESON "1" "March 2018" "meson 0.45.0" "User Commands"
+.TH MESON "1" "April 2018" "meson 0.46.0" "User Commands"
.SH NAME
mesontest - test tool for the Meson build system
.SH DESCRIPTION
diff --git a/man/wraptool.1 b/man/wraptool.1
index 93ec457..9d3a056 100644
--- a/man/wraptool.1
+++ b/man/wraptool.1
@@ -1,4 +1,4 @@
-.TH WRAPTOOL "1" "March 2018" "meson 0.45.0" "User Commands"
+.TH WRAPTOOL "1" "April 2018" "meson 0.46.0" "User Commands"
.SH NAME
wraptool - source dependency downloader
.SH DESCRIPTION
diff --git a/manual tests/2 multiwrap/subprojects/libpng.wrap b/manual tests/2 multiwrap/subprojects/libpng.wrap
index fb34a89..283775c 100644
--- a/manual tests/2 multiwrap/subprojects/libpng.wrap
+++ b/manual tests/2 multiwrap/subprojects/libpng.wrap
@@ -1,10 +1,10 @@
[wrap-file]
-directory = libpng-1.6.17
+directory = libpng-1.6.34
-source_url = ftp://ftp.simplesystems.org/pub/libpng/png/src/history/libpng16/libpng-1.6.17.tar.xz
-source_filename = libpng-1.6.17.tar.xz
-source_hash = 98507b55fbe5cd43c51981f2924e4671fd81fe35d52dc53357e20f2c77fa5dfd
+source_url = ftp://ftp-osl.osuosl.org/pub/libpng/src/libpng16/libpng-1.6.34.tar.xz
+source_filename = libpng-1.6.34.tar.xz
+source_hash = 2f1e960d92ce3b3abd03d06dfec9637dfbd22febf107a536b44f7a47c60659f6
-patch_url = https://wrapdb.mesonbuild.com/v1/projects/libpng/1.6.17/6/get_zip
-patch_filename = libpng-1.6.17-6-wrap.zip
-patch_hash = 8bd272e28e6ae84691935e84bca9f5eb02632221e6faccf427eb71bf745a7295
+patch_url = https://wrapdb.mesonbuild.com/v1/projects/libpng/1.6.34/1/get_zip
+patch_filename = libpng-1.6.34-1-wrap.zip
+patch_hash = 2123806eba8180c164e33a210f2892bbeb2473b69e56aecc786574e9221e6f20
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 694700e..5a401fe 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -206,6 +206,8 @@ class Backend:
return os.path.join(self.get_target_private_dir(target), src)
def get_unity_source_file(self, target, suffix):
+ # There is a potential conflict here, but it is unlikely that
+ # anyone both enables unity builds and has a file called foo-unity.cpp.
osrc = target.name + '-unity.' + suffix
return mesonlib.File.from_built_file(self.get_target_private_dir(target), osrc)
@@ -239,8 +241,11 @@ class Backend:
os.path.join('dummyprefixdir', fromdir))
def flatten_object_list(self, target, proj_dir_to_build_root=''):
+ return self._flatten_object_list(target, target.get_objects(), proj_dir_to_build_root)
+
+ def _flatten_object_list(self, target, objects, proj_dir_to_build_root):
obj_list = []
- for obj in target.get_objects():
+ for obj in objects:
if isinstance(obj, str):
o = os.path.join(proj_dir_to_build_root,
self.build_to_src, target.get_subdir(), obj)
@@ -248,7 +253,9 @@ class Backend:
elif isinstance(obj, mesonlib.File):
obj_list.append(obj.rel_to_builddir(self.build_to_src))
elif isinstance(obj, build.ExtractedObjects):
- obj_list += self.determine_ext_objs(target, obj, proj_dir_to_build_root)
+ if obj.recursive:
+ obj_list += self._flatten_object_list(obj.target, obj.objlist, proj_dir_to_build_root)
+ obj_list += self.determine_ext_objs(obj, proj_dir_to_build_root)
else:
raise MesonException('Unknown data type in object list.')
return obj_list
@@ -361,15 +368,11 @@ class Backend:
result += [rp]
return result
- def object_filename_from_source(self, target, source, is_unity):
+ def object_filename_from_source(self, target, source):
assert isinstance(source, mesonlib.File)
build_dir = self.environment.get_build_dir()
rel_src = source.rel_to_builddir(self.build_to_src)
- if (not self.environment.is_source(rel_src) or
- self.environment.is_header(rel_src)) and not is_unity:
- return None
-
# foo.vala files compile down to foo.c and then foo.c.o, not foo.vala.o
if rel_src.endswith(('.vala', '.gs')):
# See description in generate_vala_compile for this logic.
@@ -379,8 +382,6 @@ class Backend:
rel_src = os.path.relpath(rel_src, self.get_target_private_dir(target))
else:
rel_src = os.path.basename(rel_src)
- if is_unity:
- return 'meson-generated_' + rel_src[:-5] + '.c.' + self.environment.get_object_suffix()
# A meson- prefixed directory is reserved; hopefully no-one creates a file name with such a weird prefix.
source = 'meson-generated_' + rel_src[:-5] + '.c'
elif source.is_built:
@@ -398,24 +399,10 @@ class Backend:
os.path.join(self.environment.get_source_dir(), target.get_subdir()))
return source.replace('/', '_').replace('\\', '_') + '.' + self.environment.get_object_suffix()
- def determine_ext_objs(self, target, extobj, proj_dir_to_build_root):
+ def determine_ext_objs(self, extobj, proj_dir_to_build_root):
result = []
- targetdir = self.get_target_private_dir(extobj.target)
- # With unity builds, there's just one object that contains all the
- # sources, and we only support extracting all the objects in this mode,
- # so just return that.
- if self.is_unity(target):
- comp = get_compiler_for_source(extobj.target.compilers.values(),
- extobj.srclist[0])
- # There is a potential conflict here, but it is unlikely that
- # anyone both enables unity builds and has a file called foo-unity.cpp.
- osrc = self.get_unity_source_file(extobj.target,
- comp.get_default_suffix())
- objname = self.object_filename_from_source(extobj.target, osrc, True)
- objname = objname.replace('/', '_').replace('\\', '_')
- objpath = os.path.join(proj_dir_to_build_root, targetdir, objname)
- return [objpath]
+ # Merge sources and generated sources
sources = list(extobj.srclist)
for gensrc in extobj.genlist:
for s in gensrc.get_outputs():
@@ -423,11 +410,30 @@ class Backend:
dirpart, fnamepart = os.path.split(path)
sources.append(File(True, dirpart, fnamepart))
+ # Filter out headers and all non-source files
+ sources = [s for s in sources if self.environment.is_source(s) and not self.environment.is_header(s)]
+
+ # extobj could contain only objects and no sources
+ if not sources:
+ return result
+
+ targetdir = self.get_target_private_dir(extobj.target)
+
+ # With unity builds, there's just one object that contains all the
+ # sources, and we only support extracting all the objects in this mode,
+ # so just return that.
+ if self.is_unity(extobj.target):
+ compsrcs = classify_unity_sources(extobj.target.compilers.values(), sources)
+ sources = []
+ for comp in compsrcs.keys():
+ osrc = self.get_unity_source_file(extobj.target,
+ comp.get_default_suffix())
+ sources.append(osrc)
+
for osrc in sources:
- objname = self.object_filename_from_source(extobj.target, osrc, False)
- if objname:
- objpath = os.path.join(proj_dir_to_build_root, targetdir, objname)
- result.append(objpath)
+ objname = self.object_filename_from_source(extobj.target, osrc)
+ objpath = os.path.join(proj_dir_to_build_root, targetdir, objname)
+ result.append(objpath)
return result
@@ -721,6 +727,9 @@ class Backend:
if not isinstance(arg, (build.CustomTarget, build.BuildTarget)):
continue
result[arg.get_id()] = arg
+ for dep in t.depends:
+ assert isinstance(dep, (build.CustomTarget, build.BuildTarget))
+ result[dep.get_id()] = dep
return result
def get_custom_target_provided_libraries(self, target):
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index bc3a8ef..eeac388 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -252,6 +252,8 @@ int dummy;
# Get all generated headers. Any source file might need them so
# we need to add an order dependency to them.
def get_generated_headers(self, target):
+ if hasattr(target, 'cached_generated_headers'):
+ return target.cached_generated_headers
header_deps = []
# XXX: Why don't we add deps to CustomTarget headers here?
for genlist in target.get_generated_sources():
@@ -267,6 +269,7 @@ int dummy;
for dep in itertools.chain(target.link_targets, target.link_whole_targets):
if isinstance(dep, (build.StaticLibrary, build.SharedLibrary)):
header_deps += self.get_generated_headers(dep)
+ target.cached_generated_headers = header_deps
return header_deps
def get_target_generated_sources(self, target):
@@ -1637,7 +1640,7 @@ int dummy;
outfile.write(description)
outfile.write('\n')
- def generate_fortran_dep_hack(self, outfile):
+ def generate_fortran_dep_hack(self, outfile, crstr):
if mesonlib.is_windows():
cmd = 'cmd /C ""'
else:
@@ -1645,13 +1648,13 @@ int dummy;
template = '''# Workaround for these issues:
# https://groups.google.com/forum/#!topic/ninja-build/j-2RfBIOd_8
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485
-rule FORTRAN_DEP_HACK
+rule FORTRAN_DEP_HACK%s
command = %s
description = Dep hack
restat = 1
'''
- outfile.write(template % cmd)
+ outfile.write(template % (crstr, cmd))
def generate_llvm_ir_compile_rule(self, compiler, is_cross, outfile):
if getattr(self, 'created_llvm_ir_rule', False):
@@ -1704,12 +1707,12 @@ rule FORTRAN_DEP_HACK
if not is_cross:
self.generate_swift_compile_rules(compiler, outfile)
return
- if langname == 'fortran':
- self.generate_fortran_dep_hack(outfile)
if is_cross:
crstr = '_CROSS'
else:
crstr = ''
+ if langname == 'fortran':
+ self.generate_fortran_dep_hack(outfile, crstr)
rule = 'rule %s%s_COMPILER\n' % (langname, crstr)
depargs = compiler.get_dependency_gen_args('$out', '$DEPFILE')
quoted_depargs = []
@@ -2203,7 +2206,7 @@ rule FORTRAN_DEP_HACK
raise AssertionError('BUG: broken generated source file handling for {!r}'.format(src))
else:
raise InvalidArguments('Invalid source type: {!r}'.format(src))
- obj_basename = self.object_filename_from_source(target, src, self.is_unity(target))
+ obj_basename = self.object_filename_from_source(target, src)
rel_obj = os.path.join(self.get_target_private_dir(target), obj_basename)
dep_file = compiler.depfile_for_object(rel_obj)
@@ -2245,7 +2248,7 @@ rule FORTRAN_DEP_HACK
modfile = os.path.join(self.get_target_private_dir(target),
compiler.module_name_to_filename(modname))
if srcfile == src:
- depelem = NinjaBuildElement(self.all_outputs, modfile, 'FORTRAN_DEP_HACK', rel_obj)
+ depelem = NinjaBuildElement(self.all_outputs, modfile, 'FORTRAN_DEP_HACK' + crstr, rel_obj)
depelem.write(outfile)
commands += compiler.get_module_outdir_args(self.get_target_private_dir(target))
@@ -2353,10 +2356,11 @@ rule FORTRAN_DEP_HACK
return pch_objects
def generate_shsym(self, outfile, target):
- target_name = self.get_target_filename(target)
+ target_name = target.get_filename()
+ target_file = self.get_target_filename(target)
targetdir = self.get_target_private_dir(target)
symname = os.path.join(targetdir, target_name + '.symbols')
- elem = NinjaBuildElement(self.all_outputs, symname, 'SHSYM', target_name)
+ elem = NinjaBuildElement(self.all_outputs, symname, 'SHSYM', target_file)
if self.environment.is_cross_build() and self.environment.cross_info.need_cross_compiler():
elem.add_item('CROSS', '--cross-host=' + self.environment.cross_info.config['host_machine']['system'])
elem.write(outfile)
@@ -2608,7 +2612,7 @@ rule FORTRAN_DEP_HACK
def get_dependency_filename(self, t):
if isinstance(t, build.SharedLibrary):
- return os.path.join(self.get_target_private_dir(t), self.get_target_filename(t) + '.symbols')
+ return os.path.join(self.get_target_private_dir(t), t.get_filename() + '.symbols')
elif isinstance(t, mesonlib.File):
if t.is_built:
return t.relative_name()
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index 3a12b9b..09822ed 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -1074,7 +1074,7 @@ class Vs2010Backend(backends.Backend):
self.add_additional_options(lang, inc_cl, file_args)
self.add_preprocessor_defines(lang, inc_cl, file_defines)
self.add_include_dirs(lang, inc_cl, file_inc_dirs)
- ET.SubElement(inc_cl, 'ObjectFileName').text = "$(IntDir)" + self.object_filename_from_source(target, s, False)
+ ET.SubElement(inc_cl, 'ObjectFileName').text = "$(IntDir)" + self.object_filename_from_source(target, s)
for s in gen_src:
inc_cl = ET.SubElement(inc_src, 'CLCompile', Include=s)
lang = Vs2010Backend.lang_from_source_file(s)
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index e707053..352f857 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -213,40 +213,49 @@ class ExtractedObjects:
'''
Holds a list of sources for which the objects must be extracted
'''
- def __init__(self, target, srclist, genlist, is_unity):
+ def __init__(self, target, srclist=[], genlist=[], objlist=[], recursive=True):
self.target = target
+ self.recursive = recursive
self.srclist = srclist
self.genlist = genlist
- if is_unity:
+ self.objlist = objlist
+ if self.target.is_unity:
self.check_unity_compatible()
def __repr__(self):
r = '<{0} {1!r}: {2}>'
return r.format(self.__class__.__name__, self.target.name, self.srclist)
+ def classify_all_sources(self, sources, generated_sources):
+ # Merge sources and generated sources
+ sources = list(sources)
+ for gensrc in generated_sources:
+ for s in gensrc.get_outputs():
+ # We cannot know the path where this source will be generated,
+ # but all we need here is the file extension to determine the
+ # compiler.
+ sources.append(s)
+
+ # Filter out headers and all non-source files
+ sources = [s for s in sources if environment.is_source(s) and not environment.is_header(s)]
+
+ return classify_unity_sources(self.target.compilers.values(), sources)
+
def check_unity_compatible(self):
# Figure out if the extracted object list is compatible with a Unity
# build. When we're doing a Unified build, we go through the sources,
# and create a single source file from each subset of the sources that
# can be compiled with a specific compiler. Then we create one object
- # from each unified source file.
- # If the list of sources for which we want objects is the same as the
- # list of sources that go into each unified build, we're good.
- srclist_set = set(self.srclist)
- # Objects for all the sources are required, so we're compatible
- if srclist_set == set(self.target.sources):
- return
- # Check if the srclist is a subset (of the target's sources) that is
- # going to form a unified source file and a single object
- compsrcs = classify_unity_sources(self.target.compilers.values(),
- self.target.sources)
- for srcs in compsrcs.values():
- if srclist_set == set(srcs):
- return
- msg = 'Single object files can not be extracted in Unity builds. ' \
- 'You can only extract all the object files at once.'
- raise MesonException(msg)
+ # from each unified source file. So for each compiler we can either
+ # extra all its sources or none.
+ cmpsrcs = self.classify_all_sources(self.target.sources, self.target.generated)
+ extracted_cmpsrcs = self.classify_all_sources(self.srclist, self.genlist)
+ for comp, srcs in extracted_cmpsrcs.items():
+ if set(srcs) != set(cmpsrcs[comp]):
+ raise MesonException('Single object files can not be extracted '
+ 'in Unity builds. You can only extract all '
+ 'the object files for each compiler at once.')
class EnvironmentVariables:
def __init__(self):
@@ -637,13 +646,11 @@ class BuildTarget(Target):
if src not in self.sources:
raise MesonException('Tried to extract unknown source %s.' % src)
obj_src.append(src)
- return ExtractedObjects(self, obj_src, [], self.is_unity)
+ return ExtractedObjects(self, obj_src)
- def extract_all_objects(self):
- # FIXME: We should add support for transitive extract_objects()
- if self.objects:
- raise MesonException('Cannot extract objects from a target that itself has extracted objects')
- return ExtractedObjects(self, self.sources, self.generated, self.is_unity)
+ def extract_all_objects(self, recursive=True):
+ return ExtractedObjects(self, self.sources, self.generated, self.objects,
+ recursive)
def get_all_link_deps(self):
return self.get_transitive_link_deps()
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index 1230e3f..91c9a16 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -329,7 +329,7 @@ class CCompiler(Compiler):
def _build_wrapper(self, code, env, extra_args, dependencies=None, mode='compile', want_output=False):
args = self._get_compiler_check_args(env, extra_args, dependencies, mode)
- return self.compile(code, args.to_native(), mode, want_output=want_output)
+ return self.compile(code, args, mode, want_output=want_output)
def links(self, code, env, extra_args=None, dependencies=None):
return self.compiles(code, env, extra_args, dependencies, mode='link')
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 4887125..3dfb429 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -22,7 +22,7 @@ from .mesonlib import default_libdir, default_libexecdir, default_prefix
import ast
import argparse
-version = '0.46.0.dev1'
+version = '0.47.0.dev1'
backendlist = ['ninja', 'vs', 'vs2010', 'vs2015', 'vs2017', 'xcode']
default_yielding = False
diff --git a/mesonbuild/dependencies/__init__.py b/mesonbuild/dependencies/__init__.py
index 1c67311..5259c5b 100644
--- a/mesonbuild/dependencies/__init__.py
+++ b/mesonbuild/dependencies/__init__.py
@@ -15,7 +15,7 @@
from .boost import BoostDependency
from .base import ( # noqa: F401
Dependency, DependencyException, DependencyMethods, ExternalProgram, NonExistingExternalProgram,
- ExternalDependency, ExternalLibrary, ExtraFrameworkDependency, InternalDependency,
+ ExternalDependency, NotFoundDependency, ExternalLibrary, ExtraFrameworkDependency, InternalDependency,
PkgConfigDependency, find_external_dependency, get_dep_identifier, packages, _packages_accept_language)
from .dev import GMockDependency, GTestDependency, LLVMDependency, ValgrindDependency
from .misc import (MPIDependency, OpenMPDependency, Python3Dependency, ThreadDependency, PcapDependency, CupsDependency, LibWmfDependency)
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index 27a5fcb..0114a14 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -257,6 +257,14 @@ class ExternalDependency(Dependency):
return new
+class NotFoundDependency(Dependency):
+ def __init__(self, environment):
+ super().__init__('not-found', {})
+ self.env = environment
+ self.name = 'not-found'
+ self.is_found = False
+
+
class ConfigToolDependency(ExternalDependency):
"""Class representing dependencies found using a config tool."""
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index c7841a8..c948778 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -23,9 +23,9 @@ from .wrap import wrap, WrapMode
from . import mesonlib
from .mesonlib import FileMode, Popen_safe, listify, extract_as_list, has_path_sep
from .dependencies import ExternalProgram
-from .dependencies import InternalDependency, Dependency, DependencyException
+from .dependencies import InternalDependency, Dependency, NotFoundDependency, DependencyException
from .interpreterbase import InterpreterBase
-from .interpreterbase import check_stringlist, noPosargs, noKwargs, stringArgs, permittedKwargs, permittedMethodKwargs
+from .interpreterbase import check_stringlist, noPosargs, noKwargs, stringArgs, permittedKwargs
from .interpreterbase import InterpreterException, InvalidArguments, InvalidCode, SubdirDoneRequest
from .interpreterbase import InterpreterObject, MutableInterpreterObject, Disabler
from .modules import ModuleReturnValue
@@ -37,6 +37,10 @@ from pathlib import PurePath
import importlib
+permitted_method_kwargs = {
+ 'partial_dependency': {'compile_args', 'link_args', 'links', 'includes',
+ 'sources'},
+}
def stringifyUserArguments(args):
if isinstance(args, list):
@@ -66,15 +70,23 @@ class TryRunResultHolder(InterpreterObject):
'stderr': self.stderr_method,
})
+ @noPosargs
+ @permittedKwargs({})
def returncode_method(self, args, kwargs):
return self.res.returncode
+ @noPosargs
+ @permittedKwargs({})
def compiled_method(self, args, kwargs):
return self.res.compiled
+ @noPosargs
+ @permittedKwargs({})
def stdout_method(self, args, kwargs):
return self.res.stdout
+ @noPosargs
+ @permittedKwargs({})
def stderr_method(self, args, kwargs):
return self.res.stderr
@@ -116,12 +128,18 @@ class RunProcess(InterpreterObject):
except FileNotFoundError:
raise InterpreterException('Could not execute command "%s".' % ' '.join(command_array))
+ @noPosargs
+ @permittedKwargs({})
def returncode_method(self, args, kwargs):
return self.returncode
+ @noPosargs
+ @permittedKwargs({})
def stdout_method(self, args, kwargs):
return self.stdout
+ @noPosargs
+ @permittedKwargs({})
def stderr_method(self, args, kwargs):
return self.stderr
@@ -146,7 +164,6 @@ class EnvironmentVariablesHolder(MutableInterpreterObject, ObjectHolder):
repr_str = "<{0}: {1}>"
return repr_str.format(self.__class__.__name__, self.held_object.envvars)
- @stringArgs
def add_var(self, method, args, kwargs):
if not isinstance(kwargs.get("separator", ""), str):
raise InterpreterException("EnvironmentVariablesHolder methods 'separator'"
@@ -157,12 +174,18 @@ class EnvironmentVariablesHolder(MutableInterpreterObject, ObjectHolder):
" following one are values")
self.held_object.envvars.append((method, args[0], args[1:], kwargs))
+ @stringArgs
+ @permittedKwargs({'separator'})
def set_method(self, args, kwargs):
self.add_var(self.held_object.set, args, kwargs)
+ @stringArgs
+ @permittedKwargs({'separator'})
def append_method(self, args, kwargs):
self.add_var(self.held_object.append, args, kwargs)
+ @stringArgs
+ @permittedKwargs({'separator'})
def prepend_method(self, args, kwargs):
self.add_var(self.held_object.prepend, args, kwargs)
@@ -278,17 +301,24 @@ class DependencyHolder(InterpreterObject, ObjectHolder):
'partial_dependency': self.partial_dependency_method,
})
+ @noPosargs
+ @permittedKwargs({})
def type_name_method(self, args, kwargs):
return self.held_object.type_name
+ @noPosargs
+ @permittedKwargs({})
def found_method(self, args, kwargs):
if self.held_object.type_name == 'internal':
return True
return self.held_object.found()
+ @noPosargs
+ @permittedKwargs({})
def version_method(self, args, kwargs):
return self.held_object.get_version()
+ @permittedKwargs({'define_variable'})
def pkgconfig_method(self, args, kwargs):
args = listify(args)
if len(args) != 1:
@@ -298,6 +328,7 @@ class DependencyHolder(InterpreterObject, ObjectHolder):
raise InterpreterException('Variable name must be a string.')
return self.held_object.get_pkgconfig_variable(varname, kwargs)
+ @permittedKwargs({})
def configtool_method(self, args, kwargs):
args = listify(args)
if len(args) != 1:
@@ -307,9 +338,9 @@ class DependencyHolder(InterpreterObject, ObjectHolder):
raise InterpreterException('Variable name must be a string.')
return self.held_object.get_configtool_variable(varname)
+ @noPosargs
+ @permittedKwargs(permitted_method_kwargs['partial_dependency'])
def partial_dependency_method(self, args, kwargs):
- if args:
- raise InterpreterException('partial_dependency takes no positional arguments')
return DependencyHolder(self.held_object.get_partial_dependency(**kwargs))
class InternalDependencyHolder(InterpreterObject, ObjectHolder):
@@ -321,15 +352,19 @@ class InternalDependencyHolder(InterpreterObject, ObjectHolder):
'partial_dependency': self.partial_dependency_method,
})
+ @noPosargs
+ @permittedKwargs({})
def found_method(self, args, kwargs):
return True
+ @noPosargs
+ @permittedKwargs({})
def version_method(self, args, kwargs):
return self.held_object.get_version()
+ @noPosargs
+ @permittedKwargs(permitted_method_kwargs['partial_dependency'])
def partial_dependency_method(self, args, kwargs):
- if args:
- raise InterpreterException('get_partial_dependency takes no positional arguments')
return DependencyHolder(self.held_object.get_partial_dependency(**kwargs))
class ExternalProgramHolder(InterpreterObject, ObjectHolder):
@@ -339,9 +374,13 @@ class ExternalProgramHolder(InterpreterObject, ObjectHolder):
self.methods.update({'found': self.found_method,
'path': self.path_method})
+ @noPosargs
+ @permittedKwargs({})
def found_method(self, args, kwargs):
return self.found()
+ @noPosargs
+ @permittedKwargs({})
def path_method(self, args, kwargs):
return self.held_object.get_path()
@@ -365,6 +404,8 @@ class ExternalLibraryHolder(InterpreterObject, ObjectHolder):
def found(self):
return self.held_object.found()
+ @noPosargs
+ @permittedKwargs({})
def found_method(self, args, kwargs):
return self.found()
@@ -380,9 +421,9 @@ class ExternalLibraryHolder(InterpreterObject, ObjectHolder):
def get_exe_args(self):
return self.held_object.get_exe_args()
+ @noPosargs
+ @permittedKwargs(permitted_method_kwargs['partial_dependency'])
def partial_dependency_method(self, args, kwargs):
- if args:
- raise InterpreterException('partial_dependency takes no positional arguments')
return DependencyHolder(self.held_object.get_partial_dependency(**kwargs))
class GeneratorHolder(InterpreterObject, ObjectHolder):
@@ -392,6 +433,7 @@ class GeneratorHolder(InterpreterObject, ObjectHolder):
ObjectHolder.__init__(self, build.Generator(args, kwargs))
self.methods.update({'process': self.process_method})
+ @permittedKwargs({'extra_args', 'preserve_path_from'})
def process_method(self, args, kwargs):
extras = mesonlib.stringlistify(kwargs.get('extra_args', []))
if 'preserve_path_from' in kwargs:
@@ -439,15 +481,23 @@ class BuildMachine(InterpreterObject, ObjectHolder):
'endian': self.endian_method,
})
+ @noPosargs
+ @permittedKwargs({})
def cpu_family_method(self, args, kwargs):
return self.held_object.cpu_family
+ @noPosargs
+ @permittedKwargs({})
def cpu_method(self, args, kwargs):
return self.held_object.cpu
+ @noPosargs
+ @permittedKwargs({})
def system_method(self, args, kwargs):
return self.held_object.system
+ @noPosargs
+ @permittedKwargs({})
def endian_method(self, args, kwargs):
return self.held_object.endian
@@ -473,15 +523,23 @@ class CrossMachineInfo(InterpreterObject, ObjectHolder):
'endian': self.endian_method,
})
+ @noPosargs
+ @permittedKwargs({})
def cpu_family_method(self, args, kwargs):
return self.held_object.cpu_family
+ @noPosargs
+ @permittedKwargs({})
def cpu_method(self, args, kwargs):
return self.held_object.cpu
+ @noPosargs
+ @permittedKwargs({})
def system_method(self, args, kwargs):
return self.held_object.system
+ @noPosargs
+ @permittedKwargs({})
def endian_method(self, args, kwargs):
return self.held_object.endian
@@ -592,24 +650,41 @@ class BuildTargetHolder(TargetHolder):
def is_cross(self):
return self.held_object.is_cross()
+ @noPosargs
+ @permittedKwargs({})
def private_dir_include_method(self, args, kwargs):
return IncludeDirsHolder(build.IncludeDirs('', [], False,
[self.interpreter.backend.get_target_private_dir(self.held_object)]))
+ @noPosargs
+ @permittedKwargs({})
def full_path_method(self, args, kwargs):
return self.interpreter.backend.get_target_filename_abs(self.held_object)
+ @noPosargs
+ @permittedKwargs({})
def outdir_method(self, args, kwargs):
return self.interpreter.backend.get_target_dir(self.held_object)
+ @permittedKwargs({})
def extract_objects_method(self, args, kwargs):
gobjs = self.held_object.extract_objects(args)
return GeneratedObjectsHolder(gobjs)
+ @noPosargs
+ @permittedKwargs({'recursive'})
def extract_all_objects_method(self, args, kwargs):
- gobjs = self.held_object.extract_all_objects()
+ recursive = kwargs.get('recursive', False)
+ gobjs = self.held_object.extract_all_objects(recursive)
+ if gobjs.objlist and 'recursive' not in kwargs:
+ mlog.warning('extract_all_objects called without setting recursive '
+ 'keyword argument. Meson currently defaults to '
+ 'non-recursive to maintain backward compatibility but '
+ 'the default will be changed in the future.')
return GeneratedObjectsHolder(gobjs)
+ @noPosargs
+ @permittedKwargs({})
def get_id_method(self, args, kwargs):
return self.held_object.get_id()
@@ -644,9 +719,13 @@ class BothLibrariesHolder(BuildTargetHolder):
h2 = self.static_holder.held_object
return r.format(self.__class__.__name__, h1.get_id(), h1.filename, h2.get_id(), h2.filename)
+ @noPosargs
+ @permittedKwargs({})
def get_shared_lib_method(self, args, kwargs):
return self.shared_holder
+ @noPosargs
+ @permittedKwargs({})
def get_static_lib_method(self, args, kwargs):
return self.static_holder
@@ -674,6 +753,8 @@ class CustomTargetHolder(TargetHolder):
h = self.held_object
return r.format(self.__class__.__name__, h.get_id(), h.command)
+ @noPosargs
+ @permittedKwargs({})
def full_path_method(self, args, kwargs):
return self.interpreter.backend.get_target_filename_abs(self.held_object)
@@ -697,12 +778,14 @@ class RunTargetHolder(InterpreterObject, ObjectHolder):
return r.format(self.__class__.__name__, h.get_id(), h.command)
class Test(InterpreterObject):
- def __init__(self, name, project, suite, exe, is_parallel, cmd_args, env, should_fail, timeout, workdir):
+ def __init__(self, name, project, suite, exe, depends, is_parallel,
+ cmd_args, env, should_fail, timeout, workdir):
InterpreterObject.__init__(self)
self.name = name
self.suite = suite
self.project_name = project
self.exe = exe
+ self.depends = depends
self.is_parallel = is_parallel
self.cmd_args = cmd_args
self.env = env
@@ -724,6 +807,7 @@ class SubprojectHolder(InterpreterObject, ObjectHolder):
self.methods.update({'get_variable': self.get_variable_method,
})
+ @permittedKwargs({})
def get_variable_method(self, args, kwargs):
if len(args) != 1:
raise InterpreterException('Get_variable takes one argument.')
@@ -768,11 +852,13 @@ class CompilerHolder(InterpreterObject):
'symbols_have_underscore_prefix': self.symbols_have_underscore_prefix_method,
})
- @permittedMethodKwargs({})
+ @noPosargs
+ @permittedKwargs({})
def version_method(self, args, kwargs):
return self.compiler.version
- @permittedMethodKwargs({})
+ @noPosargs
+ @permittedKwargs({})
def cmd_array_method(self, args, kwargs):
return self.compiler.exelist
@@ -812,7 +898,7 @@ class CompilerHolder(InterpreterObject):
deps = final_deps
return deps
- @permittedMethodKwargs({
+ @permittedKwargs({
'prefix',
'args',
'dependencies',
@@ -831,7 +917,7 @@ class CompilerHolder(InterpreterObject):
mlog.log('Checking for alignment of "', mlog.bold(typename), '": ', result, sep='')
return result
- @permittedMethodKwargs({
+ @permittedKwargs({
'name',
'no_builtin_args',
'include_directories',
@@ -863,11 +949,13 @@ class CompilerHolder(InterpreterObject):
mlog.log('Checking if "', mlog.bold(testname), '" runs: ', h, sep='')
return TryRunResultHolder(result)
- @permittedMethodKwargs({})
+ @noPosargs
+ @permittedKwargs({})
def get_id_method(self, args, kwargs):
return self.compiler.get_id()
- @permittedMethodKwargs({})
+ @noPosargs
+ @permittedKwargs({})
def symbols_have_underscore_prefix_method(self, args, kwargs):
'''
Check if the compiler prefixes _ (underscore) to global C symbols
@@ -875,7 +963,8 @@ class CompilerHolder(InterpreterObject):
'''
return self.compiler.symbols_have_underscore_prefix(self.environment)
- @permittedMethodKwargs({})
+ @noPosargs
+ @permittedKwargs({})
def unittest_args_method(self, args, kwargs):
'''
This function is deprecated and should not be used.
@@ -886,7 +975,7 @@ class CompilerHolder(InterpreterObject):
build_to_src = os.path.relpath(self.environment.get_source_dir(), self.environment.get_build_dir())
return self.compiler.get_feature_args({'unittest': 'true'}, build_to_src)
- @permittedMethodKwargs({
+ @permittedKwargs({
'prefix',
'no_builtin_args',
'include_directories',
@@ -914,7 +1003,7 @@ class CompilerHolder(InterpreterObject):
'" has member "', mlog.bold(membername), '": ', hadtxt, sep='')
return had
- @permittedMethodKwargs({
+ @permittedKwargs({
'prefix',
'no_builtin_args',
'include_directories',
@@ -941,7 +1030,7 @@ class CompilerHolder(InterpreterObject):
'" has members ', members, ': ', hadtxt, sep='')
return had
- @permittedMethodKwargs({
+ @permittedKwargs({
'prefix',
'no_builtin_args',
'include_directories',
@@ -966,7 +1055,7 @@ class CompilerHolder(InterpreterObject):
mlog.log('Checking for function "', mlog.bold(funcname), '": ', hadtxt, sep='')
return had
- @permittedMethodKwargs({
+ @permittedKwargs({
'prefix',
'no_builtin_args',
'include_directories',
@@ -991,7 +1080,7 @@ class CompilerHolder(InterpreterObject):
mlog.log('Checking for type "', mlog.bold(typename), '": ', hadtxt, sep='')
return had
- @permittedMethodKwargs({
+ @permittedKwargs({
'prefix',
'low',
'high',
@@ -1024,7 +1113,7 @@ class CompilerHolder(InterpreterObject):
mlog.log('Computing int of "%s": %d' % (expression, res))
return res
- @permittedMethodKwargs({
+ @permittedKwargs({
'prefix',
'no_builtin_args',
'include_directories',
@@ -1045,7 +1134,7 @@ class CompilerHolder(InterpreterObject):
mlog.log('Checking for size of "%s": %d' % (element, esize))
return esize
- @permittedMethodKwargs({
+ @permittedKwargs({
'prefix',
'no_builtin_args',
'include_directories',
@@ -1066,7 +1155,7 @@ class CompilerHolder(InterpreterObject):
mlog.log('Fetching value of define "%s": %s' % (element, value))
return value
- @permittedMethodKwargs({
+ @permittedKwargs({
'name',
'no_builtin_args',
'include_directories',
@@ -1096,7 +1185,7 @@ class CompilerHolder(InterpreterObject):
mlog.log('Checking if "', mlog.bold(testname), '" compiles: ', h, sep='')
return result
- @permittedMethodKwargs({
+ @permittedKwargs({
'name',
'no_builtin_args',
'include_directories',
@@ -1126,7 +1215,7 @@ class CompilerHolder(InterpreterObject):
mlog.log('Checking if "', mlog.bold(testname), '" links: ', h, sep='')
return result
- @permittedMethodKwargs({
+ @permittedKwargs({
'prefix',
'no_builtin_args',
'include_directories',
@@ -1151,7 +1240,7 @@ class CompilerHolder(InterpreterObject):
mlog.log('Has header "%s":' % hname, h)
return haz
- @permittedMethodKwargs({
+ @permittedKwargs({
'prefix',
'no_builtin_args',
'include_directories',
@@ -1177,7 +1266,7 @@ class CompilerHolder(InterpreterObject):
mlog.log('Header <{0}> has symbol "{1}":'.format(hname, symbol), h)
return haz
- @permittedMethodKwargs({
+ @permittedKwargs({
'required',
'dirs',
})
@@ -1202,14 +1291,14 @@ class CompilerHolder(InterpreterObject):
self.compiler.language)
return ExternalLibraryHolder(lib)
- @permittedMethodKwargs({})
+ @permittedKwargs({})
def has_argument_method(self, args, kwargs):
args = mesonlib.stringlistify(args)
if len(args) != 1:
raise InterpreterException('has_argument takes exactly one argument.')
return self.has_multi_arguments_method(args, kwargs)
- @permittedMethodKwargs({})
+ @permittedKwargs({})
def has_multi_arguments_method(self, args, kwargs):
args = mesonlib.stringlistify(args)
result = self.compiler.has_multi_arguments(args, self.environment)
@@ -1223,7 +1312,7 @@ class CompilerHolder(InterpreterObject):
h)
return result
- @permittedMethodKwargs({})
+ @permittedKwargs({})
def get_supported_arguments_method(self, args, kwargs):
args = mesonlib.stringlistify(args)
supported_args = []
@@ -1232,7 +1321,7 @@ class CompilerHolder(InterpreterObject):
supported_args.append(arg)
return supported_args
- @permittedMethodKwargs({})
+ @permittedKwargs({})
def first_supported_argument_method(self, args, kwargs):
for i in mesonlib.stringlistify(args):
if self.has_argument_method(i, kwargs):
@@ -1241,14 +1330,14 @@ class CompilerHolder(InterpreterObject):
mlog.log('First supported argument:', mlog.red('None'))
return []
- @permittedMethodKwargs({})
+ @permittedKwargs({})
def has_link_argument_method(self, args, kwargs):
args = mesonlib.stringlistify(args)
if len(args) != 1:
raise InterpreterException('has_link_argument takes exactly one argument.')
return self.has_multi_link_arguments_method(args, kwargs)
- @permittedMethodKwargs({})
+ @permittedKwargs({})
def has_multi_link_arguments_method(self, args, kwargs):
args = mesonlib.stringlistify(args)
result = self.compiler.has_multi_link_arguments(args, self.environment)
@@ -1262,7 +1351,7 @@ class CompilerHolder(InterpreterObject):
h)
return result
- @permittedMethodKwargs({})
+ @permittedKwargs({})
def get_supported_link_arguments_method(self, args, kwargs):
args = mesonlib.stringlistify(args)
supported_args = []
@@ -1271,7 +1360,7 @@ class CompilerHolder(InterpreterObject):
supported_args.append(arg)
return supported_args
- @permittedMethodKwargs({})
+ @permittedKwargs({})
def first_supported_link_argument_method(self, args, kwargs):
for i in mesonlib.stringlistify(args):
if self.has_link_argument_method(i, kwargs):
@@ -1378,6 +1467,7 @@ class MesonMain(InterpreterObject):
raise InterpreterException(m.format(name))
return build.RunScript(found.get_command(), args)
+ @permittedKwargs({})
def add_install_script_method(self, args, kwargs):
if len(args) < 1:
raise InterpreterException('add_install_script takes one or more arguments')
@@ -1385,6 +1475,7 @@ class MesonMain(InterpreterObject):
script = self._find_source_script(args[0], args[1:])
self.build.install_scripts.append(script)
+ @permittedKwargs({})
def add_postconf_script_method(self, args, kwargs):
if len(args) < 1:
raise InterpreterException('add_postconf_script takes one or more arguments')
@@ -1392,6 +1483,8 @@ class MesonMain(InterpreterObject):
script = self._find_source_script(args[0], args[1:])
self.build.postconf_scripts.append(script)
+ @noPosargs
+ @permittedKwargs({})
def current_source_dir_method(self, args, kwargs):
src = self.interpreter.environment.source_dir
sub = self.interpreter.subdir
@@ -1399,6 +1492,8 @@ class MesonMain(InterpreterObject):
return src
return os.path.join(src, sub)
+ @noPosargs
+ @permittedKwargs({})
def current_build_dir_method(self, args, kwargs):
src = self.interpreter.environment.build_dir
sub = self.interpreter.subdir
@@ -1406,15 +1501,23 @@ class MesonMain(InterpreterObject):
return src
return os.path.join(src, sub)
+ @noPosargs
+ @permittedKwargs({})
def backend_method(self, args, kwargs):
return self.interpreter.backend.name
+ @noPosargs
+ @permittedKwargs({})
def source_root_method(self, args, kwargs):
return self.interpreter.environment.source_dir
+ @noPosargs
+ @permittedKwargs({})
def build_root_method(self, args, kwargs):
return self.interpreter.environment.build_dir
+ @noPosargs
+ @permittedKwargs({})
def has_exe_wrapper_method(self, args, kwargs):
if self.is_cross_build_method(None, None) and \
'binaries' in self.build.environment.cross_info.config and \
@@ -1427,9 +1530,12 @@ class MesonMain(InterpreterObject):
# Need to revisit this.
return True
+ @noPosargs
+ @permittedKwargs({})
def is_cross_build_method(self, args, kwargs):
return self.build.environment.is_cross_build()
+ @permittedKwargs({'native'})
def get_compiler_method(self, args, kwargs):
if len(args) != 1:
raise InterpreterException('get_compiler_method must have one and only one argument.')
@@ -1450,15 +1556,20 @@ class MesonMain(InterpreterObject):
return CompilerHolder(clist[cname], self.build.environment)
raise InterpreterException('Tried to access compiler for unspecified language "%s".' % cname)
+ @noPosargs
+ @permittedKwargs({})
def is_unity_method(self, args, kwargs):
optval = self.interpreter.environment.coredata.get_builtin_option('unity')
if optval == 'on' or (optval == 'subprojects' and self.interpreter.subproject != ''):
return True
return False
+ @noPosargs
+ @permittedKwargs({})
def is_subproject_method(self, args, kwargs):
return self.interpreter.is_subproject()
+ @permittedKwargs({})
def install_dependency_manifest_method(self, args, kwargs):
if len(args) != 1:
raise InterpreterException('Must specify manifest install file name')
@@ -1466,6 +1577,7 @@ class MesonMain(InterpreterObject):
raise InterpreterException('Argument must be a string.')
self.build.dep_manifest_name = args[0]
+ @permittedKwargs({})
def override_find_program_method(self, args, kwargs):
if len(args) != 2:
raise InterpreterException('Override needs two arguments')
@@ -1486,18 +1598,27 @@ class MesonMain(InterpreterObject):
raise InterpreterException('Second argument must be an external program.')
self.interpreter.add_find_program_override(name, exe)
+ @noPosargs
+ @permittedKwargs({})
def project_version_method(self, args, kwargs):
return self.build.dep_manifest[self.interpreter.active_projectname]['version']
+ @noPosargs
+ @permittedKwargs({})
def project_license_method(self, args, kwargs):
return self.build.dep_manifest[self.interpreter.active_projectname]['license']
+ @noPosargs
+ @permittedKwargs({})
def version_method(self, args, kwargs):
return coredata.version
+ @noPosargs
+ @permittedKwargs({})
def project_name_method(self, args, kwargs):
return self.interpreter.active_projectname
+ @permittedKwargs({})
def get_cross_property_method(self, args, kwargs):
if len(args) < 1 or len(args) > 2:
raise InterpreterException('Must have one or two arguments.')
@@ -1555,7 +1676,7 @@ permitted_kwargs = {'add_global_arguments': {'language'},
'library': known_library_kwargs,
'subdir': {'if_found'},
'subproject': {'version', 'default_options'},
- 'test': {'args', 'env', 'is_parallel', 'should_fail', 'timeout', 'workdir', 'suite'},
+ 'test': {'args', 'depends', 'env', 'is_parallel', 'should_fail', 'timeout', 'workdir', 'suite'},
'vcs_tag': {'input', 'output', 'fallback', 'command', 'replace_string'},
}
@@ -2492,7 +2613,7 @@ to directly access options of other subprojects.''')
if name == '':
if required:
raise InvalidArguments('Dependency is both required and not-found')
- return DependencyHolder(Dependency('not-found', {}))
+ return DependencyHolder(NotFoundDependency(self.environment))
if '<' in name or '>' in name or '=' in name:
raise InvalidArguments('Characters <, > and = are forbidden in dependency names. To specify'
@@ -2516,7 +2637,7 @@ to directly access options of other subprojects.''')
# We need to actually search for this dep
exception = None
- dep = None
+ dep = NotFoundDependency(self.environment)
# Search for it outside the project
if self.coredata.wrap_mode != WrapMode.forcefallback or 'fallback' not in kwargs:
@@ -2528,7 +2649,7 @@ to directly access options of other subprojects.''')
exception = DependencyException("fallback for %s not found" % name)
# Search inside the projects list
- if not dep or not dep.found():
+ if not dep.found():
if 'fallback' in kwargs:
fallback_dep = self.dependency_fallback(name, kwargs)
if fallback_dep:
@@ -2536,7 +2657,7 @@ to directly access options of other subprojects.''')
# cannot cache them. They must always be evaluated else
# we won't actually read all the build files.
return fallback_dep
- if not dep:
+ if required:
assert(exception is not None)
raise exception
@@ -2734,7 +2855,7 @@ root and issuing %s.
if 'command' not in kwargs:
raise InterpreterException('Missing "command" keyword argument')
all_args = extract_as_list(kwargs, 'command')
- deps = extract_as_list(kwargs, 'depends')
+ deps = extract_as_list(kwargs, 'depends', unholder=True)
else:
raise InterpreterException('Run_target needs at least one positional argument.')
@@ -2749,10 +2870,6 @@ root and issuing %s.
raise InterpreterException('First argument must be a string.')
cleaned_deps = []
for d in deps:
- try:
- d = d.held_object
- except AttributeError:
- pass
if not isinstance(d, (build.BuildTarget, build.CustomTarget)):
raise InterpreterException('Depends items must be build targets.')
cleaned_deps.append(d)
@@ -2835,7 +2952,12 @@ root and issuing %s.
if len(s) > 0:
s = ':' + s
suite.append(prj.replace(' ', '_').replace(':', '_') + s)
- t = Test(args[0], prj, suite, exe.held_object, par, cmd_args, env, should_fail, timeout, workdir)
+ depends = extract_as_list(kwargs, 'depends', unholder=True)
+ for dep in depends:
+ if not isinstance(dep, (build.CustomTarget, build.BuildTarget)):
+ raise InterpreterException('Depends items must be build targets.')
+ t = Test(args[0], prj, suite, exe.held_object, depends, par, cmd_args,
+ env, should_fail, timeout, workdir)
if is_base_test:
self.build.tests.append(t)
mlog.debug('Adding test "', mlog.bold(args[0]), '".', sep='')
@@ -3152,11 +3274,9 @@ different subdirectory.
if ":" not in setup_name:
setup_name = (self.subproject if self.subproject else self.build.project_name) + ":" + setup_name
try:
- inp = extract_as_list(kwargs, 'exe_wrapper')
+ inp = extract_as_list(kwargs, 'exe_wrapper', unholder=True)
exe_wrapper = []
for i in inp:
- if hasattr(i, 'held_object'):
- i = i.held_object
if isinstance(i, str):
exe_wrapper.append(i)
elif isinstance(i, dependencies.ExternalProgram):
diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py
index f957d90..bedcf26 100644
--- a/mesonbuild/interpreterbase.py
+++ b/mesonbuild/interpreterbase.py
@@ -31,28 +31,51 @@ def check_stringlist(a, msg='Arguments must be strings.'):
mlog.debug('Element not a string:', str(a))
raise InvalidArguments(msg)
+def _get_callee_args(wrapped_args):
+ # Functions have 4 positional args and methods have 3.
+ s = wrapped_args[0]
+ if len(wrapped_args) == 3:
+ node_or_state = None
+ args = wrapped_args[1]
+ kwargs = wrapped_args[2]
+ elif len(wrapped_args) == 4:
+ node_or_state = wrapped_args[1]
+ args = wrapped_args[2]
+ kwargs = wrapped_args[3]
+ else:
+ raise InvalidArguments('Expecting 3 or 4 args, got {}'.format(len(wrapped_args)))
+
+ # Sometimes interpreter methods are called internally with None instead of
+ # empty list/dict
+ args = args if args is not None else []
+ kwargs = kwargs if kwargs is not None else {}
+ return s, node_or_state, args, kwargs
+
def noPosargs(f):
@wraps(f)
- def wrapped(self, node, args, kwargs):
+ def wrapped(*wrapped_args, **wrapped_kwargs):
+ args = _get_callee_args(wrapped_args)[2]
if args:
raise InvalidArguments('Function does not take positional arguments.')
- return f(self, node, args, kwargs)
+ return f(*wrapped_args, **wrapped_kwargs)
return wrapped
def noKwargs(f):
@wraps(f)
- def wrapped(self, node, args, kwargs):
+ def wrapped(*wrapped_args, **wrapped_kwargs):
+ kwargs = _get_callee_args(wrapped_args)[3]
if kwargs:
raise InvalidArguments('Function does not take keyword arguments.')
- return f(self, node, args, kwargs)
+ return f(*wrapped_args, **wrapped_kwargs)
return wrapped
def stringArgs(f):
@wraps(f)
- def wrapped(self, node, args, kwargs):
+ def wrapped(*wrapped_args, **wrapped_kwargs):
+ args = _get_callee_args(wrapped_args)[2]
assert(isinstance(args, list))
check_stringlist(args)
- return f(self, node, args, kwargs)
+ return f(*wrapped_args, **wrapped_kwargs)
return wrapped
class permittedKwargs:
@@ -62,12 +85,13 @@ class permittedKwargs:
def __call__(self, f):
@wraps(f)
- def wrapped(s, node_or_state, args, kwargs):
+ def wrapped(*wrapped_args, **wrapped_kwargs):
+ s, node_or_state, args, kwargs = _get_callee_args(wrapped_args)
loc = types.SimpleNamespace()
if hasattr(s, 'subdir'):
loc.subdir = s.subdir
loc.lineno = s.current_lineno
- elif hasattr(node_or_state, 'subdir'):
+ elif node_or_state and hasattr(node_or_state, 'subdir'):
loc.subdir = node_or_state.subdir
loc.lineno = node_or_state.current_lineno
else:
@@ -76,26 +100,9 @@ class permittedKwargs:
if k not in self.permitted:
mlog.warning('''Passed invalid keyword argument "{}".'''.format(k), location=loc)
mlog.warning('This will become a hard error in the future.')
- return f(s, node_or_state, args, kwargs)
- return wrapped
-
-
-class permittedMethodKwargs:
-
- def __init__(self, permitted):
- self.permitted = permitted
-
- def __call__(self, f):
- @wraps(f)
- def wrapped(obj, args, kwargs):
- for k in kwargs:
- if k not in self.permitted:
- mlog.warning('''Passed invalid keyword argument "{}".'''.format(k))
- mlog.warning('This will become a hard error in the future.')
- return f(obj, args, kwargs)
+ return f(*wrapped_args, **wrapped_kwargs)
return wrapped
-
class InterpreterException(mesonlib.MesonException):
pass
diff --git a/mesonbuild/mlog.py b/mesonbuild/mlog.py
index 6cbaf60..afefaa6 100644
--- a/mesonbuild/mlog.py
+++ b/mesonbuild/mlog.py
@@ -119,9 +119,8 @@ def _log_error(severity, *args, **kwargs):
else:
assert False, 'Invalid severity ' + severity
- if 'location' in kwargs:
- location = kwargs['location']
- del kwargs['location']
+ location = kwargs.pop('location', None)
+ if location is not None:
location_str = '{}:{}:'.format(os.path.join(location.subdir,
environment.build_filename),
location.lineno)
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py
index 5455118..abefe05 100644
--- a/mesonbuild/modules/gnome.py
+++ b/mesonbuild/modules/gnome.py
@@ -67,8 +67,13 @@ class GnomeModule(ExtensionModule):
global native_glib_version
if native_glib_version is None:
glib_dep = PkgConfigDependency('glib-2.0', state.environment,
- {'native': True})
- native_glib_version = glib_dep.get_version()
+ {'native': True, 'required': False})
+ if glib_dep.found():
+ native_glib_version = glib_dep.get_version()
+ else:
+ mlog.warning('Could not detect glib version, assuming 2.54. '
+ 'You may get build errors if your glib is older.')
+ native_glib_version = '2.54'
return native_glib_version
def __print_gresources_warning(self, state):
@@ -869,12 +874,12 @@ This will become a hard error in the future.''')
return []
@permittedKwargs({'interface_prefix', 'namespace', 'object_manager', 'build_by_default',
- 'annotations', 'docbook', 'install', 'install_header'})
+ 'annotations', 'docbook', 'install_header', 'install_dir', 'sources'})
def gdbus_codegen(self, state, args, kwargs):
- if len(args) != 2:
- raise MesonException('Gdbus_codegen takes two arguments, name and xml file.')
+ if len(args) not in (1, 2):
+ raise MesonException('Gdbus_codegen takes at most two arguments, name and xml file.')
namebase = args[0]
- xml_file = args[1]
+ xml_files = [args[1:]]
target_name = namebase + '-gdbus'
cmd = [self.interpreter.find_program_impl('gdbus-codegen')]
if 'interface_prefix' in kwargs:
@@ -883,6 +888,8 @@ This will become a hard error in the future.''')
cmd += ['--c-namespace', kwargs.pop('namespace')]
if kwargs.get('object_manager', False):
cmd += ['--c-generate-object-manager']
+ if 'sources' in kwargs:
+ xml_files += mesonlib.listify(kwargs.pop('sources'))
build_by_default = kwargs.get('build_by_default', False)
# Annotations are a bit ugly in that they are a list of lists of strings...
@@ -904,7 +911,7 @@ This will become a hard error in the future.''')
install_dir = kwargs.get('install_dir', state.environment.coredata.get_builtin_option('includedir'))
output = namebase + '.c'
- custom_kwargs = {'input': xml_file,
+ custom_kwargs = {'input': xml_files,
'output': output,
'command': cmd + ['--body', '--output', '@OUTDIR@/' + output, '@INPUT@'],
'build_by_default': build_by_default
@@ -912,7 +919,7 @@ This will become a hard error in the future.''')
targets.append(build.CustomTarget(output, state.subdir, state.subproject, custom_kwargs))
output = namebase + '.h'
- custom_kwargs = {'input': xml_file,
+ custom_kwargs = {'input': xml_files,
'output': output,
'command': cmd + ['--header', '--output', '@OUTDIR@/' + output, '@INPUT@'],
'build_by_default': build_by_default,
@@ -929,7 +936,7 @@ This will become a hard error in the future.''')
docbook_cmd = cmd + ['--output-directory', '@OUTDIR@', '--generate-docbook', docbook, '@INPUT@']
output = namebase + '-docbook'
- custom_kwargs = {'input': xml_file,
+ custom_kwargs = {'input': xml_files,
'output': output,
'command': docbook_cmd,
'build_by_default': build_by_default
@@ -952,7 +959,7 @@ This will become a hard error in the future.''')
self._print_gdbus_warning()
cmd += ['--generate-c-code', '@OUTDIR@/' + namebase, '@INPUT@']
outputs = [namebase + '.c', namebase + '.h']
- custom_kwargs = {'input': xml_file,
+ custom_kwargs = {'input': xml_files,
'output': outputs,
'command': cmd,
'build_by_default': build_by_default
diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py
index 934e2f4..a3ba973 100644
--- a/mesonbuild/modules/pkgconfig.py
+++ b/mesonbuild/modules/pkgconfig.py
@@ -59,7 +59,7 @@ class DependenciesHelper:
elif hasattr(obj, 'pcdep'):
pcdeps = mesonlib.listify(obj.pcdep)
for d in pcdeps:
- processed_reqs += d.name
+ processed_reqs.append(d.name)
self.add_version_reqs(d.name, obj.version_reqs)
elif isinstance(obj, dependencies.PkgConfigDependency):
if obj.found():
diff --git a/mesonbuild/modules/python.py b/mesonbuild/modules/python.py
index 16bdfd6..afcae8f 100644
--- a/mesonbuild/modules/python.py
+++ b/mesonbuild/modules/python.py
@@ -313,32 +313,58 @@ class PythonInstallation(ExternalProgramHolder, InterpreterObject):
return ModuleReturnValue(True, [])
@noKwargs
- def get_path(self, node, args, kwargs):
+ def has_path(self, node, args, kwargs):
if len(args) != 1:
- raise InvalidArguments('get_path takes exactly one positional argument.')
+ raise InvalidArguments('has_path takes exactly one positional argument.')
path_name = args[0]
if not isinstance(path_name, str):
- raise InvalidArguments('get_path argument must be a string.')
+ raise InvalidArguments('has_path argument must be a string.')
+
+ return ModuleReturnValue(path_name in self.paths, [])
- path = self.paths.get(path_name)
+ @noKwargs
+ def get_path(self, node, args, kwargs):
+ if len(args) not in (1, 2):
+ raise InvalidArguments('get_path must have one or two arguments.')
+ path_name = args[0]
+ if not isinstance(path_name, str):
+ raise InvalidArguments('get_path argument must be a string.')
- if path is None:
- raise InvalidArguments('{} is not a valid path name'.format(path_name))
+ try:
+ path = self.paths[path_name]
+ except KeyError:
+ if len(args) == 2:
+ path = args[1]
+ else:
+ raise InvalidArguments('{} is not a valid path name'.format(path_name))
return ModuleReturnValue(path, [])
@noKwargs
- def get_variable(self, node, args, kwargs):
+ def has_variable(self, node, args, kwargs):
if len(args) != 1:
- raise InvalidArguments('get_variable takes exactly one positional argument.')
+ raise InvalidArguments('has_variable takes exactly one positional argument.')
var_name = args[0]
if not isinstance(var_name, str):
- raise InvalidArguments('get_variable argument must be a string.')
+ raise InvalidArguments('has_variable argument must be a string.')
+
+ return ModuleReturnValue(var_name in self.variables, [])
- var = self.variables.get(var_name)
+ @noKwargs
+ def get_variable(self, node, args, kwargs):
+ if len(args) not in (1, 2):
+ raise InvalidArguments('get_variable must have one or two arguments.')
+ var_name = args[0]
+ if not isinstance(var_name, str):
+ raise InvalidArguments('get_variable argument must be a string.')
- if var is None:
- raise InvalidArguments('{} is not a valid path name'.format(var_name))
+ try:
+ var = self.variables[var_name]
+ except KeyError:
+ if len(args) == 2:
+ var = args[1]
+ else:
+ raise InvalidArguments('{} is not a valid variable name'.format(var_name))
return ModuleReturnValue(var, [])
@@ -351,7 +377,7 @@ class PythonInstallation(ExternalProgramHolder, InterpreterObject):
if method_name in ['extension_module', 'dependency', 'install_sources']:
value = fn(self.interpreter, None, args, kwargs)
return self.interpreter.holderify(value)
- elif method_name in ['get_variable', 'get_path', 'found', 'language_version', 'get_install_dir']:
+ elif method_name in ['has_variable', 'get_variable', 'has_path', 'get_path', 'found', 'language_version', 'get_install_dir']:
value = fn(None, args, kwargs)
return self.interpreter.module_method_callback(value)
else:
diff --git a/mesonbuild/mparser.py b/mesonbuild/mparser.py
index 9e43065..8cef377 100644
--- a/mesonbuild/mparser.py
+++ b/mesonbuild/mparser.py
@@ -28,18 +28,6 @@ ESCAPE_SEQUENCE_SINGLE_RE = re.compile(r'''
| \\[\\'abfnrtv] # Single-character escapes
)''', re.UNICODE | re.VERBOSE)
-# This is the regex for the supported escape sequences of a multiline string
-# literal, like '''abc\x00'''. The only difference is that single quote (')
-# doesn't require escaping.
-ESCAPE_SEQUENCE_MULTI_RE = re.compile(r'''
- ( \\U........ # 8-digit hex escapes
- | \\u.... # 4-digit hex escapes
- | \\x.. # 2-digit hex escapes
- | \\[0-7]{1,3} # Octal escapes
- | \\N\{[^}]+\} # Unicode characters by name
- | \\[\\abfnrtv] # Single-character escapes
- )''', re.UNICODE | re.VERBOSE)
-
class MesonUnicodeDecodeError(MesonException):
def __init__(self, match):
super().__init__("%s" % match)
@@ -187,10 +175,6 @@ This will become a hard error in a future Meson release.""", self.getline(line_s
elif tid == 'multiline_string':
tid = 'string'
value = match_text[3:-3]
- try:
- value = ESCAPE_SEQUENCE_MULTI_RE.sub(decode_match, value)
- except MesonUnicodeDecodeError as err:
- raise MesonException("Failed to parse escape sequence: '{}' in string:\n{}".format(err.match, match_text))
lines = match_text.split('\n')
if len(lines) > 1:
lineno += len(lines) - 1
diff --git a/run_project_tests.py b/run_project_tests.py
index a1d36ef..8c02a9e 100755
--- a/run_project_tests.py
+++ b/run_project_tests.py
@@ -21,10 +21,7 @@ from io import StringIO
from ast import literal_eval
from enum import Enum
import tempfile
-from mesonbuild import mtest
-from mesonbuild import environment
-from mesonbuild import mesonlib
-from mesonbuild import mlog
+from mesonbuild import build, environment, mesonlib, mlog, mtest
from mesonbuild.mesonlib import stringlistify, Popen_safe
from mesonbuild.coredata import backendlist
import argparse
@@ -137,9 +134,9 @@ def get_relative_files_list_from_dir(fromdir):
paths.append(path)
return paths
-def platform_fix_name(fname, compiler):
+def platform_fix_name(fname, compiler, env):
if '?lib' in fname:
- if mesonlib.is_cygwin():
+ if mesonlib.for_cygwin(env.is_cross_build(), env):
fname = re.sub(r'lib/\?lib(.*)\.so$', r'bin/cyg\1.dll', fname)
fname = re.sub(r'\?lib(.*)\.dll$', r'cyg\1.dll', fname)
else:
@@ -147,7 +144,7 @@ def platform_fix_name(fname, compiler):
if fname.endswith('?exe'):
fname = fname[:-4]
- if mesonlib.is_windows() or mesonlib.is_cygwin():
+ if mesonlib.for_windows(env.is_cross_build(), env) or mesonlib.for_cygwin(env.is_cross_build(), env):
return fname + '.exe'
if fname.startswith('?msvc:'):
@@ -162,7 +159,7 @@ def platform_fix_name(fname, compiler):
return fname
-def validate_install(srcdir, installdir, compiler):
+def validate_install(srcdir, installdir, compiler, env):
# List of installed files
info_file = os.path.join(srcdir, 'installed_files.txt')
# If this exists, the test does not install any other files
@@ -175,7 +172,7 @@ def validate_install(srcdir, installdir, compiler):
elif os.path.exists(info_file):
with open(info_file) as f:
for line in f:
- line = platform_fix_name(line.strip(), compiler)
+ line = platform_fix_name(line.strip(), compiler, env)
if line:
expected[line] = False
# Check if expected files were found
@@ -207,8 +204,16 @@ def log_text_file(logfile, testdir, stdo, stde):
logfile.write(stde)
logfile.write('\n\n---\n\n')
if print_debug:
- print(stdo)
- print(stde, file=sys.stderr)
+ try:
+ print(stdo)
+ except UnicodeError:
+ sanitized_out = stdo.encode('ascii', errors='replace').decode()
+ print(sanitized_out)
+ try:
+ print(stde, file=sys.stderr)
+ except UnicodeError:
+ sanitized_err = stde.encode('ascii', errors='replace').decode()
+ print(sanitized_err, file=sys.stderr)
if stop:
print("Aborting..")
for f in futures:
@@ -314,7 +319,7 @@ def _run_test(testdir, test_build_dir, install_dir, extra_args, compiler, backen
(returncode, stdo, stde) = run_configure(meson_command, gen_args)
try:
logfile = os.path.join(test_build_dir, 'meson-logs/meson-log.txt')
- with open(logfile, errors='ignore') as f:
+ with open(logfile, encoding='utf-8', errors='ignore') as f:
mesonlog = f.read()
except Exception:
mesonlog = no_meson_log_msg
@@ -328,6 +333,7 @@ def _run_test(testdir, test_build_dir, install_dir, extra_args, compiler, backen
return TestResult('Test that should have failed succeeded', BuildStep.configure, stdo, stde, mesonlog, gen_time)
if returncode != 0:
return TestResult('Generating the build system failed.', BuildStep.configure, stdo, stde, mesonlog, gen_time)
+ builddata = build.load(test_build_dir)
# Touch the meson.build file to force a regenerate so we can test that
# regeneration works before a build is run.
ensure_backend_detects_changes(backend)
@@ -381,7 +387,8 @@ def _run_test(testdir, test_build_dir, install_dir, extra_args, compiler, backen
return TestResult('Running clean failed.', BuildStep.clean, stdo, stde, mesonlog, gen_time, build_time, test_time)
if not install_commands:
return TestResult('', BuildStep.install, '', '', mesonlog, gen_time, build_time, test_time)
- return TestResult(validate_install(testdir, install_dir, compiler), BuildStep.validate, stdo, stde, mesonlog, gen_time, build_time, test_time)
+ return TestResult(validate_install(testdir, install_dir, compiler, builddata.environment),
+ BuildStep.validate, stdo, stde, mesonlog, gen_time, build_time, test_time)
def gather_tests(testdir):
tests = [t.replace('\\', '/').split('/', 2)[2] for t in glob(testdir + '/*')]
@@ -516,7 +523,7 @@ def detect_tests_to_run():
def run_tests(all_tests, log_name_base, extra_args):
global logfile
txtname = log_name_base + '.txt'
- with open(txtname, 'w', encoding="utf_8") as lf:
+ with open(txtname, 'w', encoding='utf-8', errors='ignore') as lf:
logfile = lf
return _run_tests(all_tests, log_name_base, extra_args)
@@ -694,7 +701,10 @@ if __name__ == '__main__':
if failing_tests > 0:
print('\nMesonlogs of failing tests\n')
for l in failing_logs:
- print(l, '\n')
+ try:
+ print(l, '\n')
+ except UnicodeError:
+ print(l.encode('ascii', errors='replace').decode(), '\n')
for name, dirs, skip in all_tests:
dirs = (os.path.basename(x) for x in dirs)
for k, g in itertools.groupby(dirs, key=lambda x: x.split()[0]):
diff --git a/run_unittests.py b/run_unittests.py
index e0cd1ec..ce18a1a 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -439,6 +439,7 @@ class InternalTests(unittest.TestCase):
kwargs = {'sources': [1, 2, 3], 'pch_sources': [4, 5, 6]}
self.assertEqual([[1, 2, 3], [4, 5, 6]], extract(kwargs, 'sources', 'pch_sources'))
+ @unittest.skipIf(not os.path.isdir('docs'), 'Doc dir not found, presumably because this is a tarball release.')
def test_snippets(self):
hashcounter = re.compile('^ *(#)+')
snippet_dir = Path('docs/markdown/snippets')
@@ -456,7 +457,6 @@ class InternalTests(unittest.TestCase):
self.assertTrue(False, 'A file without .md suffix in snippets dir: ' + f.name)
def test_pkgconfig_module(self):
- deps = mesonbuild.modules.pkgconfig.DependenciesHelper("thislib")
class Mock:
pass
@@ -465,9 +465,17 @@ class InternalTests(unittest.TestCase):
mock.pcdep = Mock()
mock.pcdep.name = "some_name"
mock.version_reqs = []
+
+ # pkgconfig dependency as lib
+ deps = mesonbuild.modules.pkgconfig.DependenciesHelper("thislib")
deps.add_pub_libs([mock])
self.assertEqual(deps.format_reqs(deps.pub_reqs), "some_name")
+ # pkgconfig dependency as requires
+ deps = mesonbuild.modules.pkgconfig.DependenciesHelper("thislib")
+ deps.add_pub_reqs([mock])
+ self.assertEqual(deps.format_reqs(deps.pub_reqs), "some_name")
+
class BasePlatformTests(unittest.TestCase):
def setUp(self):
@@ -634,9 +642,11 @@ class BasePlatformTests(unittest.TestCase):
return self.build(target=target)
def setconf(self, arg, will_build=True):
+ if not isinstance(arg, list):
+ arg = [arg]
if will_build:
ensure_backend_detects_changes(self.backend)
- self._run(self.mconf_command + [arg, self.builddir])
+ self._run(self.mconf_command + arg + [self.builddir])
def wipe(self):
windows_proof_rmtree(self.builddir)
@@ -2012,6 +2022,58 @@ recommended as it can lead to undefined behaviour on some platforms''')
self.builddir = exebuilddir
self.assertRebuiltTarget('app')
+ def test_conflicting_d_dash_option(self):
+ testdir = os.path.join(self.unit_test_dir, '30 mixed command line args')
+ with self.assertRaises(subprocess.CalledProcessError) as e:
+ self.init(testdir, extra_args=['-Dbindir=foo', '--bindir=bar'])
+ # Just to ensure that we caught the correct error
+ self.assertIn('passed as both', e.stderr)
+
+ def _test_same_option_twice(self, arg, args):
+ testdir = os.path.join(self.unit_test_dir, '30 mixed command line args')
+ self.init(testdir, extra_args=args)
+ opts = self.introspect('--buildoptions')
+ for item in opts:
+ if item['name'] == arg:
+ self.assertEqual(item['value'], 'bar')
+ return
+ raise Exception('Missing {} value?'.format(arg))
+
+ def test_same_dash_option_twice(self):
+ self._test_same_option_twice('bindir', ['--bindir=foo', '--bindir=bar'])
+
+ def test_same_d_option_twice(self):
+ self._test_same_option_twice('bindir', ['-Dbindir=foo', '-Dbindir=bar'])
+
+ def test_same_project_d_option_twice(self):
+ self._test_same_option_twice('one', ['-Done=foo', '-Done=bar'])
+
+ def _test_same_option_twice_configure(self, arg, args):
+ testdir = os.path.join(self.unit_test_dir, '30 mixed command line args')
+ self.init(testdir)
+ self.setconf(args)
+ opts = self.introspect('--buildoptions')
+ for item in opts:
+ if item['name'] == arg:
+ self.assertEqual(item['value'], 'bar')
+ return
+ raise Exception('Missing {} value?'.format(arg))
+
+ def test_same_dash_option_twice_configure(self):
+ with self.assertRaises(subprocess.CalledProcessError) as e:
+ self._test_same_option_twice_configure(
+ 'bindir', ['--bindir=foo', '--bindir=bar'])
+ self.assertIn('Pick one.', e.stderr)
+
+ def test_same_d_option_twice_configure(self):
+ self._test_same_option_twice_configure(
+ 'bindir', ['-Dbindir=foo', '-Dbindir=bar'])
+
+ def test_same_project_d_option_twice_configure(self):
+ self._test_same_option_twice_configure(
+ 'one', ['-Done=foo', '-Done=bar'])
+
+
class FailureTests(BasePlatformTests):
'''
@@ -2957,7 +3019,7 @@ class LinuxArmCrossCompileTests(BasePlatformTests):
https://github.com/mesonbuild/meson/issues/3089
'''
testdir = os.path.join(self.unit_test_dir, '29 cross file overrides always args')
- self.meson_cross_file = os.path.join(self.unit_test_dir, 'ubuntu-armhf-overrides.txt')
+ self.meson_cross_file = os.path.join(testdir, 'ubuntu-armhf-overrides.txt')
self.init(testdir)
compdb = self.get_compdb()
self.assertRegex(compdb[0]['command'], '-D_FILE_OFFSET_BITS=64.*-U_FILE_OFFSET_BITS')
diff --git a/test cases/common/132 dependency file generation/meson.build b/test cases/common/132 dependency file generation/meson.build
index cd66cb7..b5ee47b 100644
--- a/test cases/common/132 dependency file generation/meson.build
+++ b/test cases/common/132 dependency file generation/meson.build
@@ -3,7 +3,7 @@ project('dep file gen', 'c')
cc_id = meson.get_compiler('c').get_id()
cc_ver = meson.get_compiler('c').version()
-if cc_id == 'intel' or (cc_id == 'lcc' and cc_ver.version_compare('<=1.23.08')
+if cc_id == 'intel' or (cc_id == 'lcc' and cc_ver.version_compare('<=1.23.08'))
# ICC and LCC <= 1.23.08 do not escape spaces in paths in the dependency file, so Ninja
# (correctly) thinks that the rule has multiple outputs and errors out:
# 'depfile has multiple output paths'
diff --git a/test cases/common/183 same target name/file.c b/test cases/common/196 same target name/file.c
index 6f1c172..6f1c172 100644
--- a/test cases/common/183 same target name/file.c
+++ b/test cases/common/196 same target name/file.c
diff --git a/test cases/common/183 same target name/meson.build b/test cases/common/196 same target name/meson.build
index 4e585d5..4e585d5 100644
--- a/test cases/common/183 same target name/meson.build
+++ b/test cases/common/196 same target name/meson.build
diff --git a/test cases/common/183 same target name/sub/file2.c b/test cases/common/196 same target name/sub/file2.c
index a5e453d..a5e453d 100644
--- a/test cases/common/183 same target name/sub/file2.c
+++ b/test cases/common/196 same target name/sub/file2.c
diff --git a/test cases/common/183 same target name/sub/meson.build b/test cases/common/196 same target name/sub/meson.build
index 610a4a3..610a4a3 100644
--- a/test cases/common/183 same target name/sub/meson.build
+++ b/test cases/common/196 same target name/sub/meson.build
diff --git a/test cases/common/197 test depends/gen.py b/test cases/common/197 test depends/gen.py
new file mode 100755
index 0000000..ee4ed98
--- /dev/null
+++ b/test cases/common/197 test depends/gen.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python3
+
+import sys
+
+
+def main():
+ with open(sys.argv[1], 'w') as out:
+ out.write(sys.argv[2])
+ out.write('\n')
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test cases/common/197 test depends/main.c b/test cases/common/197 test depends/main.c
new file mode 100644
index 0000000..78f2de1
--- /dev/null
+++ b/test cases/common/197 test depends/main.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/test cases/common/197 test depends/meson.build b/test cases/common/197 test depends/meson.build
new file mode 100644
index 0000000..888c451
--- /dev/null
+++ b/test cases/common/197 test depends/meson.build
@@ -0,0 +1,26 @@
+project('test depends', 'c')
+
+gen = find_program('gen.py')
+
+custom_dep = custom_target('custom_dep',
+ build_by_default : false,
+ output : 'custom_dep.txt',
+ command : [gen, '@OUTPUT@', 'custom_dep'],
+)
+
+exe_dep = executable('exe_dep', 'main.c',
+ build_by_default : false,
+)
+
+test_prog = find_program('test.py')
+test('string dependencies', test_prog,
+ args : [
+ # This is declared for convenience,
+ # real use case might have some obscure method
+ # to find these dependencies, e.g. automatic plugin loading.
+ 'custom_dep.txt',
+ exe_dep.full_path(),
+ ],
+ depends : [custom_dep, exe_dep],
+ workdir : meson.current_build_dir(),
+)
diff --git a/test cases/common/197 test depends/test.py b/test cases/common/197 test depends/test.py
new file mode 100755
index 0000000..5b9f65c
--- /dev/null
+++ b/test cases/common/197 test depends/test.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python3
+
+import os
+import os.path
+import sys
+
+
+def main():
+ print('Looking in:', os.getcwd())
+ not_found = list()
+ for f in sys.argv[1:]:
+ if not os.path.exists(f):
+ not_found.append(f)
+ if not_found:
+ print('Not found:', ', '.join(not_found))
+ sys.exit(1)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test cases/common/22 header in file list/meson.build b/test cases/common/22 header in file list/meson.build
index ff42cc4..79eec8d 100644
--- a/test cases/common/22 header in file list/meson.build
+++ b/test cases/common/22 header in file list/meson.build
@@ -3,7 +3,7 @@ project('header in file list', 'c')
cc_id = meson.get_compiler('c').get_id()
cc_ver = meson.get_compiler('c').version()
-if cc_id == 'intel' or (cc_id == 'lcc' and cc_ver.version_compare('<=1.23.08')
+if cc_id == 'intel' or (cc_id == 'lcc' and cc_ver.version_compare('<=1.23.08'))
# ICC and LCC <= 1.23.08 do not escape spaces in paths in the dependency file, so Ninja
# (correctly) thinks that the rule has multiple outputs and errors out:
# 'depfile has multiple output paths'
diff --git a/test cases/common/32 multiline string/meson.build b/test cases/common/32 multiline string/meson.build
index 1f952f1..262cb15 100644
--- a/test cases/common/32 multiline string/meson.build
+++ b/test cases/common/32 multiline string/meson.build
@@ -23,3 +23,13 @@ quote2 = '\''
if quote1 != quote2
error('Single quote quoting is broken.')
endif
+
+cc = meson.get_compiler('c')
+prog = '''
+int main(int argc, char **argv) {
+ int num = 1;
+ printf("%d\n", num);
+ return 0;
+}'''
+
+assert(cc.compiles(prog), 'multline test compile failed')
diff --git a/test cases/common/33 try compile/meson.build b/test cases/common/33 try compile/meson.build
index cb1037d..09ca395 100644
--- a/test cases/common/33 try compile/meson.build
+++ b/test cases/common/33 try compile/meson.build
@@ -1,11 +1,11 @@
project('try compile', 'c', 'cpp')
code = '''#include<stdio.h>
-void func() { printf("Something.\\n"); }
+void func() { printf("Something.\n"); }
'''
breakcode = '''#include<nonexisting.h>
-void func() { printf("This won't work.\\n"); }
+void func() { printf("This won't work.\n"); }
'''
foreach compiler : [meson.get_compiler('c'), meson.get_compiler('cpp')]
diff --git a/test cases/common/39 tryrun/meson.build b/test cases/common/39 tryrun/meson.build
index daf5be7..c64446f 100644
--- a/test cases/common/39 tryrun/meson.build
+++ b/test cases/common/39 tryrun/meson.build
@@ -13,8 +13,8 @@ endif
ok_code = '''#include<stdio.h>
int main(int argc, char **argv) {
- printf("%s\\n", "stdout");
- fprintf(stderr, "%s\\n", "stderr");
+ printf("%s\n", "stdout");
+ fprintf(stderr, "%s\n", "stderr");
return 0;
}
'''
diff --git a/test cases/common/42 string operations/meson.build b/test cases/common/42 string operations/meson.build
index 1c289eb..6596142 100644
--- a/test cases/common/42 string operations/meson.build
+++ b/test cases/common/42 string operations/meson.build
@@ -78,15 +78,17 @@ assert('"1.1.20"'.strip('".') == '1.1.20', '". badly stripped')
assert('"1.1.20" '.strip('" ') == '1.1.20', '". badly stripped')
bs_c = '''\c'''
-bs_bs_c = '''\\\c'''
+bs_bs_c = '''\\c'''
nl = '''
'''
-bs_n = '''\\n'''
+bs_n = '''\n'''
bs_nl = '''\
'''
-bs_bs_n = '''\\\\n'''
-bs_bs_nl = '''\\\\
+bs_bs_n = '''\\n'''
+bs_bs_nl = '''\\
'''
+bs_bs = '''\\'''
+bs = '''\'''
assert('\c' == bs_c, 'Single backslash broken')
assert('\\c' == bs_c, 'Double backslash broken')
@@ -97,3 +99,5 @@ assert('\\n' == bs_n, 'Double backslash broken before n')
assert('\\\n' == bs_nl, 'Three backslash broken before n')
assert('\\\\n' == bs_bs_n, 'Four backslash broken before n')
assert('\\\\\n' == bs_bs_nl, 'Five backslash broken before n')
+assert('\\\\' == bs_bs, 'Double-backslash broken')
+assert('\\' == bs, 'Backslash broken')
diff --git a/test cases/common/64 custom header generator/meson.build b/test cases/common/64 custom header generator/meson.build
index 2279513..d43915a 100644
--- a/test cases/common/64 custom header generator/meson.build
+++ b/test cases/common/64 custom header generator/meson.build
@@ -3,7 +3,7 @@ project('custom header generator', 'c')
cc_id = meson.get_compiler('c').get_id()
cc_ver = meson.get_compiler('c').version()
-if cc_id == 'intel' or (cc_id == 'lcc' and cc_ver.version_compare('<=1.23.08')
+if cc_id == 'intel' or (cc_id == 'lcc' and cc_ver.version_compare('<=1.23.08'))
# ICC and LCC <= 1.23.08 do not escape spaces in paths in the dependency file, so Ninja
# (correctly) thinks that the rule has multiple outputs and errors out:
# 'depfile has multiple output paths'
diff --git a/test cases/common/88 extract all/meson.build b/test cases/common/88 extract all/meson.build
index 91a8d5f..4f08a4f 100644
--- a/test cases/common/88 extract all/meson.build
+++ b/test cases/common/88 extract all/meson.build
@@ -2,8 +2,12 @@ project('extract all', 'c')
a = static_library('a', 'one.c', 'two.c')
b = static_library('b', 'three.c', 'four.c')
-c = static_library('c',
- objects : [a.extract_all_objects(), b.extract_all_objects()])
+c = static_library('c', objects : [a.extract_all_objects(), b.extract_all_objects()])
+d = static_library('d', objects : [a.extract_all_objects(), b.extract_all_objects(), c.extract_all_objects()])
+d_recursive = static_library('d_recursive', objects : [c.extract_all_objects(recursive : true)])
-e = executable('proggie', 'prog.c', link_with : c)
+e = executable('proggie', 'prog.c', link_with : d)
test('extall', e)
+
+e = executable('proggie_recursive', 'prog.c', link_with : d_recursive)
+test('extall_recursive', e)
diff --git a/test cases/frameworks/7 gnome/gdbus/meson.build b/test cases/frameworks/7 gnome/gdbus/meson.build
index 57d7f23..68ad706 100644
--- a/test cases/frameworks/7 gnome/gdbus/meson.build
+++ b/test cases/frameworks/7 gnome/gdbus/meson.build
@@ -7,7 +7,8 @@ gdbus_src = gnome.gdbus_codegen('generated-gdbus-no-docbook', 'com.example.Sampl
)
assert(gdbus_src.length() == 2, 'expected 2 targets')
-gdbus_src = gnome.gdbus_codegen('generated-gdbus', 'com.example.Sample.xml',
+gdbus_src = gnome.gdbus_codegen('generated-gdbus',
+ sources : 'com.example.Sample.xml',
interface_prefix : 'com.example.',
namespace : 'Sample',
annotations : [
diff --git a/test cases/unit/27 forcefallback/meson.build b/test cases/unit/27 forcefallback/meson.build
index e6a90ea..d5c06c3 100644
--- a/test cases/unit/27 forcefallback/meson.build
+++ b/test cases/unit/27 forcefallback/meson.build
@@ -2,7 +2,8 @@ project('mainproj', 'c',
default_options : ['wrap_mode=forcefallback'])
zlib_dep = dependency('zlib', fallback: ['notzlib', 'zlib_dep'])
+notfound_dep = dependency('cannotabletofind', fallback: ['definitelynotfound', 'some_var'], required : false)
-test_not_zlib = executable('test_not_zlib', ['test_not_zlib.c'], dependencies: [zlib_dep])
+test_not_zlib = executable('test_not_zlib', ['test_not_zlib.c'], dependencies: [zlib_dep, notfound_dep])
test('test_not_zlib', test_not_zlib)
diff --git a/test cases/unit/30 mixed command line args/meson.build b/test cases/unit/30 mixed command line args/meson.build
new file mode 100644
index 0000000..af5cdc7
--- /dev/null
+++ b/test cases/unit/30 mixed command line args/meson.build
@@ -0,0 +1 @@
+project('Mixed command line arguments')
diff --git a/test cases/unit/30 mixed command line args/meson_options.txt b/test cases/unit/30 mixed command line args/meson_options.txt
new file mode 100644
index 0000000..5a4bc22
--- /dev/null
+++ b/test cases/unit/30 mixed command line args/meson_options.txt
@@ -0,0 +1,10 @@
+option(
+ 'one',
+ type : 'string',
+)
+option(
+ 'two',
+ type : 'combo',
+ choices : ['foo', 'bar'],
+ value : 'foo',
+)