aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xci/appveyor-install.bat3
-rw-r--r--docs/markdown/Reference-manual.md29
-rw-r--r--docs/markdown/Reference-tables.md3
-rw-r--r--docs/markdown/snippets/gen-subdirs.md21
-rw-r--r--mesonbuild/backend/ninjabackend.py24
-rw-r--r--mesonbuild/backend/vs2010backend.py41
-rw-r--r--mesonbuild/build.py62
-rw-r--r--mesonbuild/compilers/c.py8
-rw-r--r--mesonbuild/compilers/compilers.py10
-rw-r--r--mesonbuild/dependencies/__init__.py2
-rw-r--r--mesonbuild/dependencies/base.py32
-rw-r--r--mesonbuild/dependencies/dev.py31
-rw-r--r--mesonbuild/environment.py2
-rw-r--r--mesonbuild/interpreter.py27
-rw-r--r--mesonbuild/mesonlib.py53
-rwxr-xr-xrun_project_tests.py24
-rwxr-xr-xrun_unittests.py22
-rw-r--r--test cases/common/125 shared module/meson.build4
-rw-r--r--test cases/common/135 generated assembly/square-arm.S.in4
-rw-r--r--test cases/common/135 generated assembly/square-x86.S.in4
-rw-r--r--test cases/common/135 generated assembly/square-x86_64.S.in4
-rw-r--r--test cases/common/140 get define/meson.build25
-rw-r--r--test cases/common/156 shared module resolving symbol in executable/meson.build8
-rw-r--r--test cases/common/173 preserve gendir/base.inp1
-rw-r--r--test cases/common/173 preserve gendir/com/mesonbuild/subbie.inp1
-rwxr-xr-xtest cases/common/173 preserve gendir/genprog.py47
-rw-r--r--test cases/common/173 preserve gendir/meson.build13
-rw-r--r--test cases/common/173 preserve gendir/testprog.c6
-rw-r--r--test cases/frameworks/11 gir subproject/gir/meson.build3
-rw-r--r--test cases/frameworks/11 gir subproject/installed_files.txt4
-rw-r--r--test cases/frameworks/12 multiple gir/installed_files.txt4
-rw-r--r--test cases/frameworks/15 llvm/meson.build24
-rw-r--r--test cases/frameworks/17 mpi/meson.build5
-rw-r--r--test cases/frameworks/18 vulkan/meson.build5
-rw-r--r--test cases/frameworks/2 gtest/meson.build5
-rw-r--r--test cases/frameworks/3 gmock/meson.build10
-rw-r--r--test cases/frameworks/5 protocol buffers/asubdir/defs.proto4
-rw-r--r--test cases/frameworks/5 protocol buffers/defs.proto4
-rw-r--r--test cases/frameworks/5 protocol buffers/meson.build4
-rw-r--r--test cases/frameworks/5 protocol buffers/sidedir/meson.build7
-rw-r--r--test cases/frameworks/5 protocol buffers/sidedir/sideprog.cpp16
-rw-r--r--test cases/frameworks/5 protocol buffers/withpath/com/mesonbuild/simple.proto7
-rw-r--r--test cases/frameworks/5 protocol buffers/withpath/com/mesonbuild/subsite/complex.proto10
-rw-r--r--test cases/frameworks/5 protocol buffers/withpath/meson.build13
-rw-r--r--test cases/frameworks/5 protocol buffers/withpath/pathprog.cpp16
-rw-r--r--test cases/frameworks/7 gnome/gir/meson.build3
-rw-r--r--test cases/frameworks/7 gnome/installed_files.txt6
-rw-r--r--test cases/objc/2 nsstring/meson.build5
-rw-r--r--test cases/objc/3 objc args/meson.build (renamed from test cases/objc/4 objc args/meson.build)0
-rw-r--r--test cases/objc/3 objc args/prog.m (renamed from test cases/objc/4 objc args/prog.m)0
-rw-r--r--test cases/objcpp/1 simple/meson.build (renamed from test cases/objc/3 objc++/meson.build)0
-rw-r--r--test cases/objcpp/1 simple/prog.mm (renamed from test cases/objc/3 objc++/prog.mm)0
-rw-r--r--test cases/objcpp/2 objc++ args/meson.build (renamed from test cases/objc/5 objc++ args/meson.build)0
-rw-r--r--test cases/objcpp/2 objc++ args/prog.mm (renamed from test cases/objc/5 objc++ args/prog.mm)0
-rw-r--r--test cases/vala/11 generated vapi/installed_files.txt4
-rw-r--r--test cases/vala/11 generated vapi/libbar/bar.c23
-rw-r--r--test cases/vala/11 generated vapi/libbar/bar.h6
-rw-r--r--test cases/vala/11 generated vapi/libfoo/foo.c23
-rw-r--r--test cases/vala/11 generated vapi/libfoo/foo.h6
-rw-r--r--test cases/vala/11 generated vapi/main.vala4
-rw-r--r--test cases/vala/7 shared library/installed_files.txt4
-rw-r--r--test cases/vala/9 gir/installed_files.txt2
-rwxr-xr-xwraptool.py5
63 files changed, 598 insertions, 145 deletions
diff --git a/ci/appveyor-install.bat b/ci/appveyor-install.bat
index 2d4a8cb..1e60179 100755
--- a/ci/appveyor-install.bat
+++ b/ci/appveyor-install.bat
@@ -10,10 +10,13 @@ echo Updating Cygwin and installing ninja and test prerequisites
%CYGWIN_ROOT%\%SETUP% -qnNdO -R "%CYGWIN_ROOT%" -s "%CYGWIN_MIRROR%" -l "%CACHE%" -g -P ^
gcc-objc++,^
gcc-objc,^
+gobject-introspection,^
libboost-devel,^
libglib2.0-devel,^
+libgtk3-devel,^
ninja,^
python3-pip,^
+vala,^
zlib-devel
echo Install done
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index e30b79c..a3e1ef0 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -403,7 +403,7 @@ be passed to [shared and static libraries](#library).
flags here for all platforms.
- `link_depends` strings, files, or custom targets the link step
depends on such as a symbol visibility map. The purpose is to
- automaticallytrigger a re-link (but not a re-compile) of the target
+ automatically trigger a re-link (but not a re-compile) of the target
when this file changes.
- `link_whole` links all contents of the given static libraries
whether they are used by not, equivalent to the
@@ -412,13 +412,18 @@ be passed to [shared and static libraries](#library).
- `link_with`, one or more shared or static libraries (built by this
project) that this target should be linked with, If passed a list
this list will be flattened as of 0.41.0.
+- `export_dynamic` when set to true causes the target's symbols to be
+ dynamically exported, allowing modules built using the
+ [`shared_module`](#shared_module) function to refer to functions,
+ variables and other symbols defined in the executable itself. Implies
+ the `implib` argument. Since 0.44.0
- `implib` when set to true, an import library is generated for the
executable (the name of the import library is based on *exe_name*).
Alternatively, when set to a string, that gives the base name for
the import library. The import library is used when the returned
build target object appears in `link_with:` elsewhere. Only has any
- effect on platforms where that is meaningful (e.g. Windows). Since
- 0.42.0
+ effect on platforms where that is meaningful (e.g. Windows). Implies
+ the `export_dynamic` argument. Since 0.42.0
- `implicit_include_directories` is a boolean telling whether Meson
adds the current source and build directories to the include path,
defaults to `true`, since 0.42.0
@@ -1010,6 +1015,11 @@ This is useful for building modules that will be `dlopen()`ed and
hence may contain undefined symbols that will be provided by the
library that is loading it.
+If you want the shared module to be able to refer to functions and
+variables defined in the [`executable`](#executable) it is loaded by,
+you will need to set the `export_dynamic` argument of the executable to
+`true`.
+
*Added 0.37.0*
### static_library()
@@ -1695,11 +1705,18 @@ This object is returned by [`generator()`](#generator) and contains a
generator that is used to transform files from one type to another by
an executable (e.g. `idl` files into source code and headers).
-* `process(list_of_files)` takes a list of files, causes them to be
- processed and returns an object containing the result which can
+* `process(list_of_files, ...)` takes a list of files, causes them to
+ be processed and returns an object containing the result which can
then, for example, be passed into a build target definition. The
keyword argument `extra_args`, if specified, will be used to replace
- an entry `@EXTRA_ARGS@` in the argument list.
+ an entry `@EXTRA_ARGS@` in the argument list. The keyword argument
+ `preserve_path_from`, if given, specifies that the output files need
+ to maintain their directory structure inside the target temporary
+ directory. The most common value for this is
+ `meson.current_source_dir()`. With this value when a file called
+ `subdir/one.input` is processed it generates a file `<target private
+ directory>/subdir/one.out` as opposed to `<target private
+ directory>/one.out`.
### `subproject` object
diff --git a/docs/markdown/Reference-tables.md b/docs/markdown/Reference-tables.md
index 8e048dc..ee3b8c2 100644
--- a/docs/markdown/Reference-tables.md
+++ b/docs/markdown/Reference-tables.md
@@ -57,6 +57,9 @@ These are provided by the `.system()` method call.
| windows | Any version of Windows |
| cygwin | The Cygwin environment for Windows |
| haiku | |
+| freebsd | FreeBSD and it's derivatives |
+| dragonfly | DragonFly BSD |
+| netbsd | |
Any string not listed above is not guaranteed to remain stable in
future releases.
diff --git a/docs/markdown/snippets/gen-subdirs.md b/docs/markdown/snippets/gen-subdirs.md
new file mode 100644
index 0000000..fdb5945
--- /dev/null
+++ b/docs/markdown/snippets/gen-subdirs.md
@@ -0,0 +1,21 @@
+## Generator outputs can preserve directory structure
+
+Normally when generating files with a generator, Meson flattens the
+input files so they all go in the same directory. Some code
+generators, such as Protocol Buffers, require that the generated files
+have the same directory layout as the input files used to generate
+them. This can now be achieved like this:
+
+```meson
+g = generator(...) # Compiles protobuf sources
+generated = gen.process('com/mesonbuild/one.proto',
+ 'com/mesonbuild/two.proto',
+ preserve_path_from : meson.current_source_dir())
+
+This would cause the following files to be generated inside the target
+private directory:
+
+ com/mesonbuild/one.pb.h
+ com/mesonbuild/one.pb.cc
+ com/mesonbuild/two.pb.h
+ com/mesonbuild/two.pb.cc
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 1057892..77c7d50 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -42,8 +42,12 @@ def ninja_quote(text):
for char in ('$', ' ', ':'):
text = text.replace(char, '$' + char)
if '\n' in text:
- raise MesonException('Ninja does not support newlines in rules. '
- 'Please report this error with a test case to the Meson bug tracker.')
+ errmsg = '''Ninja does not support newlines in rules. The content was:
+
+%s
+
+Please report this error with a test case to the Meson bug tracker.''' % text
+ raise MesonException(errmsg)
return text
@@ -1787,18 +1791,23 @@ rule FORTRAN_DEP_HACK
continue
self.generate_genlist_for_target(genlist, target, outfile)
- def replace_paths(self, target, args):
- source_target_dir = self.get_target_source_dir(target)
+ def replace_paths(self, target, args, override_subdir=None):
+ if override_subdir:
+ source_target_dir = os.path.join(self.build_to_src, override_subdir)
+ else:
+ source_target_dir = self.get_target_source_dir(target)
relout = self.get_target_private_dir(target)
args = [x.replace("@SOURCE_DIR@", self.build_to_src).replace("@BUILD_DIR@", relout)
for x in args]
args = [x.replace("@CURRENT_SOURCE_DIR@", source_target_dir) for x in args]
args = [x.replace("@SOURCE_ROOT@", self.build_to_src).replace("@BUILD_ROOT@", '.')
for x in args]
+ args = [x.replace('\\', '/') for x in args]
return args
def generate_genlist_for_target(self, genlist, target, outfile):
generator = genlist.get_generator()
+ subdir = genlist.subdir
exe = generator.get_exe()
exe_arr = self.exe_object_to_cmd_array(exe)
infilelist = genlist.get_inputs()
@@ -1830,7 +1839,7 @@ rule FORTRAN_DEP_HACK
if sole_output == '':
outfilelist = outfilelist[len(generator.outputs):]
relout = self.get_target_private_dir(target)
- args = self.replace_paths(target, args)
+ args = self.replace_paths(target, args, override_subdir=subdir)
cmdlist = exe_arr + self.replace_extra_args(args, genlist)
if generator.capture:
exe_data = self.serialize_executable(
@@ -2254,7 +2263,7 @@ rule FORTRAN_DEP_HACK
def generate_msvc_pch_command(self, target, compiler, pch):
if len(pch) != 2:
- raise RuntimeError('MSVC requires one header and one source to produce precompiled headers.')
+ raise MesonException('MSVC requires one header and one source to produce precompiled headers.')
header = pch[0]
source = pch[1]
pchname = compiler.get_pch_name(header)
@@ -2337,6 +2346,9 @@ rule FORTRAN_DEP_HACK
# If gui_app, and that's significant on this platform
if target.gui_app and hasattr(linker, 'get_gui_app_args'):
commands += linker.get_gui_app_args()
+ # If export_dynamic, add the appropriate linker arguments
+ if target.export_dynamic:
+ commands += linker.gen_export_dynamic_link_args(self.environment)
# If implib, and that's significant on this platform (i.e. Windows using either GCC or Visual Studio)
if target.import_filename:
commands += linker.gen_import_library_args(os.path.join(self.get_target_dir(target), target.import_filename))
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index 6a587ac..1722db7 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -87,7 +87,6 @@ class Vs2010Backend(backends.Backend):
custom_target_include_dirs = []
custom_target_output_files = []
target_private_dir = self.relpath(self.get_target_private_dir(target), self.get_target_dir(target))
- source_target_dir = self.get_target_source_dir(target)
down = self.target_to_build_root(target)
for genlist in target.get_generated_sources():
if isinstance(genlist, (build.CustomTarget, build.CustomTargetIndex)):
@@ -103,6 +102,7 @@ class Vs2010Backend(backends.Backend):
exe = generator.get_exe()
infilelist = genlist.get_inputs()
outfilelist = genlist.get_outputs()
+ source_dir = os.path.join(self.build_to_src, genlist.subdir)
exe_arr = self.exe_object_to_cmd_array(exe)
idgroup = ET.SubElement(parent_node, 'ItemGroup')
for i in range(len(infilelist)):
@@ -122,10 +122,11 @@ class Vs2010Backend(backends.Backend):
args = [x.replace("@SOURCE_DIR@", self.environment.get_source_dir())
.replace("@BUILD_DIR@", target_private_dir)
for x in args]
- args = [x.replace("@CURRENT_SOURCE_DIR@", source_target_dir) for x in args]
+ args = [x.replace("@CURRENT_SOURCE_DIR@", source_dir) for x in args]
args = [x.replace("@SOURCE_ROOT@", self.environment.get_source_dir())
.replace("@BUILD_ROOT@", self.environment.get_build_dir())
for x in args]
+ args = [x.replace('\\', '/') for x in args]
cmd = exe_arr + self.replace_extra_args(args, genlist)
if generator.capture:
exe_data = self.serialize_executable(
@@ -861,7 +862,14 @@ class Vs2010Backend(backends.Backend):
if not pch:
continue
pch_node.text = 'Use'
- pch_sources[lang] = [pch[0], pch[1], lang]
+ if compiler.id == 'msvc':
+ if len(pch) != 2:
+ raise MesonException('MSVC requires one header and one source to produce precompiled headers.')
+ pch_sources[lang] = [pch[0], pch[1], lang]
+ else:
+ # I don't know whether its relevant but let's handle other compilers
+ # used with a vs backend
+ pch_sources[lang] = [pch[0], None, lang]
if len(pch_sources) == 1:
# If there is only 1 language with precompiled headers, we can use it for the entire project, which
# is cleaner than specifying it for each source file.
@@ -1016,19 +1024,20 @@ class Vs2010Backend(backends.Backend):
self.add_include_dirs(lang, inc_cl, file_inc_dirs)
for lang in pch_sources:
header, impl, suffix = pch_sources[lang]
- relpath = os.path.join(proj_to_src_dir, impl)
- inc_cl = ET.SubElement(inc_src, 'CLCompile', Include=relpath)
- pch = ET.SubElement(inc_cl, 'PrecompiledHeader')
- pch.text = 'Create'
- pch_out = ET.SubElement(inc_cl, 'PrecompiledHeaderOutputFile')
- pch_out.text = '$(IntDir)$(TargetName)-%s.pch' % suffix
- pch_file = ET.SubElement(inc_cl, 'PrecompiledHeaderFile')
- # MSBuild searches for the header relative from the implementation, so we have to use
- # just the file name instead of the relative path to the file.
- pch_file.text = os.path.split(header)[1]
- 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)
+ if impl:
+ relpath = os.path.join(proj_to_src_dir, impl)
+ inc_cl = ET.SubElement(inc_src, 'CLCompile', Include=relpath)
+ pch = ET.SubElement(inc_cl, 'PrecompiledHeader')
+ pch.text = 'Create'
+ pch_out = ET.SubElement(inc_cl, 'PrecompiledHeaderOutputFile')
+ pch_out.text = '$(IntDir)$(TargetName)-%s.pch' % suffix
+ pch_file = ET.SubElement(inc_cl, 'PrecompiledHeaderFile')
+ # MSBuild searches for the header relative from the implementation, so we have to use
+ # just the file name instead of the relative path to the file.
+ pch_file.text = os.path.split(header)[1]
+ 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)
if self.has_objects(objects, additional_objects, gen_objs):
inc_objs = ET.SubElement(root, 'ItemGroup')
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 8a2e716..5eab794 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -14,7 +14,7 @@
import copy, os, re
from collections import OrderedDict
-import itertools
+import itertools, pathlib
from . import environment
from . import dependencies
@@ -82,6 +82,7 @@ known_lib_kwargs.update({'version': True, # Only for shared libs
known_exe_kwargs = known_basic_kwargs.copy()
known_exe_kwargs.update({'implib': True,
+ 'export_dynamic': True
})
class InvalidArguments(MesonException):
@@ -1076,7 +1077,8 @@ class Generator:
def get_base_outnames(self, inname):
plainname = os.path.split(inname)[1]
basename = os.path.splitext(plainname)[0]
- return [x.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname) for x in self.outputs]
+ bases = [x.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname) for x in self.outputs]
+ return bases
def get_dep_outname(self, inname):
if self.depfile is None:
@@ -1090,32 +1092,54 @@ class Generator:
basename = os.path.splitext(plainname)[0]
return [x.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname) for x in self.arglist]
- def process_files(self, name, files, state, extra_args=[]):
- output = GeneratedList(self, extra_args=extra_args)
+ def is_parent_path(self, parent, trial):
+ relpath = pathlib.PurePath(trial).relative_to(parent)
+ return relpath.parts[0] != '..' # For subdirs we can only go "down".
+
+ def process_files(self, name, files, state, preserve_path_from=None, extra_args=[]):
+ output = GeneratedList(self, state.subdir, preserve_path_from, extra_args=extra_args)
for f in files:
if isinstance(f, str):
f = File.from_source_file(state.environment.source_dir, state.subdir, f)
elif not isinstance(f, File):
raise InvalidArguments('{} arguments must be strings or files not {!r}.'.format(name, f))
- output.add_file(f)
+ if preserve_path_from:
+ abs_f = f.absolute_path(state.environment.source_dir, state.environment.build_dir)
+ if not self.is_parent_path(preserve_path_from, abs_f):
+ raise InvalidArguments('When using preserve_path_from, all input files must be in a subdirectory of the given dir.')
+ output.add_file(f, state)
return output
class GeneratedList:
- def __init__(self, generator, extra_args=[]):
+ def __init__(self, generator, subdir, preserve_path_from=None, extra_args=[]):
if hasattr(generator, 'held_object'):
generator = generator.held_object
self.generator = generator
self.name = self.generator.exe
+ self.subdir = subdir
self.infilelist = []
self.outfilelist = []
self.outmap = {}
self.extra_depends = []
+ self.preserve_path_from = preserve_path_from
self.extra_args = extra_args
- def add_file(self, newfile):
+ def add_preserved_path_segment(self, infile, outfiles, state):
+ result = []
+ in_abs = infile.absolute_path(state.environment.source_dir, state.environment.build_dir)
+ assert(os.path.isabs(self.preserve_path_from))
+ rel = os.path.relpath(in_abs, self.preserve_path_from)
+ path_segment = os.path.split(rel)[0]
+ for of in outfiles:
+ result.append(os.path.join(path_segment, of))
+ return result
+
+ def add_file(self, newfile, state):
self.infilelist.append(newfile)
outfiles = self.generator.get_base_outnames(newfile.fname)
+ if self.preserve_path_from:
+ outfiles = self.add_preserved_path_segment(newfile, outfiles, state)
self.outfilelist += outfiles
self.outmap[newfile] = outfiles
@@ -1160,23 +1184,33 @@ class Executable(BuildTarget):
# The import library that GCC would generate (and prefer)
self.gcc_import_filename = None
- # if implib appears, this target is linkwith:-able, but that only means
- # something on Windows platforms.
- self.is_linkwithable = False
- if 'implib' in kwargs and kwargs['implib']:
+ # Check for export_dynamic
+ self.export_dynamic = False
+ if kwargs.get('export_dynamic'):
+ if not isinstance(kwargs['export_dynamic'], bool):
+ raise InvalidArguments('"export_dynamic" keyword argument must be a boolean')
+ self.export_dynamic = True
+ if kwargs.get('implib'):
+ self.export_dynamic = True
+ if self.export_dynamic and kwargs.get('implib') is False:
+ raise InvalidArguments('"implib" keyword argument must not be false for if "export_dynamic" is true')
+
+ # If using export_dynamic, set the import library name
+ if self.export_dynamic:
implib_basename = self.name + '.exe'
- if not isinstance(kwargs['implib'], bool):
+ if not isinstance(kwargs.get('implib', False), bool):
implib_basename = kwargs['implib']
- self.is_linkwithable = True
if for_windows(is_cross, environment) or for_cygwin(is_cross, environment):
self.vs_import_filename = '{0}.lib'.format(implib_basename)
self.gcc_import_filename = 'lib{0}.a'.format(implib_basename)
-
if self.get_using_msvc():
self.import_filename = self.vs_import_filename
else:
self.import_filename = self.gcc_import_filename
+ # Only linkwithable if using export_dynamic
+ self.is_linkwithable = self.export_dynamic
+
def type_suffix(self):
return "@exe"
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index 233fc84..4c6e3a2 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -183,6 +183,14 @@ class CCompiler(Compiler):
def get_default_include_dirs(self):
return []
+ def gen_export_dynamic_link_args(self, env):
+ if for_windows(env.is_cross_build(), env):
+ return ['-Wl,--export-all-symbols']
+ elif for_darwin(env.is_cross_build(), env):
+ return []
+ else:
+ return ['-Wl,-export-dynamic']
+
def gen_import_library_args(self, implibname):
"""
The name of the outputted import library
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index b14074b..2602d14 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -855,7 +855,15 @@ class Compiler:
paths = padding
else:
paths = paths + ':' + padding
- args = ['-Wl,-rpath,' + paths]
+ args = []
+ if mesonlib.is_dragonflybsd():
+ # This argument instructs the compiler to record the value of
+ # ORIGIN in the .dynamic section of the elf. On Linux this is done
+ # by default, but is not on dragonfly for some reason. Without this
+ # $ORIGIN in the runtime path will be undefined and any binaries
+ # linked against local libraries will fail to resolve them.
+ args.append('-Wl,-z,origin')
+ args.append('-Wl,-rpath,' + paths)
if get_compiler_is_linuxlike(self):
# Rpaths to use while linking must be absolute. These are not
# written to the binary. Needed only with GNU ld:
diff --git a/mesonbuild/dependencies/__init__.py b/mesonbuild/dependencies/__init__.py
index 4dc2b27..69235da 100644
--- a/mesonbuild/dependencies/__init__.py
+++ b/mesonbuild/dependencies/__init__.py
@@ -13,7 +13,7 @@
# limitations under the License.
from .base import ( # noqa: F401
- Dependency, DependencyException, DependencyMethods, ExternalProgram,
+ Dependency, DependencyException, DependencyMethods, ExternalProgram, NonExistingExternalProgram,
ExternalDependency, ExternalLibrary, ExtraFrameworkDependency, InternalDependency,
PkgConfigDependency, find_external_dependency, get_dep_identifier, packages, _packages_accept_language)
from .dev import GMockDependency, GTestDependency, LLVMDependency, ValgrindDependency
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index 46cce43..e29d4de 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -400,11 +400,22 @@ class PkgConfigDependency(ExternalDependency):
m = 'Invalid version of dependency, need {!r} {!r} found {!r}.'
raise DependencyException(m.format(name, not_found, self.version))
return
- found_msg += [mlog.green('YES'), self.version]
- # Fetch cargs to be used while using this dependency
- self._set_cargs()
- # Fetch the libraries and library paths needed for using this
- self._set_libs()
+
+ try:
+ # Fetch cargs to be used while using this dependency
+ self._set_cargs()
+ # Fetch the libraries and library paths needed for using this
+ self._set_libs()
+ found_msg += [mlog.green('YES'), self.version]
+ except DependencyException as e:
+ if self.required:
+ raise
+ else:
+ self.compile_args = []
+ self.link_args = []
+ self.is_found = False
+ found_msg += [mlog.red('NO'), '; reason: {}'.format(str(e))]
+
# Print the found message only at the very end because fetching cflags
# and libs can also fail if other needed pkg-config files aren't found.
if not self.silent:
@@ -754,6 +765,17 @@ class ExternalProgram:
def get_name(self):
return self.name
+class NonExistingExternalProgram(ExternalProgram):
+
+ def __init__(self):
+ super().__init__(name = 'nonexistingprogram', silent = True)
+
+ def __repr__(self):
+ r = '<{} {!r} -> {!r}>'
+ return r.format(self.__class__.__name__, self.name, self.command)
+
+ def found(self):
+ return False
class ExternalLibrary(ExternalDependency):
def __init__(self, name, link_args, environment, language, silent=False):
diff --git a/mesonbuild/dependencies/dev.py b/mesonbuild/dependencies/dev.py
index 91414d5..25316df 100644
--- a/mesonbuild/dependencies/dev.py
+++ b/mesonbuild/dependencies/dev.py
@@ -17,11 +17,10 @@
import os
import re
-import shutil
from .. import mlog
from .. import mesonlib
-from ..mesonlib import version_compare, Popen_safe, stringlistify, extract_as_list
+from ..mesonlib import version_compare, stringlistify, extract_as_list
from .base import (
DependencyException, ExternalDependency, PkgConfigDependency,
strip_system_libdirs, ConfigToolDependency,
@@ -171,9 +170,37 @@ class LLVMDependency(ConfigToolDependency):
else:
self._set_old_link_args()
self.link_args = strip_system_libdirs(environment, self.link_args)
+ self.link_args = self.__fix_bogus_link_args(self.link_args)
+
+ @staticmethod
+ def __fix_bogus_link_args(args):
+ """This function attempts to fix bogus link arguments that llvm-config
+ generates.
+
+ Currently it works around the following:
+ - FreeBSD: when statically linking -l/usr/lib/libexecinfo.so will
+ be generated, strip the -l in cases like this.
+ """
+ new_args = []
+ for arg in args:
+ if arg.startswith('-l') and arg.endswith('.so'):
+ new_args.append(arg.lstrip('-l'))
+ else:
+ new_args.append(arg)
+ return new_args
def _set_new_link_args(self):
"""How to set linker args for LLVM versions >= 3.9"""
+ if ((mesonlib.is_dragonflybsd() or mesonlib.is_freebsd()) and not
+ self.static and version_compare(self.version, '>= 4.0')):
+ # llvm-config on DragonFly BSD and FreeBSD for versions 4.0, 5.0,
+ # and 6.0 have an error when generating arguments for shared mode
+ # linking, even though libLLVM.so is installed, because for some
+ # reason the tool expects to find a .so for each static library.
+ # This works around that.
+ self.link_args = self.get_config_value(['--ldflags'], 'link_args')
+ self.link_args.append('-lLLVM')
+ return
link_args = ['--link-static', '--system-libs'] if self.static else ['--link-shared']
self.link_args = self.get_config_value(
['--libs', '--ldflags'] + link_args + list(self.required_modules),
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index 0c9a2f3..e5aa43e 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -731,7 +731,7 @@ class Environment:
return compilers.LLVMDCompiler(exelist, version, is_cross, full_version=full_version)
elif 'gdc' in out:
return compilers.GnuDCompiler(exelist, version, is_cross, full_version=full_version)
- elif 'Digital Mars' in out:
+ elif 'The D Language Foundation' in out or 'Digital Mars' in out:
return compilers.DmdDCompiler(exelist, version, is_cross, full_version=full_version)
raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"')
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 29b4033..c759892 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -375,7 +375,18 @@ class GeneratorHolder(InterpreterObject, ObjectHolder):
def process_method(self, args, kwargs):
extras = mesonlib.stringlistify(kwargs.get('extra_args', []))
- gl = self.held_object.process_files('Generator', args, self.interpreter, extra_args=extras)
+ if 'preserve_path_from' in kwargs:
+ preserve_path_from = kwargs['preserve_path_from']
+ if not isinstance(preserve_path_from, str):
+ raise InvalidArguments('Preserve_path_from must be a string.')
+ preserve_path_from = os.path.normpath(preserve_path_from)
+ if not os.path.isabs(preserve_path_from):
+ # This is a bit of a hack. Fix properly before merging.
+ raise InvalidArguments('Preserve_path_from must be an absolute path for now. Sorry.')
+ else:
+ preserve_path_from = None
+ gl = self.held_object.process_files('Generator', args, self.interpreter,
+ preserve_path_from, extra_args=extras)
return GeneratedListHolder(gl)
@@ -1347,7 +1358,7 @@ build_target_common_kwargs = (
rust_kwargs |
cs_kwargs)
-exe_kwargs = (build_target_common_kwargs) | {'implib'}
+exe_kwargs = (build_target_common_kwargs) | {'implib', 'export_dynamic'}
shlib_kwargs = (build_target_common_kwargs) | {'version', 'soversion'}
shmod_kwargs = shlib_kwargs
stlib_kwargs = shlib_kwargs
@@ -1372,7 +1383,7 @@ permitted_kwargs = {'add_global_arguments': {'language'},
'declare_dependency': {'include_directories', 'link_with', 'sources', 'dependencies', 'compile_args', 'link_args', 'version'},
'executable': exe_kwargs,
'find_program': {'required', 'native'},
- 'generator': {'arguments', 'output', 'depfile', 'capture'},
+ 'generator': {'arguments', 'output', 'depfile', 'capture', 'preserve_path_from'},
'include_directories': {'is_system'},
'install_data': {'install_dir', 'install_mode', 'sources'},
'install_headers': {'install_dir', 'subdir'},
@@ -1883,10 +1894,14 @@ to directly access options of other subprojects.''')
raise InvalidCode('Second call to project().')
if not self.is_subproject() and 'subproject_dir' in kwargs:
spdirname = kwargs['subproject_dir']
- if '/' in spdirname or '\\' in spdirname:
- raise InterpreterException('Subproject_dir must not contain a path segment.')
+ if not isinstance(spdirname, str):
+ raise InterpreterException('Subproject_dir must be a string')
+ if os.path.isabs(spdirname):
+ raise InterpreterException('Subproject_dir must not be an absolute path.')
if spdirname.startswith('.'):
raise InterpreterException('Subproject_dir must not begin with a period.')
+ if '..' in spdirname:
+ raise InterpreterException('Subproject_dir must not contain a ".." segment.')
self.subproject_dir = spdirname
if 'meson_version' in kwargs:
@@ -2119,7 +2134,7 @@ to directly access options of other subprojects.''')
if required and (progobj is None or not progobj.found()):
raise InvalidArguments('Program "%s" not found or not executable' % args[0])
if progobj is None:
- return ExternalProgramHolder(dependencies.ExternalProgram('nonexistingprogram'))
+ return ExternalProgramHolder(dependencies.NonExistingExternalProgram())
return progobj
def func_find_library(self, node, args, kwargs):
diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py
index 3b32996..4871bf7 100644
--- a/mesonbuild/mesonlib.py
+++ b/mesonbuild/mesonlib.py
@@ -25,29 +25,40 @@ from glob import glob
def detect_meson_py_location():
c = sys.argv[0]
- c_fname = os.path.split(c)[1]
- if c_fname == 'meson' or c_fname == 'meson.py':
- # $ /foo/meson.py <args>
- if os.path.isabs(c):
- return c
- # $ meson <args> (gets run from /usr/bin/meson)
+ c_dir, c_fname = os.path.split(c)
+
+ # get the absolute path to the <mesontool> folder
+ m_dir = None
+ if os.path.isabs(c):
+ # $ /foo/<mesontool>.py <args>
+ m_dir = c_dir
+ elif c_dir == '':
+ # $ <mesontool> <args> (gets run from /usr/bin/<mesontool>)
in_path_exe = shutil.which(c_fname)
if in_path_exe:
- # Special case: when run like "./meson.py <opts>" and user has
- # period in PATH, we need to expand it out, because, for example,
+ m_dir, c_fname = os.path.split(in_path_exe)
+ # Special case: when run like "./meson.py <opts>",
+ # we need to expand it out, because, for example,
# "ninja test" will be run from a different directory.
- if '.' in os.environ['PATH'].split(':'):
- p, f = os.path.split(in_path_exe)
- if p == '' or p == '.':
- return os.path.join(os.getcwd(), f)
- return in_path_exe
- # $ python3 ./meson.py <args>
- if os.path.exists(c):
- return os.path.join(os.getcwd(), c)
-
+ if m_dir == '.':
+ m_dir = os.getcwd()
+ else:
+ m_dir = os.path.abspath(c_dir)
+
+ # find meson in m_dir
+ if m_dir is not None:
+ for fname in ['meson', 'meson.py']:
+ m_path = os.path.join(m_dir, fname)
+ if os.path.exists(m_path):
+ return m_path
+
+ # No meson found, which means that either:
+ # a) meson is not installed
+ # b) meson is installed to a non-standard location
+ # c) the script that invoked mesonlib is not the one of meson tools (e.g. run_unittests.py)
# The only thing remaining is to try to find the bundled executable and
# pray distro packagers have not moved it.
- fname = os.path.join(os.path.dirname(__file__), '..', 'meson.py')
+ fname = os.path.normpath(os.path.join(os.path.dirname(__file__), '..', 'meson.py'))
if not os.path.exists(fname):
raise RuntimeError('Could not determine how to run Meson. Please file a bug with details.')
return fname
@@ -285,6 +296,12 @@ def is_cygwin():
def is_debianlike():
return os.path.isfile('/etc/debian_version')
+def is_dragonflybsd():
+ return platform.system().lower() == 'dragonfly'
+
+def is_freebsd():
+ return platform.system().lower() == 'freebsd'
+
def for_windows(is_cross, env):
"""
Host machine is windows?
diff --git a/run_project_tests.py b/run_project_tests.py
index 0bf5f31..d191e28 100755
--- a/run_project_tests.py
+++ b/run_project_tests.py
@@ -185,6 +185,7 @@ def get_relative_files_list_from_dir(fromdir):
def platform_fix_name(fname, compiler):
if '?lib' in fname:
if mesonlib.is_cygwin():
+ 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:
fname = re.sub(r'\?lib', 'lib', fname)
@@ -447,20 +448,28 @@ def have_objc_compiler():
env = environment.Environment(None, build_dir, None, get_fake_options('/'), [])
try:
objc_comp = env.detect_objc_compiler(False)
- except:
+ except mesonlib.MesonException:
return False
if not objc_comp:
return False
try:
objc_comp.sanity_check(env.get_scratch_dir(), env)
- objcpp_comp = env.detect_objc_compiler(False)
- except:
+ except mesonlib.MesonException:
+ return False
+ return True
+
+def have_objcpp_compiler():
+ with AutoDeletedDir(tempfile.mkdtemp(prefix='b ', dir='.')) as build_dir:
+ env = environment.Environment(None, build_dir, None, get_fake_options('/'), [])
+ try:
+ objcpp_comp = env.detect_objcpp_compiler(False)
+ except mesonlib.MesonException:
return False
if not objcpp_comp:
return False
try:
objcpp_comp.sanity_check(env.get_scratch_dir(), env)
- except:
+ except mesonlib.MesonException:
return False
return True
@@ -487,6 +496,7 @@ def detect_tests_to_run():
('rust', 'rust', backend is not Backend.ninja or not shutil.which('rustc')),
('d', 'd', backend is not Backend.ninja or not have_d_compiler()),
('objective c', 'objc', backend not in (Backend.ninja, Backend.xcode) or mesonlib.is_windows() or not have_objc_compiler()),
+ ('objective c++', 'objcpp', backend not in (Backend.ninja, Backend.xcode) or mesonlib.is_windows() or not have_objcpp_compiler()),
('fortran', 'fortran', backend is not Backend.ninja or not shutil.which('gfortran')),
('swift', 'swift', backend not in (Backend.ninja, Backend.xcode) or not shutil.which('swiftc')),
('python3', 'python3', backend is not Backend.ninja),
@@ -495,7 +505,11 @@ def detect_tests_to_run():
if mesonlib.is_windows():
# TODO: Set BOOST_ROOT in .appveyor.yml
gathered_tests += [('framework', ['test cases/frameworks/1 boost'], 'BOOST_ROOT' not in os.environ)]
- elif mesonlib.is_osx() or mesonlib.is_cygwin():
+ elif mesonlib.is_osx():
+ if os.path.exists('/usr/local/include/boost'):
+ # Just do the BOOST test
+ gathered_tests += [('framework', ['test cases/frameworks/1 boost'], False)]
+ elif mesonlib.is_cygwin():
# Just do the BOOST test
gathered_tests += [('framework', ['test cases/frameworks/1 boost'], False)]
else:
diff --git a/run_unittests.py b/run_unittests.py
index 08ad632..f61544f 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -34,8 +34,10 @@ import mesonbuild.environment
import mesonbuild.mesonlib
import mesonbuild.coredata
from mesonbuild.interpreter import ObjectHolder
-from mesonbuild.mesonlib import is_linux, is_windows, is_osx, is_cygwin, windows_proof_rmtree
-from mesonbuild.mesonlib import python_command, meson_command, version_compare
+from mesonbuild.mesonlib import (
+ is_linux, is_windows, is_osx, is_cygwin, is_dragonflybsd,
+ windows_proof_rmtree, python_command, meson_command, version_compare,
+)
from mesonbuild.environment import Environment, detect_ninja
from mesonbuild.mesonlib import MesonException, EnvironmentException
from mesonbuild.dependencies import PkgConfigDependency, ExternalProgram
@@ -1386,12 +1388,24 @@ int main(int argc, char **argv) {
for each in ('prog', 'subdir/liblib1.so', ):
rpath = get_rpath(os.path.join(self.builddir, each))
self.assertTrue(rpath)
- for path in rpath.split(':'):
+ if is_dragonflybsd():
+ # DragonflyBSD will prepend /usr/lib/gccVERSION to the rpath,
+ # so ignore that.
+ self.assertTrue(rpath.startswith('/usr/lib/gcc'))
+ rpaths = rpath.split(':')[1:]
+ else:
+ rpaths = rpath.split(':')
+ for path in rpaths:
self.assertTrue(path.startswith('$ORIGIN'), msg=(each, path))
# These two don't link to anything else, so they do not need an rpath entry.
for each in ('subdir/subdir2/liblib2.so', 'subdir/subdir3/liblib3.so'):
rpath = get_rpath(os.path.join(self.builddir, each))
- self.assertTrue(rpath is None)
+ if is_dragonflybsd():
+ # The rpath should be equal to /usr/lib/gccVERSION
+ self.assertTrue(rpath.startswith('/usr/lib/gcc'))
+ self.assertEqual(len(rpath.split(':')), 1)
+ else:
+ self.assertTrue(rpath is None)
def test_dash_d_dedup(self):
testdir = os.path.join(self.unit_test_dir, '10 d dedup')
diff --git a/test cases/common/125 shared module/meson.build b/test cases/common/125 shared module/meson.build
index 29277e9..08a284d 100644
--- a/test cases/common/125 shared module/meson.build
+++ b/test cases/common/125 shared module/meson.build
@@ -8,6 +8,6 @@ l = shared_library('runtime', 'runtime.c')
# at runtime. This requires extra help on Windows, so
# should be avoided unless really necessary.
m = shared_module('mymodule', 'module.c')
-e = executable('prog', 'prog.c', link_with : l, dependencies : dl)
+e = executable('prog', 'prog.c',
+ link_with : l, export_dynamic : true, dependencies : dl)
test('import test', e, args : m)
-
diff --git a/test cases/common/135 generated assembly/square-arm.S.in b/test cases/common/135 generated assembly/square-arm.S.in
index 168c980..d2fb7ac 100644
--- a/test cases/common/135 generated assembly/square-arm.S.in
+++ b/test cases/common/135 generated assembly/square-arm.S.in
@@ -2,8 +2,8 @@
.text
.globl SYMBOL_NAME(square_unsigned)
-/* Only supported on Linux with GAS */
-# ifdef __linux__
+/* Only supported with GAS */
+# if defined(__linux__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__)
.type square_unsigned,%function
#endif
diff --git a/test cases/common/135 generated assembly/square-x86.S.in b/test cases/common/135 generated assembly/square-x86.S.in
index 19dd9f5..ee77b81 100644
--- a/test cases/common/135 generated assembly/square-x86.S.in
+++ b/test cases/common/135 generated assembly/square-x86.S.in
@@ -21,8 +21,8 @@ END
.text
.globl SYMBOL_NAME(square_unsigned)
-/* Only supported on Linux with GAS */
-# ifdef __linux__
+/* Only supported with GAS */
+# if defined(__linux__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__)
.type square_unsigned,@function
# endif
diff --git a/test cases/common/135 generated assembly/square-x86_64.S.in b/test cases/common/135 generated assembly/square-x86_64.S.in
index 0834f16..856af13 100644
--- a/test cases/common/135 generated assembly/square-x86_64.S.in
+++ b/test cases/common/135 generated assembly/square-x86_64.S.in
@@ -18,8 +18,8 @@ END
.text
.globl SYMBOL_NAME(square_unsigned)
-/* Only supported on Linux with GAS */
-# ifdef __linux__
+/* Only supported with GAS */
+# if defined(__linux__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__)
.type square_unsigned,@function
# endif
diff --git a/test cases/common/140 get define/meson.build b/test cases/common/140 get define/meson.build
index e23b7de..fd87177 100644
--- a/test cases/common/140 get define/meson.build
+++ b/test cases/common/140 get define/meson.build
@@ -19,6 +19,19 @@ foreach lang : ['c', 'cpp']
elif host_system == 'haiku'
d = cc.get_define('__HAIKU__')
assert(d == '1', '__HAIKU__ value is @0@ instead of 1'.format(d))
+ elif host_system == 'freebsd'
+ # the __FreeBSD__ define will be equal to the major version of the release
+ # (ex, in FreeBSD 11.x, __FreeBSD__ == 11). To make the test robust when
+ # being run on various versions of FreeBSD, just test that the define is
+ # set.
+ d = cc.get_define('__FreeBSD__')
+ assert(d != '', '__FreeBSD__ value is unset')
+ elif host_system == 'dragonfly'
+ d = cc.get_define('__DragonFly__')
+ assert(d == '1', '__DragonFly__ value is @0@ instead of 1'.format(d))
+ elif host_system == 'netbsd'
+ d = cc.get_define('__NetBSD__')
+ assert(d == '1', '__NetBSD__ value is @0@ instead of 1'.format(d))
else
error('Please report a bug and help us improve support for this platform')
endif
@@ -28,8 +41,16 @@ foreach lang : ['c', 'cpp']
# found in the compiler's default search path, GCC inserts an extra comment
# between the delimiter and the define which causes a parsing error.
# https://github.com/mesonbuild/meson/issues/1726
- ver = cc.get_define('ZLIB_VER_MAJOR', prefix : '#include <zlib.h>')
- assert(ver == '1', 'ZLIB_VER_MAJOR value is "@0@" instead of "1"'.format(ver))
+ if host_machine.system() == 'netbsd'
+ # NetBSD's zlib doesn't is version 1.2.3 and doesn't have a
+ # ZLIB_VER_MAJOR, but it does have a ZLIB_VERSION (which is a string), so
+ # check the first non-quote character of that.
+ ver = cc.get_define('ZLIB_VERSION', prefix : '#include <zlib.h>')[1]
+ assert(ver == '1', 'ZLIB_VERSION (major) value is "@0@" instead of "1"'.format(ver))
+ else
+ ver = cc.get_define('ZLIB_VER_MAJOR', prefix : '#include <zlib.h>')
+ assert(ver == '1', 'ZLIB_VER_MAJOR value is "@0@" instead of "1"'.format(ver))
+ endif
endif
# Check that an undefined value is empty.
diff --git a/test cases/common/156 shared module resolving symbol in executable/meson.build b/test cases/common/156 shared module resolving symbol in executable/meson.build
index 34a75f1..282a4d2 100644
--- a/test cases/common/156 shared module resolving symbol in executable/meson.build
+++ b/test cases/common/156 shared module resolving symbol in executable/meson.build
@@ -9,13 +9,7 @@ project('shared module resolving symbol in executable', 'c')
# See testcase 125 for an example of the more complex portability gymnastics
# required if we do not know (at link-time) what provides the symbol.
-link_flags = []
-if host_machine.system() != 'windows'
- # Needed to export dynamic symbols from the executable
- link_flags += ['-rdynamic']
-endif
-
dl = meson.get_compiler('c').find_library('dl', required: false)
-e = executable('prog', 'prog.c', dependencies: dl, implib: true, link_args: link_flags)
+e = executable('prog', 'prog.c', dependencies: dl, export_dynamic: true)
m = shared_module('module', 'module.c', link_with: e)
test('test', e, args: m.full_path())
diff --git a/test cases/common/173 preserve gendir/base.inp b/test cases/common/173 preserve gendir/base.inp
new file mode 100644
index 0000000..df967b9
--- /dev/null
+++ b/test cases/common/173 preserve gendir/base.inp
@@ -0,0 +1 @@
+base
diff --git a/test cases/common/173 preserve gendir/com/mesonbuild/subbie.inp b/test cases/common/173 preserve gendir/com/mesonbuild/subbie.inp
new file mode 100644
index 0000000..df0f4e9
--- /dev/null
+++ b/test cases/common/173 preserve gendir/com/mesonbuild/subbie.inp
@@ -0,0 +1 @@
+subbie
diff --git a/test cases/common/173 preserve gendir/genprog.py b/test cases/common/173 preserve gendir/genprog.py
new file mode 100755
index 0000000..8bd2b9d
--- /dev/null
+++ b/test cases/common/173 preserve gendir/genprog.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python3
+
+import os, sys, argparse
+import pathlib
+
+h_templ = '''#pragma once
+
+int %s();
+'''
+
+c_templ = '''#include"%s.h"
+
+int %s() {
+ return 0;
+}
+'''
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--searchdir', required=True)
+parser.add_argument('--outdir', required=True)
+parser.add_argument('ifiles', nargs='+')
+
+options = parser.parse_args()
+
+searchdir = options.searchdir
+outdir = options.outdir
+ifiles = options.ifiles
+
+rel_ofiles = []
+
+for ifile in ifiles:
+ if not ifile.startswith(options.searchdir):
+ sys.exit('Input file %s does not start with search dir %s.' % (ifile, searchdir))
+ rel_ofile = ifile[len(searchdir):]
+ if rel_ofile[0] == '/' or rel_ofile[0] == '\\':
+ rel_ofile = rel_ofile[1:]
+ rel_ofiles.append(os.path.splitext(rel_ofile)[0])
+
+ofile_bases = [os.path.join(outdir, i) for i in rel_ofiles]
+
+for i, ifile_name in enumerate(ifiles):
+ proto_name = open(ifile_name).readline().strip()
+ h_out = ofile_bases[i] + '.h'
+ c_out = ofile_bases[i] + '.c'
+ os.makedirs(os.path.split(ofile_bases[i])[0], exist_ok=True)
+ open(h_out, 'w').write(h_templ % (proto_name))
+ open(c_out, 'w').write(c_templ % (proto_name, proto_name))
diff --git a/test cases/common/173 preserve gendir/meson.build b/test cases/common/173 preserve gendir/meson.build
new file mode 100644
index 0000000..ce219f0
--- /dev/null
+++ b/test cases/common/173 preserve gendir/meson.build
@@ -0,0 +1,13 @@
+project('preserve subdir', 'c')
+
+gprog = find_program('genprog.py')
+
+gen = generator(gprog, \
+ output : ['@BASENAME@.c', '@BASENAME@.h'],
+ arguments : ['--searchdir=@CURRENT_SOURCE_DIR@', '--outdir=@BUILD_DIR@', '@INPUT@'])
+
+generated = gen.process('base.inp', 'com/mesonbuild/subbie.inp',
+ preserve_path_from : meson.current_source_dir())
+
+e = executable('testprog', 'testprog.c', generated)
+test('testprog', e)
diff --git a/test cases/common/173 preserve gendir/testprog.c b/test cases/common/173 preserve gendir/testprog.c
new file mode 100644
index 0000000..46b4602
--- /dev/null
+++ b/test cases/common/173 preserve gendir/testprog.c
@@ -0,0 +1,6 @@
+#include"base.h"
+#include"com/mesonbuild/subbie.h"
+
+int main(int argc, char **argv) {
+ return base() + subbie();
+}
diff --git a/test cases/frameworks/11 gir subproject/gir/meson.build b/test cases/frameworks/11 gir subproject/gir/meson.build
index 48e0a47..fe40dc6 100644
--- a/test cases/frameworks/11 gir subproject/gir/meson.build
+++ b/test cases/frameworks/11 gir subproject/gir/meson.build
@@ -31,6 +31,9 @@ message('TEST: ' + girsubproject.outdir())
envdata = environment()
envdata.append('GI_TYPELIB_PATH', girsubproject.outdir(), 'subprojects/mesongir', separator : ':')
envdata.append('LD_LIBRARY_PATH', girsubproject.outdir(), 'subprojects/mesongir')
+if ['windows', 'cygwin'].contains(host_machine.system())
+ envdata.append('PATH', girsubproject.outdir(), 'subprojects/mesongir')
+endif
test('gobject introspection/subproject/c', girexe)
test('gobject introspection/subproject/py', find_program('prog.py'),
diff --git a/test cases/frameworks/11 gir subproject/installed_files.txt b/test cases/frameworks/11 gir subproject/installed_files.txt
index 434481e..87d49a1 100644
--- a/test cases/frameworks/11 gir subproject/installed_files.txt
+++ b/test cases/frameworks/11 gir subproject/installed_files.txt
@@ -2,5 +2,5 @@ usr/lib/girepository-1.0/Meson-1.0.typelib
usr/lib/girepository-1.0/MesonSub-1.0.typelib
usr/share/gir-1.0/Meson-1.0.gir
usr/share/gir-1.0/MesonSub-1.0.gir
-usr/lib/libgirsubproject.so
-usr/lib/libgirlib.so
+usr/lib/?libgirsubproject.so
+usr/lib/?libgirlib.so
diff --git a/test cases/frameworks/12 multiple gir/installed_files.txt b/test cases/frameworks/12 multiple gir/installed_files.txt
index 9fb51bf..a5d16bc 100644
--- a/test cases/frameworks/12 multiple gir/installed_files.txt
+++ b/test cases/frameworks/12 multiple gir/installed_files.txt
@@ -1,6 +1,6 @@
usr/lib/girepository-1.0/Meson-1.0.typelib
usr/lib/girepository-1.0/MesonSub-1.0.typelib
-usr/lib/libgirlib.so
-usr/lib/libgirsubproject.so
+usr/lib/?libgirlib.so
+usr/lib/?libgirsubproject.so
usr/share/gir-1.0/Meson-1.0.gir
usr/share/gir-1.0/MesonSub-1.0.gir
diff --git a/test cases/frameworks/15 llvm/meson.build b/test cases/frameworks/15 llvm/meson.build
index 5211006..549adce 100644
--- a/test cases/frameworks/15 llvm/meson.build
+++ b/test cases/frameworks/15 llvm/meson.build
@@ -20,17 +20,19 @@ foreach static : [true, false]
'llvm',
modules : ['bitwriter', 'asmprinter', 'executionengine', 'target',
'mcjit', 'nativecodegen'],
- required : true,
+ required : false,
static : static,
)
- name = static ? 'static' : 'dynamic'
- executable(
- 'sum-@0@'.format(name),
- 'sum.c',
- dependencies : [
- llvm_dep, dep_tinfo,
- dependency('zlib'),
- meson.get_compiler('c').find_library('dl', required : false),
- ]
- )
+ if llvm_dep.found()
+ name = static ? 'static' : 'dynamic'
+ executable(
+ 'sum-@0@'.format(name),
+ 'sum.c',
+ dependencies : [
+ llvm_dep, dep_tinfo,
+ dependency('zlib'),
+ meson.get_compiler('c').find_library('dl', required : false),
+ ]
+ )
+ endif
endforeach
diff --git a/test cases/frameworks/17 mpi/meson.build b/test cases/frameworks/17 mpi/meson.build
index 17acd71..01ad61d 100644
--- a/test cases/frameworks/17 mpi/meson.build
+++ b/test cases/frameworks/17 mpi/meson.build
@@ -6,7 +6,10 @@ if build_machine.system() == 'windows' and cc.get_id() != 'msvc'
error('MESON_SKIP_TEST: MPI not available on Windows without MSVC.')
endif
-mpic = dependency('mpi', language : 'c')
+mpic = dependency('mpi', language : 'c', required : false)
+if not mpic.found()
+ error('MESON_SKIP_TEST: MPI not found, skipping.')
+endif
exec = executable('exec',
'main.c',
dependencies : [mpic])
diff --git a/test cases/frameworks/18 vulkan/meson.build b/test cases/frameworks/18 vulkan/meson.build
index 54f1d47..e98854e 100644
--- a/test cases/frameworks/18 vulkan/meson.build
+++ b/test cases/frameworks/18 vulkan/meson.build
@@ -1,6 +1,9 @@
project('vulkan test', 'c')
-vulkan_dep = dependency('vulkan')
+vulkan_dep = dependency('vulkan', required : false)
+if not vulkan_dep.found()
+ error('MESON_SKIP_TEST: vulkan not found.')
+endif
e = executable('vulkanprog', 'vulkanprog.c', dependencies : vulkan_dep)
diff --git a/test cases/frameworks/2 gtest/meson.build b/test cases/frameworks/2 gtest/meson.build
index 419f451..e5418e9 100644
--- a/test cases/frameworks/2 gtest/meson.build
+++ b/test cases/frameworks/2 gtest/meson.build
@@ -1,6 +1,9 @@
project('gtest', 'cpp')
-gtest = dependency('gtest', main : true)
+gtest = dependency('gtest', main : true, required : false)
+if not gtest.found()
+ error('MESON_SKIP_TEST: gtest not installed.')
+endif
gtest_nomain = dependency('gtest', main : false)
e = executable('testprog', 'test.cc', dependencies : gtest)
diff --git a/test cases/frameworks/3 gmock/meson.build b/test cases/frameworks/3 gmock/meson.build
index 341f9d7..516547f 100644
--- a/test cases/frameworks/3 gmock/meson.build
+++ b/test cases/frameworks/3 gmock/meson.build
@@ -3,8 +3,14 @@ project('gmock test', 'cpp')
# Using gmock without gtest is a pain so just
# don't support that then.
-gtest = dependency('gtest', main : true)
-gmock = dependency('gmock')
+gtest = dependency('gtest', main : true, required : false)
+if not gtest.found()
+ error('MESON_SKIP_TEST: gtest not installed.')
+endif
+gmock = dependency('gmock', required : false)
+if not gmock.found()
+ error('MESON_SKIP_TEST: gmock not installed.')
+endif
e = executable('gmocktest', 'gmocktest.cc', dependencies : [gtest, gmock])
test('gmock test', e)
diff --git a/test cases/frameworks/5 protocol buffers/asubdir/defs.proto b/test cases/frameworks/5 protocol buffers/asubdir/defs.proto
index f795651..dad5754 100644
--- a/test cases/frameworks/5 protocol buffers/asubdir/defs.proto
+++ b/test cases/frameworks/5 protocol buffers/asubdir/defs.proto
@@ -1,3 +1,5 @@
+syntax = "proto3";
+
message Dummy {
- required string text = 1;
+ string text = 1;
}
diff --git a/test cases/frameworks/5 protocol buffers/defs.proto b/test cases/frameworks/5 protocol buffers/defs.proto
index f795651..dad5754 100644
--- a/test cases/frameworks/5 protocol buffers/defs.proto
+++ b/test cases/frameworks/5 protocol buffers/defs.proto
@@ -1,3 +1,5 @@
+syntax = "proto3";
+
message Dummy {
- required string text = 1;
+ string text = 1;
}
diff --git a/test cases/frameworks/5 protocol buffers/meson.build b/test cases/frameworks/5 protocol buffers/meson.build
index 58666f9..94fa980 100644
--- a/test cases/frameworks/5 protocol buffers/meson.build
+++ b/test cases/frameworks/5 protocol buffers/meson.build
@@ -10,7 +10,7 @@ endif
gen = generator(protoc, \
output : ['@BASENAME@.pb.cc', '@BASENAME@.pb.h'],
- arguments : ['--proto_path=@SOURCE_DIR@', '--cpp_out=@BUILD_DIR@', '@INPUT@'])
+ arguments : ['--proto_path=@CURRENT_SOURCE_DIR@', '--cpp_out=@BUILD_DIR@', '@INPUT@'])
generated = gen.process('defs.proto')
e = executable('prog', 'main.cpp', generated,
@@ -18,3 +18,5 @@ e = executable('prog', 'main.cpp', generated,
test('prototest', e)
subdir('asubdir')
+subdir('withpath')
+subdir('sidedir')
diff --git a/test cases/frameworks/5 protocol buffers/sidedir/meson.build b/test cases/frameworks/5 protocol buffers/sidedir/meson.build
new file mode 100644
index 0000000..ce9b7be
--- /dev/null
+++ b/test cases/frameworks/5 protocol buffers/sidedir/meson.build
@@ -0,0 +1,7 @@
+# Generated source defined in one directory but
+# used in another.
+
+e = executable('sideprog', 'sideprog.cpp', generated,
+ override_options : ['unity=off'],
+ dependencies : dep)
+test('sideprog', e)
diff --git a/test cases/frameworks/5 protocol buffers/sidedir/sideprog.cpp b/test cases/frameworks/5 protocol buffers/sidedir/sideprog.cpp
new file mode 100644
index 0000000..83af4b2
--- /dev/null
+++ b/test cases/frameworks/5 protocol buffers/sidedir/sideprog.cpp
@@ -0,0 +1,16 @@
+#include"com/mesonbuild/simple.pb.h"
+#include"com/mesonbuild/subsite/complex.pb.h"
+
+#include<memory>
+
+int main(int argc, char **argv) {
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+ {
+ subdirectorial::SimpleMessage *s = new subdirectorial::SimpleMessage();
+ s->set_the_integer(3);
+ subdirectorial::ComplexMessage c;
+ c.set_allocated_sm(s);
+ }
+ google::protobuf::ShutdownProtobufLibrary();
+ return 0;
+}
diff --git a/test cases/frameworks/5 protocol buffers/withpath/com/mesonbuild/simple.proto b/test cases/frameworks/5 protocol buffers/withpath/com/mesonbuild/simple.proto
new file mode 100644
index 0000000..336779f
--- /dev/null
+++ b/test cases/frameworks/5 protocol buffers/withpath/com/mesonbuild/simple.proto
@@ -0,0 +1,7 @@
+syntax = "proto3";
+
+package subdirectorial;
+
+message SimpleMessage {
+ int32 the_integer = 1;
+}
diff --git a/test cases/frameworks/5 protocol buffers/withpath/com/mesonbuild/subsite/complex.proto b/test cases/frameworks/5 protocol buffers/withpath/com/mesonbuild/subsite/complex.proto
new file mode 100644
index 0000000..8dc32c2
--- /dev/null
+++ b/test cases/frameworks/5 protocol buffers/withpath/com/mesonbuild/subsite/complex.proto
@@ -0,0 +1,10 @@
+syntax = "proto3";
+
+package subdirectorial;
+
+import "com/mesonbuild/simple.proto";
+
+message ComplexMessage {
+ string a_message = 1;
+ SimpleMessage sm = 2;
+}
diff --git a/test cases/frameworks/5 protocol buffers/withpath/meson.build b/test cases/frameworks/5 protocol buffers/withpath/meson.build
new file mode 100644
index 0000000..68a7381
--- /dev/null
+++ b/test cases/frameworks/5 protocol buffers/withpath/meson.build
@@ -0,0 +1,13 @@
+# Testing protobuf files that are deeply hierarchical
+# and must preserve their path segments in output files
+# because protoc will always put it in there.
+
+generated = gen.process('com/mesonbuild/simple.proto',
+ 'com/mesonbuild/subsite/complex.proto',
+ preserve_path_from : meson.current_source_dir(),
+ )
+
+e = executable('pathprog', 'pathprog.cpp', generated,
+ override_options : ['unity=off'],
+ dependencies : dep)
+test('pathprog', e)
diff --git a/test cases/frameworks/5 protocol buffers/withpath/pathprog.cpp b/test cases/frameworks/5 protocol buffers/withpath/pathprog.cpp
new file mode 100644
index 0000000..83af4b2
--- /dev/null
+++ b/test cases/frameworks/5 protocol buffers/withpath/pathprog.cpp
@@ -0,0 +1,16 @@
+#include"com/mesonbuild/simple.pb.h"
+#include"com/mesonbuild/subsite/complex.pb.h"
+
+#include<memory>
+
+int main(int argc, char **argv) {
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+ {
+ subdirectorial::SimpleMessage *s = new subdirectorial::SimpleMessage();
+ s->set_the_integer(3);
+ subdirectorial::ComplexMessage c;
+ c.set_allocated_sm(s);
+ }
+ google::protobuf::ShutdownProtobufLibrary();
+ return 0;
+}
diff --git a/test cases/frameworks/7 gnome/gir/meson.build b/test cases/frameworks/7 gnome/gir/meson.build
index a91cb97..1771548 100644
--- a/test cases/frameworks/7 gnome/gir/meson.build
+++ b/test cases/frameworks/7 gnome/gir/meson.build
@@ -41,5 +41,8 @@ gir_paths = ':'.join([girlib.outdir(), dep1lib.outdir(), dep2lib.outdir()])
envdata = environment()
envdata.append('GI_TYPELIB_PATH', gir_paths, separator : ':')
envdata.append('LD_LIBRARY_PATH', gir_paths)
+if ['windows', 'cygwin'].contains(host_machine.system())
+ envdata.append('PATH', gir_paths)
+endif
test('gobject introspection/py', find_program('prog.py'),
env : envdata)
diff --git a/test cases/frameworks/7 gnome/installed_files.txt b/test cases/frameworks/7 gnome/installed_files.txt
index d0d51d5..c7c704f 100644
--- a/test cases/frameworks/7 gnome/installed_files.txt
+++ b/test cases/frameworks/7 gnome/installed_files.txt
@@ -2,9 +2,9 @@ usr/include/enums.h
usr/include/enums2.h
usr/include/enums3.h
usr/include/marshaller.h
-usr/lib/libgir_lib.so
-usr/lib/libdep1lib.so
-usr/lib/libdep2lib.so
+usr/lib/?libgir_lib.so
+usr/lib/?libdep1lib.so
+usr/lib/?libdep2lib.so
usr/lib/girepository-1.0/Meson-1.0.typelib
usr/lib/girepository-1.0/MesonDep1-1.0.typelib
usr/lib/girepository-1.0/MesonDep2-1.0.typelib
diff --git a/test cases/objc/2 nsstring/meson.build b/test cases/objc/2 nsstring/meson.build
index a877d74..7f2483f 100644
--- a/test cases/objc/2 nsstring/meson.build
+++ b/test cases/objc/2 nsstring/meson.build
@@ -5,7 +5,10 @@ if host_machine.system() == 'darwin'
elif host_machine.system() == 'cygwin'
error('MESON_SKIP_TEST GNUstep is not packaged for Cygwin.')
else
- dep = dependency('gnustep')
+ dep = dependency('gnustep', required : false)
+ if not dep.found()
+ error('MESON_SKIP_TEST: GNUstep is not installed')
+ endif
if host_machine.system() == 'linux' and meson.get_compiler('objc').get_id() == 'clang'
error('MESON_SKIP_TEST: GNUstep is broken on Linux with Clang')
endif
diff --git a/test cases/objc/4 objc args/meson.build b/test cases/objc/3 objc args/meson.build
index 8887d96..8887d96 100644
--- a/test cases/objc/4 objc args/meson.build
+++ b/test cases/objc/3 objc args/meson.build
diff --git a/test cases/objc/4 objc args/prog.m b/test cases/objc/3 objc args/prog.m
index bfd686a..bfd686a 100644
--- a/test cases/objc/4 objc args/prog.m
+++ b/test cases/objc/3 objc args/prog.m
diff --git a/test cases/objc/3 objc++/meson.build b/test cases/objcpp/1 simple/meson.build
index 7d91884..7d91884 100644
--- a/test cases/objc/3 objc++/meson.build
+++ b/test cases/objcpp/1 simple/meson.build
diff --git a/test cases/objc/3 objc++/prog.mm b/test cases/objcpp/1 simple/prog.mm
index 927e810..927e810 100644
--- a/test cases/objc/3 objc++/prog.mm
+++ b/test cases/objcpp/1 simple/prog.mm
diff --git a/test cases/objc/5 objc++ args/meson.build b/test cases/objcpp/2 objc++ args/meson.build
index e0e34b0..e0e34b0 100644
--- a/test cases/objc/5 objc++ args/meson.build
+++ b/test cases/objcpp/2 objc++ args/meson.build
diff --git a/test cases/objc/5 objc++ args/prog.mm b/test cases/objcpp/2 objc++ args/prog.mm
index 3decaf2..3decaf2 100644
--- a/test cases/objc/5 objc++ args/prog.mm
+++ b/test cases/objcpp/2 objc++ args/prog.mm
diff --git a/test cases/vala/11 generated vapi/installed_files.txt b/test cases/vala/11 generated vapi/installed_files.txt
index 5993d01..aeaf2da 100644
--- a/test cases/vala/11 generated vapi/installed_files.txt
+++ b/test cases/vala/11 generated vapi/installed_files.txt
@@ -1,6 +1,6 @@
usr/bin/vapigen-test
-usr/lib/libfoo.so
-usr/lib/libbar.so
+usr/lib/?libfoo.so
+usr/lib/?libbar.so
usr/share/vala/vapi/foo-1.0.vapi
usr/share/vala/vapi/foo-1.0.deps
usr/share/vala/vapi/bar-1.0.vapi
diff --git a/test cases/vala/11 generated vapi/libbar/bar.c b/test cases/vala/11 generated vapi/libbar/bar.c
index f0f5cb8..3037141 100644
--- a/test cases/vala/11 generated vapi/libbar/bar.c
+++ b/test cases/vala/11 generated vapi/libbar/bar.c
@@ -1,12 +1,29 @@
#include "bar.h"
#include "foo.h"
+struct _BarBar
+{
+ GObject parent_instance;
+};
+
+G_DEFINE_TYPE (BarBar, bar_bar, G_TYPE_OBJECT)
+
+static void
+bar_bar_class_init (BarBarClass *klass)
+{
+}
+
+static void
+bar_bar_init (BarBar *self)
+{
+}
+
/**
- * bar_return_success:
+ * bar_bar_return_success:
*
* Returns 0
*/
-int bar_return_success(void)
+int bar_bar_return_success(void)
{
- return foo_return_success();
+ return foo_foo_return_success();
}
diff --git a/test cases/vala/11 generated vapi/libbar/bar.h b/test cases/vala/11 generated vapi/libbar/bar.h
index 165b104..4ca7270 100644
--- a/test cases/vala/11 generated vapi/libbar/bar.h
+++ b/test cases/vala/11 generated vapi/libbar/bar.h
@@ -2,4 +2,8 @@
#pragma once
-int bar_return_success(void);
+#define BAR_TYPE_BAR (bar_bar_get_type())
+
+G_DECLARE_FINAL_TYPE (BarBar, bar_bar, BAR, BAR, GObject)
+
+int bar_bar_return_success(void);
diff --git a/test cases/vala/11 generated vapi/libfoo/foo.c b/test cases/vala/11 generated vapi/libfoo/foo.c
index 0413ac5..dd2b891 100644
--- a/test cases/vala/11 generated vapi/libfoo/foo.c
+++ b/test cases/vala/11 generated vapi/libfoo/foo.c
@@ -1,11 +1,28 @@
#include "foo.h"
+struct _FooFoo
+{
+ GObject parent_instance;
+};
+
+G_DEFINE_TYPE (FooFoo, foo_foo, G_TYPE_OBJECT)
+
+static void
+foo_foo_class_init (FooFooClass *klass)
+{
+}
+
+static void
+foo_foo_init (FooFoo *self)
+{
+}
+
/**
- * foo_return_success:
+ * foo_foo_return_success:
*
* Returns 0
*/
-int foo_return_success(void)
+int foo_foo_return_success(void)
{
- return 0;
+ return 0;
}
diff --git a/test cases/vala/11 generated vapi/libfoo/foo.h b/test cases/vala/11 generated vapi/libfoo/foo.h
index f09256d..e1887d8 100644
--- a/test cases/vala/11 generated vapi/libfoo/foo.h
+++ b/test cases/vala/11 generated vapi/libfoo/foo.h
@@ -2,4 +2,8 @@
#pragma once
-int foo_return_success(void);
+#define FOO_TYPE_FOO (foo_foo_get_type())
+
+G_DECLARE_FINAL_TYPE (FooFoo, foo_foo, Foo, FOO, GObject)
+
+int foo_foo_return_success(void);
diff --git a/test cases/vala/11 generated vapi/main.vala b/test cases/vala/11 generated vapi/main.vala
index 303ab33..d61fba0 100644
--- a/test cases/vala/11 generated vapi/main.vala
+++ b/test cases/vala/11 generated vapi/main.vala
@@ -3,7 +3,7 @@ using Bar;
class Main : GLib.Object {
public static int main(string[] args) {
- var ignore = Foo.return_success();
- return Bar.return_success();
+ var ignore = Foo.Foo.return_success();
+ return Bar.Bar.return_success();
}
}
diff --git a/test cases/vala/7 shared library/installed_files.txt b/test cases/vala/7 shared library/installed_files.txt
index f70e439..012b107 100644
--- a/test cases/vala/7 shared library/installed_files.txt
+++ b/test cases/vala/7 shared library/installed_files.txt
@@ -1,5 +1,5 @@
-usr/lib/libinstalled_vala_lib.so
-usr/lib/libinstalled_vala_all.so
+usr/lib/?libinstalled_vala_lib.so
+usr/lib/?libinstalled_vala_all.so
usr/include/installed_vala_all.h
usr/include/valah/installed_vala_all_nolib.h
usr/include/installed_vala_onlyh.h
diff --git a/test cases/vala/9 gir/installed_files.txt b/test cases/vala/9 gir/installed_files.txt
index 7a0e055..64bddee 100644
--- a/test cases/vala/9 gir/installed_files.txt
+++ b/test cases/vala/9 gir/installed_files.txt
@@ -1,2 +1,2 @@
-usr/lib/libfoo.so
+usr/lib/?libfoo.so
usr/share/gir-1.0/Foo-1.0.gir
diff --git a/wraptool.py b/wraptool.py
index 5e03efd..a5ee9ef 100755
--- a/wraptool.py
+++ b/wraptool.py
@@ -17,4 +17,7 @@
from mesonbuild.wrap import wraptool
import sys
-sys.exit(wraptool.run(sys.argv[1:]))
+if __name__ == '__main__':
+ print('Warning: This executable is deprecated. Use "meson wrap" instead.',
+ file=sys.stderr)
+ sys.exit(wraptool.run(sys.argv[1:]))