aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml10
-rw-r--r--docs/markdown/Build-options.md30
-rw-r--r--docs/markdown/Configuration.md8
-rw-r--r--docs/markdown/Dependencies.md169
-rw-r--r--docs/markdown/Gnome-module.md2
-rw-r--r--docs/markdown/Reference-manual.md14
-rw-r--r--docs/markdown/Release-notes-for-0.44.0.md6
-rw-r--r--docs/markdown/Release-notes-for-0.47.0.md6
-rw-r--r--docs/markdown/snippets/configure_file_encoding.md12
-rw-r--r--docs/markdown/snippets/gdbus_codegen_options.md14
-rwxr-xr-xmeson.py2
-rw-r--r--mesonbuild/backend/backends.py21
-rw-r--r--mesonbuild/backend/ninjabackend.py14
-rw-r--r--mesonbuild/backend/vs2010backend.py13
-rw-r--r--mesonbuild/build.py9
-rw-r--r--mesonbuild/compilers/c.py41
-rw-r--r--mesonbuild/compilers/compilers.py4
-rw-r--r--mesonbuild/compilers/fortran.py10
-rw-r--r--mesonbuild/coredata.py20
-rw-r--r--mesonbuild/dependencies/misc.py1
-rw-r--r--mesonbuild/dependencies/ui.py4
-rw-r--r--mesonbuild/interpreter.py34
-rw-r--r--mesonbuild/interpreterbase.py7
-rw-r--r--mesonbuild/mesonlib.py11
-rw-r--r--mesonbuild/mintro.py4
-rw-r--r--mesonbuild/modules/gnome.py12
-rw-r--r--mesonbuild/scripts/gtkdochelper.py5
-rwxr-xr-xrun_tests.py21
-rwxr-xr-xrun_unittests.py15
-rw-r--r--test cases/common/140 get define/concat.h24
-rw-r--r--test cases/common/140 get define/meson.build18
-rw-r--r--test cases/common/16 configure file/config8.h.in3
-rw-r--r--test cases/common/16 configure file/meson.build10
-rw-r--r--test cases/common/188 subdir_done/meson.build4
-rw-r--r--test cases/failing/78 link with shared module on osx/meson.build8
-rw-r--r--test cases/failing/78 link with shared module on osx/module.c3
-rw-r--r--test cases/failing/78 link with shared module on osx/prog.c4
-rw-r--r--test cases/failing/79 non ascii in ascii encoded configure file/config9.h.in1
-rw-r--r--test cases/failing/79 non ascii in ascii encoded configure file/meson.build10
-rw-r--r--test cases/rust/8 many files/foo.rs3
-rw-r--r--test cases/rust/8 many files/main.rs5
-rw-r--r--test cases/rust/8 many files/meson.build3
-rw-r--r--test cases/vala/25 extract_all_objects/meson.build11
-rw-r--r--test cases/vala/25 extract_all_objects/prog.vala7
-rw-r--r--test cases/vala/26 vala and asm/meson.build23
-rw-r--r--test cases/vala/26 vala and asm/prog.vala9
-rw-r--r--test cases/vala/26 vala and asm/retval-arm.S11
-rw-r--r--test cases/vala/26 vala and asm/retval-x86.S12
-rw-r--r--test cases/vala/26 vala and asm/retval-x86_64.S11
-rw-r--r--test cases/vala/26 vala and asm/symbol-underscore.h5
-rw-r--r--test cases/windows/8 dll versioning/installed_files.txt2
51 files changed, 562 insertions, 144 deletions
diff --git a/.travis.yml b/.travis.yml
index f4b15af..62385d6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -33,16 +33,10 @@ matrix:
# Test cross builds separately, they do not use the global compiler
- os: linux
compiler: gcc
- env: RUN_TESTS_ARGS="--cross=arm"
+ env: RUN_TESTS_ARGS="--cross"
- os: linux
compiler: gcc
- env: RUN_TESTS_ARGS="--cross=arm" MESON_ARGS="--unity=on"
- - os: linux
- compiler: gcc
- env: RUN_TESTS_ARGS="--cross=mingw"
- - os: linux
- compiler: gcc
- env: RUN_TESTS_ARGS="--cross=mingw" MESON_ARGS="--unity=on"
+ env: RUN_TESTS_ARGS="--cross" MESON_ARGS="--unity=on"
before_install:
- python ./skip_ci.py --base-branch-env=TRAVIS_BRANCH --is-pull-env=TRAVIS_PULL_REQUEST
diff --git a/docs/markdown/Build-options.md b/docs/markdown/Build-options.md
index 9ccdf83..ec4a3bb 100644
--- a/docs/markdown/Build-options.md
+++ b/docs/markdown/Build-options.md
@@ -21,6 +21,8 @@ option('free_array_opt', type : 'array', value : ['one', 'two'])
option('array_opt', type : 'array', choices : ['one', 'two', 'three'], value : ['one', 'two'])
```
+## Build option types
+
All types allow a `description` value to be set describing the option,
if no option is set then the name of the option will be used instead.
@@ -40,7 +42,7 @@ A combo allows any one of the values in the `choices` parameter to be
selected. If no default value is set then the first value will be the
default.
-## Integers
+### Integers
An integer option contains a single integer with optional upper and
lower values that are specified with the `min` and `max` keyword
@@ -135,3 +137,29 @@ project which also has an option called `some_option`, then calling
`get_option` returns the value of the superproject. If the value of
`yield` is `false`, `get_option` returns the value of the subproject's
option.
+
+
+## Built-in build options
+
+There are a number of built-in options. To get the current list execute `meson
+configure` in the build directory.
+
+### Visual Studio
+
+#### Startup project
+
+The backend\_startup\_project option can be set to define the default project
+that will be executed with the "Start debugging F5" action in visual studio.
+It should be the same name as an executable target name.
+
+```meson
+project('my_project', 'c', default_options: ['backend_startup_project=my_exe'])
+executable('my_exe', ...)
+```
+
+### Ninja
+
+#### Max links
+
+The backend\_max\_links can be set to limit the number of processes that ninja
+will use to link.
diff --git a/docs/markdown/Configuration.md b/docs/markdown/Configuration.md
index 89f423c..8b79bc6 100644
--- a/docs/markdown/Configuration.md
+++ b/docs/markdown/Configuration.md
@@ -113,6 +113,14 @@ Will produce:
#define BAR
```
+## Dealing with file encodings
+
+The default meson file encoding to configure files is utf-8. If you need to
+configure a file that is not utf-8 encoded the encoding keyword will allow
+you to specify which file encoding to use. It is however strongly advised to
+convert your non utf-8 file to utf-8 whenever possible. Supported file
+encodings are those of python3, see [standard-encodings](https://docs.python.org/3/library/codecs.html#standard-encodings).
+
# A full example
Generating and using a configuration file requires the following steps:
diff --git a/docs/markdown/Dependencies.md b/docs/markdown/Dependencies.md
index d2b5e0a..3e4e5ad 100644
--- a/docs/markdown/Dependencies.md
+++ b/docs/markdown/Dependencies.md
@@ -111,6 +111,38 @@ of all the work behind the scenes to make this work.
# Dependencies with custom lookup functionality
+Some dependencies have specific detection logic.
+
+Generic dependency names are case-sensitive<sup>[1](#footnote1)</sup>, but these
+dependency names are matched case-insensitively. The recommended style is to
+write them in all lower-case.
+
+In some cases, more than one detection method exists, and the `method` keyword
+may be used to select a detection method to use. The `auto` method uses any
+checking mechanisms in whatever order meson thinks is best.
+
+e.g. libwmf and CUPS provide both pkg-config and config-tool support. You can
+force one or another via the `method` keyword:
+
+```meson
+cups_dep = dependency('cups', method : 'pkg-config')
+wmf_dep = dependency('libwmf', method : 'config-tool')
+```
+
+## Dependencies using config tools
+
+[CUPS](#cups), [LLVM](#llvm), [pcap](#pcap), [WxWidgets](#wxwidgets),
+[libwmf](#libwmf), and GnuStep either do not provide pkg-config modules or
+additionally can be detected via a config tool (cups-config, llvm-config,
+etc). Meson has native support for these tools, and they can be found like other
+dependencies:
+
+```meson
+pcap_dep = dependency('pcap', version : '>=1.0')
+cups_dep = dependency('cups', version : '>=1.4')
+llvm_dep = dependency('llvm', version : '>=4.0')
+```
+
## AppleFrameworks
Use the `modules` keyword to list frameworks required, e.g.
@@ -119,6 +151,8 @@ Use the `modules` keyword to list frameworks required, e.g.
dep = find_dep('appleframeworks', modules : 'foundation')
```
+These dependencies can never be found for non-OSX hosts.
+
## Boost
Boost is not a single dependency but rather a group of different
@@ -148,10 +182,16 @@ environment variables.
You can set the argument `threading` to `single` to use boost libraries that
have been compiled for single-threaded use instead.
+## CUPS
+
+`method` may be `auto`, `config-tool`, `pkg-config` or `extraframework`.
+
## GL
This finds the OpenGL library in a way appropriate to the platform.
+`method` may be `auto`, `pkg-config` or `system`.
+
## GTest and GMock
GTest and GMock come as sources that must be compiled as part of your
@@ -167,8 +207,46 @@ gtest_dep = dependency('gtest', main : true, required : false)
e = executable('testprog', 'test.cc', dependencies : gtest_dep)
test('gtest test', e)
```
+
+## libwmf
+
+*(added 0.44.0)*
+
+`method` may be `auto`, `config-tool` or `pkg-config`.
+
+## LLVM
+
+Meson has native support for LLVM going back to version LLVM version 3.5.
+It supports a few additional features compared to other config-tool based
+dependencies.
+
+As of 0.44.0 Meson supports the `static` keyword argument for LLVM. Before this
+LLVM >= 3.9 would always dynamically link, while older versions would
+statically link, due to a quirk in `llvm-config`.
+
+### Modules, a.k.a. Components
+
+Meson wraps LLVM's concept of components in it's own modules concept.
+When you need specific components you add them as modules as meson will do the
+right thing:
+
+```meson
+llvm_dep = dependency('llvm', version : '>= 4.0', modules : ['amdgpu'])
+```
+
+As of 0.44.0 it can also take optional modules (these will affect the arguments
+generated for a static link):
+
+```meson
+llvm_dep = dependency(
+ 'llvm', version : '>= 4.0', modules : ['amdgpu'], optional_modules : ['inteljitevents'],
+)
+```
+
## MPI
+*(added 0.42.0)*
+
MPI is supported for C, C++ and Fortran. Because dependencies are
language-specific, you must specify the requested language using the
`language` keyword argument, i.e.,
@@ -185,11 +263,33 @@ environment variables `MPICC`, `MPICXX`, `MPIFC`, `MPIF90`, or
## OpenMP
+*(added 0.46.0)*
+
This dependency selects the appropriate compiler flags and/or libraries to use
for OpenMP support.
The `language` keyword may used.
+## pcap
+
+*(added 0.42.0)*
+
+`method` may be `auto`, `config-tool` or `pkg-config`.
+
+## Python3
+
+Python3 is handled specially by meson:
+1. Meson tries to use `pkg-config`.
+1. If `pkg-config` fails meson uses a fallback:
+ - On Windows the fallback is the current `python3` interpreter.
+ - On OSX the fallback is a framework dependency from `/Library/Frameworks`.
+
+Note that `python3` found by this dependency might differ from the one used in
+`python3` module because modules uses the current interpreter, but dependency tries
+`pkg-config` first.
+
+`method` may be `auto`, `extraframework`, `pkg-config` or `sysconfig`
+
## Qt4 & Qt5
Meson has native Qt support. Its usage is best demonstrated with an
@@ -229,11 +329,15 @@ include path of the given module(s) to the compiler flags. (since v0.47.0)
**Note** using private headers in your project is a bad idea, do so at your own
risk.
+`method` may be `auto`, `pkgconfig` or `qmake`.
+
## SDL2
SDL2 can be located using `pkg-confg`, the `sdl2-config` config tool, or as an
OSX framework.
+`method` may be `auto`, `config-tool`, `extraframework` or `pkg-config`.
+
## Threads
This dependency selects the appropriate compiler flags and/or libraries to use
@@ -248,27 +352,11 @@ and avoids trying to link with it's non-PIC static libs.
## Vulkan
-Vulkan can be located using `pkg-config`, or the `VULKAN_SDK` environment variable.
-
-## Dependencies using config tools
-
-CUPS, LLVM, PCAP, [WxWidgets](#wxwidgets), libwmf, and GnuStep either do not
-provide pkg-config modules or additionally can be detected via a config tool
-(cups-config, llvm-config, etc). Meson has native support for these tools, and
-they can be found like other dependencies:
+*(added 0.42.0)*
-```meson
-pcap_dep = dependency('pcap', version : '>=1.0')
-cups_dep = dependency('cups', version : '>=1.4')
-llvm_dep = dependency('llvm', version : '>=4.0')
-```
-
-Some of these tools (like wmf and cups) provide both pkg-config and config
-tools support. You can force one or another via the method keyword:
+Vulkan can be located using `pkg-config`, or the `VULKAN_SDK` environment variable.
-```meson
-wmf_dep = dependency('wmf', method : 'config-tool')
-```
+`method` may be `auto`, `pkg-config` or `system`.
## WxWidgets
@@ -294,43 +382,6 @@ $ wx-config --cxxflags std stc
$ wx-config --libs std stc
```
-## LLVM
-
-Meson has native support for LLVM going back to version LLVM version 3.5.
-It supports a few additional features compared to other config-tool based
-dependencies.
-
-As of 0.44.0 Meson supports the `static` keyword argument for LLVM. Before this
-LLVM >= 3.9 would always dynamically link, while older versions would
-statically link, due to a quirk in `llvm-config`.
-
-### Modules, a.k.a. Components
-
-Meson wraps LLVM's concept of components in it's own modules concept.
-When you need specific components you add them as modules as meson will do the
-right thing:
-
-```meson
-llvm_dep = dependency('llvm', version : '>= 4.0', modules : ['amdgpu'])
-```
-
-As of 0.44.0 it can also take optional modules (these will affect the arguments
-generated for a static link):
-
-```meson
-llvm_dep = dependency(
- 'llvm', version : '>= 4.0', modules : ['amdgpu'], optional_modules : ['inteljitevents'],
-)
-```
-
-## Python3
-
-Python3 is handled specially by meson:
-1. Meson tries to use `pkg-config`.
-1. If `pkg-config` fails meson uses a fallback:
- - On Windows the fallback is the current `python3` interpreter.
- - On OSX the fallback is a framework dependency from `/Library/Frameworks`.
-
-Note that `python3` found by this dependency might differ from the one used in
-`python3` module because modules uses the current interpreter, but dependency tries
-`pkg-config` first.
+<hr>
+<a name="footnote1">1</a>: They may appear to be case-insensitive, if the
+ underlying file system happens to be case-insensitive.
diff --git a/docs/markdown/Gnome-module.md b/docs/markdown/Gnome-module.md
index 1bf333f..634fe79 100644
--- a/docs/markdown/Gnome-module.md
+++ b/docs/markdown/Gnome-module.md
@@ -234,6 +234,8 @@ one XML file.
* `sources`: list of XML files
* `interface_prefix`: prefix for the interface
* `namespace`: namespace of the interface
+* `extra_args`: (*Added 0.47.0*) additional command line arguments to pass
+* `autocleanup`: *(Added 0.47.0)* if set generates autocleanup code. Can be one of `none`, `objects` or `all`
* `object_manager`: *(Added 0.40.0)* if true generates object manager code
* `annotations`: *(Added 0.43.0)* list of lists of 3 strings for the annotation for `'ELEMENT', 'KEY', 'VALUE'`
* `docbook`: *(Added 0.43.0)* prefix to generate `'PREFIX'-NAME.xml` docbooks
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index a5733a2..9829781 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -214,6 +214,9 @@ the `@variable@` syntax.
was specified. It defaults to `c`, in which case preprocessor directives
will be prefixed with `#`, you can also use `nasm`, in which case the
prefix will be `%`.
+- `encoding` *(added v0.47.0)* set the file encoding for the input and output file,
+ defaults to utf-8. The supported encodings are those of python3, see
+ [standard-encodings](https://docs.python.org/3/library/codecs.html#standard-encodings).
### custom_target()
@@ -343,8 +346,9 @@ otherwise. This function supports the following keyword arguments:
dependency to find if it's available for multiple languages.
- `method` defines the way the dependency is detected, the default is
`auto` but can be overridden to be e.g. `qmake` for Qt development,
- and different dependencies support different values for this (though
- `auto` will work on all of them)
+ and [different dependencies support different values](
+ Dependencies.md#dependencies-with-custom-lookup-functionality)
+ for this (though `auto` will work on all of them)
- `native` if set to `true`, causes Meson to find the dependency on
the build machine system rather than the host system (i.e. where the
cross compiled binary will run on), usually only needed if you build
@@ -1161,6 +1165,10 @@ variables defined in the [`executable`](#executable) it is loaded by,
you will need to set the `export_dynamic` argument of the executable to
`true`.
+**Note:** Linking to a shared module is not supported on some platforms, notably
+OSX. Consider using a [`shared_library`](#shared_library) instead, if you need
+to both `dlopen()` and link with a library.
+
*Added 0.37.0*
### static_library()
@@ -1567,6 +1575,8 @@ the following methods:
- `get_define(definename)` returns the given preprocessor symbol's
value as a string or empty string if it is not defined.
+ Starting with 0.47.0, this method will concatenate string literals as
+ the compiler would. E.g. `"a" "b"` will become `"ab"`.
- `get_id()` returns a string identifying the compiler. For example,
`gcc`, `msvc`, [and more](Reference-tables.html#compiler-ids).
diff --git a/docs/markdown/Release-notes-for-0.44.0.md b/docs/markdown/Release-notes-for-0.44.0.md
index 56956d7..d765940 100644
--- a/docs/markdown/Release-notes-for-0.44.0.md
+++ b/docs/markdown/Release-notes-for-0.44.0.md
@@ -145,3 +145,9 @@ myprog = find_program('myscript.py')
```
Then Meson will run the script with its internal Python version if necessary.
+
+## Libwmf dependency now supports libwmf-config
+
+Earlier, `dependency('libwmf')` could only detect the library with pkg-config
+files. Now, if pkg-config files are not found, Meson will look for
+`libwmf-config` and if it's found, will use that to find the library.
diff --git a/docs/markdown/Release-notes-for-0.47.0.md b/docs/markdown/Release-notes-for-0.47.0.md
index 58d47ee..fa4a34c 100644
--- a/docs/markdown/Release-notes-for-0.47.0.md
+++ b/docs/markdown/Release-notes-for-0.47.0.md
@@ -21,3 +21,9 @@ 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.
+
+## Concatenate string literals returned from get_define
+
+After obtaining the value of a preprocessor symbol consecutive string literals
+are merged into a single string literal.
+For example a preprocessor symbol's value `"ab" "cd"` is returned as `"abcd"`.
diff --git a/docs/markdown/snippets/configure_file_encoding.md b/docs/markdown/snippets/configure_file_encoding.md
new file mode 100644
index 0000000..8082177
--- /dev/null
+++ b/docs/markdown/snippets/configure_file_encoding.md
@@ -0,0 +1,12 @@
+## New encoding keyword for configure_file
+
+Add a new keyword to [`configure_file()`](#Reference-manual.md#configure_file)
+that allows the developer to specify the input and output file encoding.
+
+If the file encoding of the input is not UTF-8 meson can crash (see #1542).
+A crash as with UTF-16 is the best case and the worst meson will silently
+corrupt the output file for example with ISO-2022-JP. For additional details
+see pull request #3135.
+
+The new keyword defaults to UTF-8 and the documentation strongly suggest to
+convert the file to UTF-8 when possible.
diff --git a/docs/markdown/snippets/gdbus_codegen_options.md b/docs/markdown/snippets/gdbus_codegen_options.md
new file mode 100644
index 0000000..d3dd84c
--- /dev/null
+++ b/docs/markdown/snippets/gdbus_codegen_options.md
@@ -0,0 +1,14 @@
+## New options to gnome.gdbus_codegen
+
+You can now pass additional arguments to gdbus-codegen using the `extra_args`
+keyword. This is the same for the other gnome function calls.
+
+Meson now automatically adds autocleanup support to the generated code. This
+can be modified by setting the autocleanup keyword.
+
+For example:
+
+ sources += gnome.gdbus_codegen('com.mesonbuild.Test',
+ 'com.mesonbuild.Test.xml',
+ autocleanup : 'none',
+ extra_args : ['--pragma-once'])
diff --git a/meson.py b/meson.py
index dc84b51..dab08d3 100755
--- a/meson.py
+++ b/meson.py
@@ -21,7 +21,7 @@ from pathlib import Path
# we always import the correct mesonbuild modules even if PYTHONPATH is mangled
meson_exe = Path(sys.argv[0]).resolve()
if (meson_exe.parent / 'mesonbuild').is_dir():
- sys.path.insert(0, meson_exe.parent)
+ sys.path.insert(0, str(meson_exe.parent))
from mesonbuild import mesonmain
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 14e0fc3..ef677a9 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -331,7 +331,14 @@ class Backend:
l, stdlib_args = target.get_clike_dynamic_linker_and_stdlibs()
return l, stdlib_args
- def rpaths_for_bundled_shared_libraries(self, target):
+ @staticmethod
+ def _libdir_is_system(libdir, compilers):
+ for cc in compilers.values():
+ if libdir in cc.get_library_dirs():
+ return True
+ return False
+
+ def rpaths_for_bundled_shared_libraries(self, target, exclude_system=True):
paths = []
for dep in target.external_deps:
if not isinstance(dep, (dependencies.ExternalLibrary, dependencies.PkgConfigDependency)):
@@ -341,20 +348,20 @@ class Backend:
continue
# The only link argument is an absolute path to a library file.
libpath = la[0]
- if libpath.startswith(('/usr/lib', '/lib')):
+ libdir = os.path.dirname(libpath)
+ if exclude_system and self._libdir_is_system(libdir, target.compilers):
# No point in adding system paths.
continue
# Windows doesn't support rpaths, but we use this function to
# emulate rpaths by setting PATH, so also accept DLLs here
if os.path.splitext(libpath)[1] not in ['.dll', '.lib', '.so', '.dylib']:
continue
- absdir = os.path.dirname(libpath)
- if absdir.startswith(self.environment.get_source_dir()):
- rel_to_src = absdir[len(self.environment.get_source_dir()) + 1:]
+ if libdir.startswith(self.environment.get_source_dir()):
+ rel_to_src = libdir[len(self.environment.get_source_dir()) + 1:]
assert not os.path.isabs(rel_to_src), 'rel_to_src: {} is absolute'.format(rel_to_src)
paths.append(os.path.join(self.build_to_src, rel_to_src))
else:
- paths.append(absdir)
+ paths.append(libdir)
return paths
def determine_rpath_dirs(self, target):
@@ -594,7 +601,7 @@ class Backend:
if isinstance(target, build.BuildTarget):
prospectives.update(target.get_transitive_link_deps())
# External deps
- for deppath in self.rpaths_for_bundled_shared_libraries(target):
+ for deppath in self.rpaths_for_bundled_shared_libraries(target, exclude_system=False):
result.add(os.path.normpath(os.path.join(self.environment.get_build_dir(), deppath)))
for bdep in extra_bdeps:
prospectives.update(bdep.get_transitive_link_deps())
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 0398401..a773439 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -747,7 +747,7 @@ int dummy;
# On toolchains/platforms that use an import library for
# linking (separate from the shared library with all the
# code), we need to install that too (dll.a/.lib).
- if (isinstance(t, build.SharedLibrary) or isinstance(t, build.Executable)) and t.get_import_filename():
+ if isinstance(t, (build.SharedLibrary, build.SharedModule, build.Executable)) and t.get_import_filename():
if custom_install_dir:
# If the DLL is installed into a custom directory,
# install the import library into the same place so
@@ -1258,11 +1258,17 @@ int dummy;
def generate_rust_target(self, target, outfile):
rustc = target.compilers['rust']
- relsrc = []
+ # Rust compiler takes only the main file as input and
+ # figures out what other files are needed via import
+ # statements and magic.
+ main_rust_file = None
for i in target.get_sources():
if not rustc.can_compile(i):
raise InvalidArguments('Rust target %s contains a non-rust source file.' % target.get_basename())
- relsrc.append(i.rel_to_builddir(self.build_to_src))
+ if main_rust_file is None:
+ main_rust_file = i.rel_to_builddir(self.build_to_src)
+ if main_rust_file is None:
+ raise RuntimeError('A Rust target has no Rust sources. This is weird. Also a bug. Please report')
target_name = os.path.join(target.subdir, target.get_filename())
args = ['--crate-type']
if isinstance(target, build.Executable):
@@ -1329,7 +1335,7 @@ int dummy;
if target.is_cross:
crstr = '_CROSS'
compiler_name = 'rust%s_COMPILER' % crstr
- element = NinjaBuildElement(self.all_outputs, target_name, compiler_name, relsrc)
+ element = NinjaBuildElement(self.all_outputs, target_name, compiler_name, main_rust_file)
if len(orderdeps) > 0:
element.add_orderdep(orderdeps)
element.add_item('ARGS', args)
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index dc2660b..d42e91d 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -282,7 +282,7 @@ class Vs2010Backend(backends.Backend):
for dep in all_deps.keys():
guid = self.environment.coredata.target_guids[dep]
ofile.write('\t\t{%s} = {%s}\n' % (guid, guid))
- ofile.write('EndProjectSection\n')
+ ofile.write('\tEndProjectSection\n')
ofile.write('EndProject\n')
for dep, target in recursive_deps.items():
if prj[0] in default_projlist:
@@ -345,8 +345,12 @@ class Vs2010Backend(backends.Backend):
ofile.write('EndGlobal\n')
def generate_projects(self):
+ startup_project = self.environment.coredata.backend_options['backend_startup_project'].value
projlist = []
- for name, target in self.build.targets.items():
+ startup_idx = 0
+ for (i, (name, target)) in enumerate(self.build.targets.items()):
+ if startup_project and startup_project == target.get_basename():
+ startup_idx = i
outdir = Path(
self.environment.get_build_dir(),
self.get_target_dir(target)
@@ -359,6 +363,11 @@ class Vs2010Backend(backends.Backend):
proj_uuid = self.environment.coredata.target_guids[name]
self.gen_vcxproj(target, str(projfile_path), proj_uuid)
projlist.append((name, relname, proj_uuid))
+
+ # Put the startup project first in the project list
+ if startup_idx:
+ projlist = [projlist[startup_idx]] + projlist[0:startup_idx] + projlist[startup_idx + 1:-1]
+
return projlist
def split_sources(self, srclist):
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 4b42365..331b552 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -1086,8 +1086,12 @@ You probably should put it in link_with instead.''')
'''
for link_target in self.link_targets:
if isinstance(link_target, SharedModule):
- mlog.warning('''target links against shared modules. This is not
-recommended as it can lead to undefined behaviour on some platforms''')
+ if for_darwin(self.is_cross, self.environment):
+ raise MesonException('''target links against shared modules.
+This is not permitted on OSX''')
+ else:
+ mlog.warning('''target links against shared modules. This is not
+recommended as it is not supported on some platforms''')
return
class Generator:
@@ -1621,7 +1625,6 @@ class SharedModule(SharedLibrary):
if 'soversion' in kwargs:
raise MesonException('Shared modules must not specify the soversion kwarg.')
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs)
- self.import_filename = None
class CustomTarget(Target):
known_kwargs = set([
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index 90105a0..ef67e03 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import subprocess, os.path
+import subprocess, os.path, re
from .. import mlog
from .. import coredata
@@ -46,6 +46,7 @@ from .compilers import (
class CCompiler(Compiler):
library_dirs_cache = {}
program_dirs_cache = {}
+ find_library_cache = {}
def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwargs):
# If a child ObjC or CPP class has already set it, don't set it ourselves
@@ -566,8 +567,9 @@ class CCompiler(Compiler):
if p.returncode != 0:
raise EnvironmentException('Could not get define {!r}'.format(dname))
# Get the preprocessed value after the delimiter,
- # minus the extra newline at the end
- return p.stdo.split(delim + '\n')[-1][:-1]
+ # minus the extra newline at the end and
+ # merge string literals.
+ return CCompiler.concatenate_string_literals(p.stdo.split(delim + '\n')[-1][:-1])
def get_return_value(self, fname, rtype, prefix, env, extra_args, dependencies):
if rtype == 'string':
@@ -837,13 +839,8 @@ class CCompiler(Compiler):
raise AssertionError('BUG: unknown libtype {!r}'.format(libtype))
return prefixes, suffixes
- def find_library_impl(self, libname, env, extra_dirs, code, libtype='default'):
- # These libraries are either built-in or invalid
- if libname in self.ignore_libs:
- return []
+ def find_library_real(self, libname, env, extra_dirs, code, libtype):
# First try if we can just add the library as -l.
- if extra_dirs and isinstance(extra_dirs, str):
- extra_dirs = [extra_dirs]
# Gcc + co seem to prefer builtin lib dirs to -L dirs.
# Only try to find std libs if no extra dirs specified.
if not extra_dirs and libtype == 'default':
@@ -866,6 +863,22 @@ class CCompiler(Compiler):
return [trial]
return None
+ def find_library_impl(self, libname, env, extra_dirs, code, libtype):
+ # These libraries are either built-in or invalid
+ if libname in self.ignore_libs:
+ return []
+ if isinstance(extra_dirs, str):
+ extra_dirs = [extra_dirs]
+ key = (tuple(self.exelist), libname, tuple(extra_dirs), code, libtype)
+ if key not in self.find_library_cache:
+ value = self.find_library_real(libname, env, extra_dirs, code, libtype)
+ self.find_library_cache[key] = value
+ else:
+ value = self.find_library_cache[key]
+ if value is None:
+ return None
+ return value[:]
+
def find_library(self, libname, env, extra_dirs, libtype='default'):
code = 'int main(int argc, char **argv) { return 0; }'
return self.find_library_impl(libname, env, extra_dirs, code, libtype)
@@ -921,6 +934,16 @@ class CCompiler(Compiler):
code = 'int main(int argc, char **argv) { return 0; }'
return self.has_arguments(args, env, code, mode='link')
+ @staticmethod
+ def concatenate_string_literals(s):
+ pattern = re.compile(r'(?P<pre>.*([^\\]")|^")(?P<str1>([^\\"]|\\.)*)"\s+"(?P<str2>([^\\"]|\\.)*)(?P<post>".*)')
+ ret = s
+ m = pattern.match(ret)
+ while m:
+ ret = ''.join(m.group('pre', 'str1', 'str2', 'post'))
+ m = pattern.match(ret)
+ return ret
+
class ClangCCompiler(ClangCompiler, CCompiler):
def __init__(self, exelist, version, clang_type, is_cross, exe_wrapper=None, **kwargs):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs)
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index 0022b67..4cea6d4 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -50,9 +50,9 @@ cpp_suffixes = lang_suffixes['cpp'] + ('h',)
c_suffixes = lang_suffixes['c'] + ('h',)
# List of languages that can be linked with C code directly by the linker
# used in build.py:process_compilers() and build.py:get_dynamic_linker()
-clike_langs = ('d', 'objcpp', 'cpp', 'objc', 'c', 'fortran',)
+clike_langs = ('d', 'objcpp', 'cpp', 'objc', 'c', 'fortran', )
clike_suffixes = ()
-for _l in clike_langs:
+for _l in clike_langs + ('vala',):
clike_suffixes += lang_suffixes[_l]
clike_suffixes += ('h', 'll', 's')
diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py
index d0b538a..11d07b8 100644
--- a/mesonbuild/compilers/fortran.py
+++ b/mesonbuild/compilers/fortran.py
@@ -23,6 +23,8 @@ from .compilers import (
class FortranCompiler(Compiler):
library_dirs_cache = CCompiler.library_dirs_cache
+ program_dirs_cache = CCompiler.library_dirs_cache
+ find_library_cache = CCompiler.library_dirs_cache
def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwargs):
self.language = 'fortran'
@@ -174,11 +176,17 @@ class FortranCompiler(Compiler):
def get_library_naming(self, env, libtype, strict=False):
return CCompiler.get_library_naming(self, env, libtype, strict)
+ def find_library_real(self, *args):
+ return CCompiler.find_library_real(self, *args)
+
+ def find_library_impl(self, *args):
+ return CCompiler.find_library_impl(self, *args)
+
def find_library(self, libname, env, extra_dirs, libtype='default'):
code = '''program main
call exit(0)
end program main'''
- return CCompiler.find_library_impl(self, libname, env, extra_dirs, code, libtype)
+ return self.find_library_impl(libname, env, extra_dirs, code, libtype)
def thread_flags(self, env):
return CCompiler.thread_flags(self, env)
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 2d44b99..4db8e4a 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -236,7 +236,7 @@ class CoreData:
if os.path.isabs(filename):
return filename
path_to_try = os.path.abspath(filename)
- if os.path.exists(path_to_try):
+ if os.path.isfile(path_to_try):
return path_to_try
if sys.platform != 'win32':
paths = [
@@ -244,7 +244,7 @@ class CoreData:
] + os.environ.get('XDG_DATA_DIRS', '/usr/local/share:/usr/share').split(':')
for path in paths:
path_to_try = os.path.join(path, 'meson', 'cross', filename)
- if os.path.exists(path_to_try):
+ if os.path.isfile(path_to_try):
return path_to_try
raise MesonException('Cannot find specified cross file: ' + filename)
@@ -303,9 +303,19 @@ class CoreData:
def init_backend_options(self, backend_name):
if backend_name == 'ninja':
- self.backend_options['backend_max_links'] = UserIntegerOption('backend_max_links',
- 'Maximum number of linker processes to run or 0 for no limit',
- 0, None, 0)
+ self.backend_options['backend_max_links'] = \
+ UserIntegerOption(
+ 'backend_max_links',
+ 'Maximum number of linker processes to run or 0 for no '
+ 'limit',
+ 0, None, 0)
+ elif backend_name.startswith('vs'):
+ self.backend_options['backend_startup_project'] = \
+ UserStringOption(
+ 'backend_startup_project',
+ 'Default project to execute in Visual Studio',
+ '')
+
def get_builtin_option(self, optname):
if optname in self.builtins:
diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py
index a628151..37195cc 100644
--- a/mesonbuild/dependencies/misc.py
+++ b/mesonbuild/dependencies/misc.py
@@ -517,6 +517,7 @@ class CupsDependency(ExternalDependency):
class LibWmfDependency(ExternalDependency):
+ @FeatureNew('LibWMF Dependency', '0.44.0')
def __init__(self, environment, kwargs):
super().__init__('libwmf', environment, None, kwargs)
diff --git a/mesonbuild/dependencies/ui.py b/mesonbuild/dependencies/ui.py
index 1f8c3f5..44fdcd5 100644
--- a/mesonbuild/dependencies/ui.py
+++ b/mesonbuild/dependencies/ui.py
@@ -238,7 +238,7 @@ class QtBaseDependency(ExternalDependency):
def compilers_detect(self):
"Detect Qt (4 or 5) moc, uic, rcc in the specified bindir or in PATH"
- if self.bindir:
+ if self.bindir or for_windows(self.env.is_cross_build(), self.env):
moc = ExternalProgram(os.path.join(self.bindir, 'moc'), silent=True)
uic = ExternalProgram(os.path.join(self.bindir, 'uic'), silent=True)
rcc = ExternalProgram(os.path.join(self.bindir, 'rcc'), silent=True)
@@ -347,7 +347,7 @@ class QtBaseDependency(ExternalDependency):
for dir in priv_inc:
self.compile_args.append('-I' + dir)
if for_windows(self.env.is_cross_build(), self.env):
- is_debug = self.env.coredata.get_builtin_option('buildtype').startswith('debug')
+ is_debug = self.env.coredata.get_builtin_option('buildtype') == 'debug'
dbg = 'd' if is_debug else ''
if self.qtver == '4':
base_name = 'Qt' + module + dbg + '4'
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 86c55e4..421ddd9 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -1724,7 +1724,7 @@ permitted_kwargs = {'add_global_arguments': {'language'},
'add_test_setup': {'exe_wrapper', 'gdb', 'timeout_multiplier', 'env'},
'benchmark': {'args', 'env', 'should_fail', 'timeout', 'workdir', 'suite'},
'build_target': known_build_target_kwargs,
- 'configure_file': {'input', 'output', 'configuration', 'command', 'copy', 'install_dir', 'install_mode', 'capture', 'install', 'format', 'output_format'},
+ 'configure_file': {'input', 'output', 'configuration', 'command', 'copy', 'install_dir', 'install_mode', 'capture', 'install', 'format', 'output_format', 'encoding'},
'custom_target': {'input', 'output', 'command', 'install', 'install_dir', 'install_mode', 'build_always', 'capture', 'depends', 'depend_files', 'depfile', 'build_by_default'},
'dependency': {'default_options', 'fallback', 'language', 'main', 'method', 'modules', 'optional_modules', 'native', 'required', 'static', 'version', 'private_headers'},
'declare_dependency': {'include_directories', 'link_with', 'sources', 'dependencies', 'compile_args', 'link_args', 'link_whole', 'version'},
@@ -2269,7 +2269,10 @@ to directly access options of other subprojects.''')
else:
raise InterpreterException('Unknown backend "%s".' % backend)
- self.coredata.init_backend_options(backend)
+ # Only init backend options on first invocation otherwise it would
+ # override values previously set from command line.
+ if self.environment.first_invocation:
+ self.coredata.init_backend_options(backend)
options = {k: v for k, v in self.environment.cmd_line_options.items() if k.startswith('backend_')}
self.coredata.set_options(options)
@@ -2289,9 +2292,16 @@ to directly access options of other subprojects.''')
oi.process(self.option_file)
self.coredata.merge_user_options(oi.options)
- default_options = mesonlib.stringlistify(kwargs.get('default_options', []))
- default_options = coredata.create_options_dict(default_options)
- default_options.update(self.default_project_options)
+ # Do not set default_options on reconfigure otherwise it would override
+ # values previously set from command line. That means that changing
+ # default_options in a project will trigger a reconfigure but won't
+ # have any effect.
+ if self.environment.first_invocation:
+ default_options = mesonlib.stringlistify(kwargs.get('default_options', []))
+ default_options = coredata.create_options_dict(default_options)
+ default_options.update(self.default_project_options)
+ else:
+ default_options = {}
self.set_options(default_options)
self.set_backend()
@@ -3128,7 +3138,10 @@ root and issuing %s.
except mesonlib.MesonException as me:
me.file = buildfilename
raise me
- self.evaluate_codeblock(codeblock)
+ try:
+ self.evaluate_codeblock(codeblock)
+ except SubdirDoneRequest:
+ pass
self.subdir = prev_subdir
def _get_kwarg_install_mode(self, kwargs):
@@ -3218,7 +3231,7 @@ root and issuing %s.
self.build.install_dirs.append(idir)
return idir
- @FeatureNewKwargs('configure_file', '0.47.0', ['copy', 'output_format', 'install_mode'])
+ @FeatureNewKwargs('configure_file', '0.47.0', ['copy', 'output_format', 'install_mode', 'encoding'])
@FeatureNewKwargs('configure_file', '0.46.0', ['format'])
@FeatureNewKwargs('configure_file', '0.41.0', ['capture'])
@permittedKwargs(permitted_kwargs['configure_file'])
@@ -3319,8 +3332,10 @@ root and issuing %s.
mlog.log('Configuring', mlog.bold(output), 'using configuration')
if inputfile is not None:
os.makedirs(os.path.join(self.environment.build_dir, self.subdir), exist_ok=True)
+ file_encoding = kwargs.setdefault('encoding', 'utf-8')
missing_variables = mesonlib.do_conf_file(ifile_abs, ofile_abs,
- conf.held_object, fmt)
+ conf.held_object, fmt,
+ file_encoding)
if missing_variables:
var_list = ", ".join(map(repr, sorted(missing_variables)))
mlog.warning(
@@ -3347,7 +3362,8 @@ root and issuing %s.
(res.stdout, res.stderr))
if 'capture' in kwargs and kwargs['capture']:
dst_tmp = ofile_abs + '~'
- with open(dst_tmp, 'w', encoding='utf-8') as f:
+ file_encoding = kwargs.setdefault('encoding', 'utf-8')
+ with open(dst_tmp, 'w', encoding=file_encoding) as f:
f.writelines(res.stdout)
if ifile_abs:
shutil.copymode(ifile_abs, dst_tmp)
diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py
index a908732..1c61345 100644
--- a/mesonbuild/interpreterbase.py
+++ b/mesonbuild/interpreterbase.py
@@ -326,7 +326,10 @@ class InterpreterBase:
def run(self):
# Evaluate everything after the first line, which is project() because
# we already parsed that in self.parse_project()
- self.evaluate_codeblock(self.ast, start=1)
+ try:
+ self.evaluate_codeblock(self.ast, start=1)
+ except SubdirDoneRequest:
+ pass
def evaluate_codeblock(self, node, start=0, end=None):
if node is None:
@@ -343,8 +346,6 @@ class InterpreterBase:
try:
self.current_lineno = cur.lineno
self.evaluate_statement(cur)
- except SubdirDoneRequest:
- break
except Exception as e:
if not(hasattr(e, 'lineno')):
e.lineno = cur.lineno
diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py
index 9f1da3e..e4951f9 100644
--- a/mesonbuild/mesonlib.py
+++ b/mesonbuild/mesonlib.py
@@ -623,9 +623,9 @@ def do_mesondefine(line, confdata):
raise MesonException('#mesondefine argument "%s" is of unknown type.' % varname)
-def do_conf_file(src, dst, confdata, format):
+def do_conf_file(src, dst, confdata, format, encoding='utf-8'):
try:
- with open(src, encoding='utf-8') as f:
+ with open(src, encoding=encoding) as f:
data = f.readlines()
except Exception as e:
raise MesonException('Could not read input file %s: %s' % (src, str(e)))
@@ -652,8 +652,11 @@ def do_conf_file(src, dst, confdata, format):
missing_variables.update(missing)
result.append(line)
dst_tmp = dst + '~'
- with open(dst_tmp, 'w', encoding='utf-8') as f:
- f.writelines(result)
+ try:
+ with open(dst_tmp, 'w', encoding=encoding) as f:
+ f.writelines(result)
+ except Exception as e:
+ raise MesonException('Could not write output file %s: %s' % (dst, str(e)))
shutil.copymode(src, dst_tmp)
replace_if_different(dst, dst_tmp)
return missing_variables
diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py
index 57d70e7..5d60134 100644
--- a/mesonbuild/mintro.py
+++ b/mesonbuild/mintro.py
@@ -73,9 +73,9 @@ def list_installed(installdata):
res[os.path.join(installdata.build_dir, path)] = os.path.join(installdata.prefix, installdir, os.path.basename(path))
for path, installpath, unused_prefix in installdata.data:
res[path] = os.path.join(installdata.prefix, installpath)
- for path, installdir in installdata.headers:
+ for path, installdir, unused_custom_install_mode in installdata.headers:
res[path] = os.path.join(installdata.prefix, installdir, os.path.basename(path))
- for path, installpath in installdata.man:
+ for path, installpath, unused_custom_install_mode in installdata.man:
res[path] = os.path.join(installdata.prefix, installpath)
print(json.dumps(res))
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py
index 6db05ae..111e7f7 100644
--- a/mesonbuild/modules/gnome.py
+++ b/mesonbuild/modules/gnome.py
@@ -870,6 +870,8 @@ This will become a hard error in the future.''')
for i in new_args:
if expend_file_state and isinstance(i, mesonlib.File):
i = i.absolute_path(expend_file_state.environment.get_source_dir(), expend_file_state.environment.get_build_dir())
+ elif expend_file_state and isinstance(i, str):
+ i = os.path.join(expend_file_state.environment.get_source_dir(), expend_file_state.subdir, i)
elif not isinstance(i, str):
raise MesonException(kwarg_name + ' values must be strings.')
args.append(i)
@@ -881,7 +883,8 @@ This will become a hard error in the future.''')
@FeatureNewKwargs('build target', '0.46.0', ['install_header', 'install_dir', 'sources'])
@FeatureNewKwargs('build target', '0.40.0', ['build_by_default'])
- @permittedKwargs({'interface_prefix', 'namespace', 'object_manager', 'build_by_default',
+ @FeatureNewKwargs('build target', '0.47.0', ['extra_args', 'autocleanup'])
+ @permittedKwargs({'interface_prefix', 'namespace', 'extra_args', 'autocleanup', 'object_manager', 'build_by_default',
'annotations', 'docbook', 'install_header', 'install_dir', 'sources'})
def gdbus_codegen(self, state, args, kwargs):
if len(args) not in (1, 2):
@@ -890,6 +893,13 @@ This will become a hard error in the future.''')
xml_files = args[1:]
target_name = namebase + '-gdbus'
cmd = [self.interpreter.find_program_impl('gdbus-codegen')]
+ extra_args = mesonlib.stringlistify(kwargs.pop('extra_args', []))
+ cmd += extra_args
+ autocleanup = kwargs.pop('autocleanup', 'all')
+ if autocleanup not in ['none', 'objects', 'all']:
+ raise MesonException(
+ 'Gdbus_codegen does not support %s as an autocleanup value.' % (autocleanup, ))
+ cmd += ['--c-generate-autocleanup', autocleanup]
if 'interface_prefix' in kwargs:
cmd += ['--interface-prefix', kwargs.pop('interface_prefix')]
if 'namespace' in kwargs:
diff --git a/mesonbuild/scripts/gtkdochelper.py b/mesonbuild/scripts/gtkdochelper.py
index 2895991..fedcc47 100644
--- a/mesonbuild/scripts/gtkdochelper.py
+++ b/mesonbuild/scripts/gtkdochelper.py
@@ -122,7 +122,8 @@ def build_gtkdoc(source_root, build_root, doc_subdir, src_subdirs,
'--module=' + module,
'--cflags=' + cflags,
'--ldflags=' + ldflags,
- '--ld=' + ld]
+ '--ld=' + ld,
+ '--output-dir=' + abs_out]
library_paths = []
for ldflag in shlex.split(ldflags):
@@ -132,7 +133,7 @@ def build_gtkdoc(source_root, build_root, doc_subdir, src_subdirs,
library_paths.append(os.environ['LD_LIBRARY_PATH'])
library_path = ':'.join(library_paths)
- gtkdoc_run_check(scanobjs_cmd, abs_out, library_path)
+ gtkdoc_run_check(scanobjs_cmd, build_root, library_path)
# Make docbook files
if mode == 'auto':
diff --git a/run_tests.py b/run_tests.py
index d905e12..af20ba2 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -211,12 +211,7 @@ if __name__ == '__main__':
elif arg == '--backend=xcode':
backend = Backend.xcode
if arg.startswith('--cross'):
- if arg == '--cross=arm':
- cross = 'arm'
- elif arg == '--cross=mingw':
- cross = 'mingw'
- else:
- raise RuntimeError('Unknown cross tests selected')
+ cross = True
# Running on a developer machine? Be nice!
if not mesonlib.is_windows() and not mesonlib.is_haiku() and 'TRAVIS' not in os.environ:
os.nice(20)
@@ -254,12 +249,10 @@ if __name__ == '__main__':
returncode += subprocess.call(mesonlib.python_command + ['run_project_tests.py'] + sys.argv[1:], env=env)
else:
cross_test_args = mesonlib.python_command + ['run_cross_test.py']
- if cross == 'arm':
- print(mlog.bold('Running armhf cross tests.').get_text(mlog.colorize_console))
- print()
- returncode += subprocess.call(cross_test_args + ['cross/ubuntu-armhf.txt'], env=env)
- elif cross == 'mingw':
- print(mlog.bold('Running mingw-w64 64-bit cross tests.').get_text(mlog.colorize_console))
- print()
- returncode += subprocess.call(cross_test_args + ['cross/linux-mingw-w64-64bit.txt'], env=env)
+ print(mlog.bold('Running armhf cross tests.').get_text(mlog.colorize_console))
+ print()
+ returncode += subprocess.call(cross_test_args + ['cross/ubuntu-armhf.txt'], env=env)
+ print(mlog.bold('Running mingw-w64 64-bit cross tests.').get_text(mlog.colorize_console))
+ print()
+ returncode += subprocess.call(cross_test_args + ['cross/linux-mingw-w64-64bit.txt'], env=env)
sys.exit(returncode)
diff --git a/run_unittests.py b/run_unittests.py
index f17b69b..7c68904 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -1943,14 +1943,17 @@ int main(int argc, char **argv) {
exception_raised = True
self.assertTrue(exception_raised, 'Double locking did not raise exception.')
+ @unittest.skipIf(is_osx(), 'Test not applicable to OSX')
def test_check_module_linking(self):
"""
- Test that shared modules are not linked with targets(link_with:) #2865
+ Test that link_with: a shared module issues a warning
+ https://github.com/mesonbuild/meson/issues/2865
+ (That an error is raised on OSX is exercised by test failing/78)
"""
tdir = os.path.join(self.unit_test_dir, '26 shared_mod linking')
out = self.init(tdir)
msg = ('''WARNING: target links against shared modules. This is not
-recommended as it can lead to undefined behaviour on some platforms''')
+recommended as it is not supported on some platforms''')
self.assertIn(msg, out)
def test_ndebug_if_release_disabled(self):
@@ -2114,6 +2117,11 @@ recommended as it can lead to undefined behaviour on some platforms''')
self.setconf('--default-library=shared')
obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins['default_library'].value, 'shared')
+ if self.backend is Backend.ninja:
+ # reconfigure target works only with ninja backend
+ self.build('reconfigure')
+ obj = mesonbuild.coredata.load(self.builddir)
+ self.assertEqual(obj.builtins['default_library'].value, 'shared')
self.wipe()
# Should fail on unknown options
@@ -2911,6 +2919,9 @@ class LinuxlikeTests(BasePlatformTests):
self.assertEqual(want_mode, found_mode,
msg=('Expected file %s to have mode %s but found %s instead.' %
(fsobj, want_mode, found_mode)))
+ # Ensure that introspect --installed works on all types of files
+ # FIXME: also verify the files list
+ self.introspect('--installed')
def test_install_umask(self):
'''
diff --git a/test cases/common/140 get define/concat.h b/test cases/common/140 get define/concat.h
new file mode 100644
index 0000000..6eb3e5e
--- /dev/null
+++ b/test cases/common/140 get define/concat.h
@@ -0,0 +1,24 @@
+#define __STRINGIFY(x) #x
+#define TEST_STRINGIFY(x) __STRINGIFY(x)
+
+#define TEST_VERSION_MAJOR 6
+#define TEST_VERSION_MINOR 0
+#define TEST_VERSION_BUGFIX 0
+
+#define TEST_VERSION_STR \
+ TEST_STRINGIFY(TEST_VERSION_MAJOR) \
+ "." TEST_STRINGIFY(TEST_VERSION_MINOR) "." TEST_STRINGIFY( \
+ TEST_VERSION_BUGFIX)
+
+#define TEST_CONCAT_1 \
+ "ab" \
+ "cd" \
+ "ef" \
+ ""
+#define TEST_CONCAT_2 1
+#define TEST_CONCAT_3 1 2 3
+#define TEST_CONCAT_4 "ab" 1 "cd"
+#define TEST_CONCAT_5 \
+ "ab\"" \
+ "cd"
+#define TEST_CONCAT_6 "ab\" \"cd"
diff --git a/test cases/common/140 get define/meson.build b/test cases/common/140 get define/meson.build
index 9f5539b..b20c554 100644
--- a/test cases/common/140 get define/meson.build
+++ b/test cases/common/140 get define/meson.build
@@ -80,4 +80,22 @@ foreach lang : ['c', 'cpp']
have = cc.get_define('MESON_TEST_ISSUE_1665')
assert(have == '1', 'MESON_TEST_ISSUE_1665 value is "@0@" instead of "1"'.format(have))
endif
+
+ have = cc.get_define('TEST_VERSION_STR',
+ prefix : '#include <concat.h>', include_directories: include_directories('.'))
+ assert(have == '"6.0.0"', 'TEST_VERSION_STR value is "@0@" instead of ""6.0.0""'.format(have))
+
+ concat_examples = {
+ 'TEST_CONCAT_1': '"abcdef"',
+ 'TEST_CONCAT_2': '1',
+ 'TEST_CONCAT_3': '1 2 3',
+ 'TEST_CONCAT_4': '"ab" 1 "cd"',
+ 'TEST_CONCAT_5': '"ab\"cd"',
+ 'TEST_CONCAT_6': '"ab\" \"cd"',
+ }
+ foreach def,expected : concat_examples
+ have = cc.get_define(def,
+ prefix : '#include <concat.h>', include_directories: include_directories('.'))
+ assert(have == expected, '@0@ value is "@1@" instead of "@2@"'.format(def, have, expected))
+ endforeach
endforeach
diff --git a/test cases/common/16 configure file/config8.h.in b/test cases/common/16 configure file/config8.h.in
new file mode 100644
index 0000000..b854ea0
--- /dev/null
+++ b/test cases/common/16 configure file/config8.h.in
@@ -0,0 +1,3 @@
+#define MESSAGE "@var@"
+
+#define "non isolatin1 char Ä fails decode with utf-8"
diff --git a/test cases/common/16 configure file/meson.build b/test cases/common/16 configure file/meson.build
index 76ec8c6..333b121 100644
--- a/test cases/common/16 configure file/meson.build
+++ b/test cases/common/16 configure file/meson.build
@@ -174,3 +174,13 @@ ret = run_command(check_file, inf, outf)
if ret.returncode() != 0
error('Error running command: @0@\n@1@'.format(ret.stdout(), ret.stderr()))
endif
+
+# Test non isolatin1 encoded input file which fails to decode with utf-8
+conf8 = configuration_data()
+conf8.set('var', 'foo')
+configure_file(
+ input : 'config8.h.in',
+ output : '@BASENAME@',
+ encoding : 'koi8-r',
+ configuration : conf8
+)
diff --git a/test cases/common/188 subdir_done/meson.build b/test cases/common/188 subdir_done/meson.build
index 5692f3a..457e613 100644
--- a/test cases/common/188 subdir_done/meson.build
+++ b/test cases/common/188 subdir_done/meson.build
@@ -3,7 +3,9 @@
project('example exit', 'cpp')
-subdir_done()
+if true
+ subdir_done()
+endif
executable('main', 'main.cpp')
error('Unreachable')
diff --git a/test cases/failing/78 link with shared module on osx/meson.build b/test cases/failing/78 link with shared module on osx/meson.build
new file mode 100644
index 0000000..2c714f9
--- /dev/null
+++ b/test cases/failing/78 link with shared module on osx/meson.build
@@ -0,0 +1,8 @@
+project('link with shared module', 'c')
+
+if host_machine.system() != 'darwin'
+ error('Test only fails on OSX')
+endif
+
+m = shared_module('mymodule', 'module.c')
+e = executable('prog', 'prog.c', link_with : m)
diff --git a/test cases/failing/78 link with shared module on osx/module.c b/test cases/failing/78 link with shared module on osx/module.c
new file mode 100644
index 0000000..81b0d5a
--- /dev/null
+++ b/test cases/failing/78 link with shared module on osx/module.c
@@ -0,0 +1,3 @@
+int func(void) {
+ return 1496;
+}
diff --git a/test cases/failing/78 link with shared module on osx/prog.c b/test cases/failing/78 link with shared module on osx/prog.c
new file mode 100644
index 0000000..8164d8d
--- /dev/null
+++ b/test cases/failing/78 link with shared module on osx/prog.c
@@ -0,0 +1,4 @@
+
+int main(int argc, char **argv) {
+ return func();
+}
diff --git a/test cases/failing/79 non ascii in ascii encoded configure file/config9.h.in b/test cases/failing/79 non ascii in ascii encoded configure file/config9.h.in
new file mode 100644
index 0000000..323bec6
--- /dev/null
+++ b/test cases/failing/79 non ascii in ascii encoded configure file/config9.h.in
@@ -0,0 +1 @@
+#define MESSAGE "@var@"
diff --git a/test cases/failing/79 non ascii in ascii encoded configure file/meson.build b/test cases/failing/79 non ascii in ascii encoded configure file/meson.build
new file mode 100644
index 0000000..846daaf
--- /dev/null
+++ b/test cases/failing/79 non ascii in ascii encoded configure file/meson.build
@@ -0,0 +1,10 @@
+project('non acsii to ascii encoding', 'c')
+# Writing a non ASCII character with a ASCII encoding should fail
+conf9 = configuration_data()
+conf9.set('var', 'д')
+configure_file(
+ input : 'config9.h.in',
+ output : '@BASENAME@',
+ encoding : 'ascii',
+ configuration : conf9
+)
diff --git a/test cases/rust/8 many files/foo.rs b/test cases/rust/8 many files/foo.rs
new file mode 100644
index 0000000..0899dc0
--- /dev/null
+++ b/test cases/rust/8 many files/foo.rs
@@ -0,0 +1,3 @@
+pub fn bar() -> () {
+ println!("Hello, world!");
+}
diff --git a/test cases/rust/8 many files/main.rs b/test cases/rust/8 many files/main.rs
new file mode 100644
index 0000000..3ffeee2
--- /dev/null
+++ b/test cases/rust/8 many files/main.rs
@@ -0,0 +1,5 @@
+mod foo;
+
+fn main() {
+ foo::bar();
+}
diff --git a/test cases/rust/8 many files/meson.build b/test cases/rust/8 many files/meson.build
new file mode 100644
index 0000000..1d906b3
--- /dev/null
+++ b/test cases/rust/8 many files/meson.build
@@ -0,0 +1,3 @@
+project('manyfiles', 'rust')
+
+test('manyfiles', executable('manyfiles', 'main.rs', 'foo.rs'))
diff --git a/test cases/vala/25 extract_all_objects/meson.build b/test cases/vala/25 extract_all_objects/meson.build
new file mode 100644
index 0000000..a1a4ebc
--- /dev/null
+++ b/test cases/vala/25 extract_all_objects/meson.build
@@ -0,0 +1,11 @@
+project('valatest', 'vala', 'c')
+
+valadeps = [dependency('glib-2.0'), dependency('gobject-2.0')]
+
+# A dummy target, just so that we can check that extract_all_objects() works
+# properly for Vala sources. Due to a bug, Vala's .c.o files weren't included
+# which would cause the "e" executable below to have no "main" and fail to link.
+dummy = executable('valaprog_dummy', 'prog.vala', dependencies : valadeps, build_by_default: false)
+
+objs = dummy.extract_all_objects()
+e = executable('valaprog', objects: objs, dependencies : valadeps)
diff --git a/test cases/vala/25 extract_all_objects/prog.vala b/test cases/vala/25 extract_all_objects/prog.vala
new file mode 100644
index 0000000..638e776
--- /dev/null
+++ b/test cases/vala/25 extract_all_objects/prog.vala
@@ -0,0 +1,7 @@
+class MainProg : GLib.Object {
+
+ public static int main(string[] args) {
+ stdout.printf("Vala is working.\n");
+ return 0;
+ }
+}
diff --git a/test cases/vala/26 vala and asm/meson.build b/test cases/vala/26 vala and asm/meson.build
new file mode 100644
index 0000000..4e662e7
--- /dev/null
+++ b/test cases/vala/26 vala and asm/meson.build
@@ -0,0 +1,23 @@
+project('vala and asm', 'vala', 'c')
+
+cpu = host_machine.cpu_family()
+cc = meson.get_compiler('c')
+
+supported_cpus = ['arm', 'x86', 'x86_64']
+
+if not supported_cpus.contains(cpu)
+ error('MESON_SKIP_TEST unsupported cpu:' + cpu)
+endif
+
+if meson.get_compiler('c').get_id() == 'msvc'
+ error('MESON_SKIP_TEST MSVC can\'t compile assembly')
+endif
+
+if cc.symbols_have_underscore_prefix()
+ add_project_arguments('-DMESON_TEST__UNDERSCORE_SYMBOL', language: 'c')
+endif
+
+valadeps = [dependency('glib-2.0'), dependency('gobject-2.0')]
+e = executable('vala-asm', ['prog.vala', 'retval-' + cpu + '.S'],
+ dependencies: valadeps)
+test('test-vala-asm', e)
diff --git a/test cases/vala/26 vala and asm/prog.vala b/test cases/vala/26 vala and asm/prog.vala
new file mode 100644
index 0000000..d5f89a4
--- /dev/null
+++ b/test cases/vala/26 vala and asm/prog.vala
@@ -0,0 +1,9 @@
+extern int get_retval();
+
+class MainProg : GLib.Object {
+
+ public static int main(string[] args) {
+ stdout.printf("Vala is working.\n");
+ return get_retval();
+ }
+}
diff --git a/test cases/vala/26 vala and asm/retval-arm.S b/test cases/vala/26 vala and asm/retval-arm.S
new file mode 100644
index 0000000..a892362
--- /dev/null
+++ b/test cases/vala/26 vala and asm/retval-arm.S
@@ -0,0 +1,11 @@
+#include "symbol-underscore.h"
+
+.text
+.globl SYMBOL_NAME(get_retval)
+# ifdef __linux__
+.type get_retval, %function
+#endif
+
+SYMBOL_NAME(get_retval):
+ mov r0, #0
+ mov pc, lr
diff --git a/test cases/vala/26 vala and asm/retval-x86.S b/test cases/vala/26 vala and asm/retval-x86.S
new file mode 100644
index 0000000..3cb0237
--- /dev/null
+++ b/test cases/vala/26 vala and asm/retval-x86.S
@@ -0,0 +1,12 @@
+#include "symbol-underscore.h"
+
+.text
+.globl SYMBOL_NAME(get_retval)
+/* Only supported on Linux with GAS */
+# ifdef __linux__
+.type get_retval, %function
+#endif
+
+SYMBOL_NAME(get_retval):
+ xorl %eax, %eax
+ retl
diff --git a/test cases/vala/26 vala and asm/retval-x86_64.S b/test cases/vala/26 vala and asm/retval-x86_64.S
new file mode 100644
index 0000000..1a5f3eb
--- /dev/null
+++ b/test cases/vala/26 vala and asm/retval-x86_64.S
@@ -0,0 +1,11 @@
+#include "symbol-underscore.h"
+
+.text
+.globl SYMBOL_NAME(get_retval)
+# ifdef __linux__
+.type get_retval, %function
+#endif
+
+SYMBOL_NAME(get_retval):
+ xorl %eax, %eax
+ retq
diff --git a/test cases/vala/26 vala and asm/symbol-underscore.h b/test cases/vala/26 vala and asm/symbol-underscore.h
new file mode 100644
index 0000000..d0f3ef9
--- /dev/null
+++ b/test cases/vala/26 vala and asm/symbol-underscore.h
@@ -0,0 +1,5 @@
+#if defined(MESON_TEST__UNDERSCORE_SYMBOL)
+# define SYMBOL_NAME(name) _##name
+#else
+# define SYMBOL_NAME(name) name
+#endif
diff --git a/test cases/windows/8 dll versioning/installed_files.txt b/test cases/windows/8 dll versioning/installed_files.txt
index a1e9b2d..20482bf 100644
--- a/test cases/windows/8 dll versioning/installed_files.txt
+++ b/test cases/windows/8 dll versioning/installed_files.txt
@@ -11,6 +11,7 @@
?msvc:usr/libexec/customdir.dll
?msvc:usr/libexec/customdir.lib
?msvc:usr/lib/module.dll
+?msvc:usr/lib/module.lib
?gcc:usr/bin/?libsome-0.dll
?gcc:usr/lib/libsome.dll.a
?gcc:usr/bin/?libnoversion.dll
@@ -22,3 +23,4 @@
?gcc:usr/libexec/?libcustomdir.dll
?gcc:usr/libexec/libcustomdir.dll.a
?gcc:usr/lib/?libmodule.dll
+?gcc:usr/lib/libmodule.dll.a