aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Reference-manual.md28
-rw-r--r--docs/markdown/snippets/native_args.md34
-rw-r--r--mesonbuild/backend/backends.py14
-rw-r--r--mesonbuild/backend/ninjabackend.py22
-rw-r--r--mesonbuild/backend/vs2010backend.py4
-rw-r--r--mesonbuild/build.py25
-rw-r--r--mesonbuild/compilers/c.py116
-rw-r--r--mesonbuild/compilers/compilers.py30
-rw-r--r--mesonbuild/compilers/fortran.py14
-rw-r--r--mesonbuild/coredata.py3
-rw-r--r--mesonbuild/dependencies/boost.py2
-rw-r--r--mesonbuild/interpreter.py66
-rw-r--r--mesonbuild/mconf.py5
-rw-r--r--mesonbuild/mesonmain.py12
-rw-r--r--mesonbuild/mintro.py3
-rw-r--r--mesonbuild/mlog.py3
-rw-r--r--mesonbuild/wrap/wraptool.py4
-rwxr-xr-xrun_tests.py36
-rwxr-xr-xrun_unittests.py53
-rw-r--r--test cases/common/21 global arg/meson.build11
-rw-r--r--test cases/common/21 global arg/prog.c36
-rw-r--r--test cases/unit/39 external, internal library rpath/built library/meson.build13
-rw-r--r--test cases/unit/39 external, internal library rpath/external library/bar.c6
-rw-r--r--test cases/unit/39 external, internal library rpath/external library/meson.build17
24 files changed, 366 insertions, 191 deletions
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index 3ae740d..6cf7552 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -13,13 +13,22 @@ afterwards](#returned-objects).
void add_global_arguments(arg1, arg2, ...)
```
-Adds the positional arguments to the compiler command line for the
-language specified in `language` keyword argument. If a list of
-languages is given, the arguments are added to each of the
-corresponding compiler command lines. Note that there is no way to
-remove an argument set in this way. If you have an argument that is
-only used in a subset of targets, you have to specify it in per-target
-flags.
+Adds the positional arguments to the compiler command line. This
+function has two keyword arguments:
+
+- `language` specifies the language(s) that the arguments should be
+applied to. If a list of languages is given, the arguments are added
+to each of the corresponding compiler command lines. Note that there
+is no way to remove an argument set in this way. If you have an
+argument that is only used in a subset of targets, you have to specify
+it in per-target flags.
+
+- `native` is a boolean specifying whether the arguments should be
+ applied to the native or cross compilation. If `true` the arguments
+ will only be used for native compilations. If `false` the arguments
+ will only be used in cross compilations. If omitted, the flags are
+ added to native compilations if compiling natively and cross
+ compilations (only) when cross compiling. Available since 0.48.0
The arguments are used in all compiler invocations with the exception
of compile tests, because you might need to run a compile test with
@@ -60,8 +69,9 @@ endif
Takes one keyword argument, `required`. It defaults to `true`, which
means that if any of the languages specified is not found, Meson will
halt. Returns true if all languages specified were found and false
-otherwise. Since *0.47.0* the value of a [`feature`](Build-options.md#features)
-option can also be passed to the `required` keyword argument.
+otherwise. Since *0.47.0* the value of a
+[`feature`](Build-options.md#features) option can also be passed to
+the `required` keyword argument.
### add_project_arguments()
diff --git a/docs/markdown/snippets/native_args.md b/docs/markdown/snippets/native_args.md
new file mode 100644
index 0000000..54c6de2
--- /dev/null
+++ b/docs/markdown/snippets/native_args.md
@@ -0,0 +1,34 @@
+## Projects args can be set separately for cross and native builds (potentially breaking change)
+
+It has been a longstanding bug (or let's call it a "delayed bug fix")
+that if yo do this:
+
+```meson
+add_project_arguments('-DFOO', language : 'c')
+```
+
+Then the flag is used both in native and cross compilations. This is
+very confusing and almost never what you want. To fix this a new
+keyword `native` has been added to all functions that add arguments,
+namely `add_global_arguments`, `add_global_link_arguments`,
+`add_project_arguments` and `add_project_link_arguments` that behaves
+like the following:
+
+```
+## Added to native builds when compiling natively and to cross
+## compilations when doing cross compiles.
+add_project_arguments(...)
+
+## Added only to native compilations, not used in cross compilations.
+add_project_arguments(..., native : true)
+
+## Added only to cross compilations, not used in native compilations.
+add_project_arguments(..., native : false)
+```
+
+Also remember that cross compilation is a property of each
+target. There can be target that are compiled with the native compiler
+and some which are compiled with the cross compiler.
+
+Unfortunately this change is backwards incompatible and may cause some
+projects to fail building. However this should be very rare in practice.
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 7ed97b2..bdc3fad 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -355,9 +355,9 @@ class Backend:
return l, stdlib_args
@staticmethod
- def _libdir_is_system(libdir, compilers):
+ def _libdir_is_system(libdir, compilers, env):
for cc in compilers.values():
- if libdir in cc.get_library_dirs():
+ if libdir in cc.get_library_dirs(env):
return True
return False
@@ -372,7 +372,7 @@ class Backend:
# The only link argument is an absolute path to a library file.
libpath = la[0]
libdir = os.path.dirname(libpath)
- if exclude_system and self._libdir_is_system(libdir, target.compilers):
+ if exclude_system and self._libdir_is_system(libdir, target.compilers, self.environment):
# No point in adding system paths.
continue
# Windows doesn't support rpaths, but we use this function to
@@ -535,10 +535,10 @@ class Backend:
commands += compiler.get_optimization_args(self.get_option_for_target('optimization', target))
commands += compiler.get_debug_args(self.get_option_for_target('debug', target))
# Add compile args added using add_project_arguments()
- commands += self.build.get_project_args(compiler, target.subproject)
+ commands += self.build.get_project_args(compiler, target.subproject, target.is_cross)
# Add compile args added using add_global_arguments()
# These override per-project arguments
- commands += self.build.get_global_args(compiler)
+ commands += self.build.get_global_args(compiler, target.is_cross)
if not target.is_cross:
# Compile args added from the env: CFLAGS/CXXFLAGS, etc. We want these
# to override all the defaults, but not the per-target compile args.
@@ -612,8 +612,8 @@ class Backend:
# Get program and library dirs from all target compilers
if isinstance(target, build.BuildTarget):
for cc in target.compilers.values():
- paths.update(cc.get_program_dirs())
- paths.update(cc.get_library_dirs())
+ paths.update(cc.get_program_dirs(self.environment))
+ paths.update(cc.get_library_dirs(self.environment))
return list(paths)
def determine_windows_extra_paths(self, target, extra_bdeps, is_cross=False):
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index ace0693..83bff8a 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -855,8 +855,8 @@ int dummy;
for dep in target.get_external_deps():
commands.extend_direct(dep.get_link_args())
- commands += self.build.get_project_args(compiler, target.subproject)
- commands += self.build.get_global_args(compiler)
+ commands += self.build.get_project_args(compiler, target.subproject, target.is_cross)
+ commands += self.build.get_global_args(compiler, target.is_cross)
elem = NinjaBuildElement(self.all_outputs, outputs, 'cs_COMPILER', rel_srcs)
elem.add_dep(deps)
@@ -869,8 +869,8 @@ int dummy;
deps = [os.path.join(self.get_target_dir(l), l.get_filename()) for l in target.link_targets]
args = []
args += compiler.get_buildtype_args(self.get_option_for_target('buildtype', target))
- args += self.build.get_global_args(compiler)
- args += self.build.get_project_args(compiler, target.subproject)
+ args += self.build.get_global_args(compiler, target.is_cross)
+ args += self.build.get_project_args(compiler, target.subproject, target.is_cross)
args += target.get_java_args()
args += compiler.get_output_args(self.get_target_private_dir(target))
args += target.get_classpath_args()
@@ -1247,8 +1247,8 @@ int dummy;
compile_args += swiftc.get_optimization_args(self.get_option_for_target('optimization', target))
compile_args += swiftc.get_debug_args(self.get_option_for_target('debug', target))
compile_args += swiftc.get_module_args(module_name)
- compile_args += self.build.get_project_args(swiftc, target.subproject)
- compile_args += self.build.get_global_args(swiftc)
+ compile_args += self.build.get_project_args(swiftc, target.subproject, target.is_cross)
+ compile_args += self.build.get_global_args(swiftc, target.is_cross)
for i in reversed(target.get_include_dirs()):
basedir = i.get_curdir()
for d in i.get_incdirs():
@@ -1260,8 +1260,8 @@ int dummy;
sargs = swiftc.get_include_args(srctreedir)
compile_args += sargs
link_args = swiftc.get_output_args(os.path.join(self.environment.get_build_dir(), self.get_target_filename(target)))
- link_args += self.build.get_project_link_args(swiftc, target.subproject)
- link_args += self.build.get_global_link_args(swiftc)
+ link_args += self.build.get_project_link_args(swiftc, target.subproject, target.is_cross)
+ link_args += self.build.get_global_link_args(swiftc, target.is_cross)
rundir = self.get_target_private_dir(target)
out_module_name = self.swift_module_file_name(target)
in_module_files = self.determine_swift_dep_modules(target)
@@ -2333,7 +2333,7 @@ rule FORTRAN_DEP_HACK%s
guessed_dependencies = []
# TODO The get_library_naming requirement currently excludes link targets that use d or fortran as their main linker
if hasattr(linker, 'get_library_naming'):
- search_dirs = list(search_dirs) + linker.get_library_dirs()
+ search_dirs = list(search_dirs) + linker.get_library_dirs(self.environment)
static_patterns = linker.get_library_naming(self.environment, 'static', strict=True)
shared_patterns = linker.get_library_naming(self.environment, 'shared', strict=True)
for libname in libs:
@@ -2395,10 +2395,10 @@ rule FORTRAN_DEP_HACK%s
if not isinstance(target, build.StaticLibrary):
# Add link args added using add_project_link_arguments()
- commands += self.build.get_project_link_args(linker, target.subproject)
+ commands += self.build.get_project_link_args(linker, target.subproject, target.is_cross)
# Add link args added using add_global_link_arguments()
# These override per-project link arguments
- commands += self.build.get_global_link_args(linker)
+ commands += self.build.get_global_link_args(linker, target.is_cross)
if not target.is_cross:
# Link args added from the env: LDFLAGS. We want these to
# override all the defaults but not the per-target link args.
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index 4c799d0..2e86ca9 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -998,10 +998,10 @@ class Vs2010Backend(backends.Backend):
options = self.environment.coredata.base_options
extra_link_args += compiler.get_std_shared_module_link_args(options)
# Add link args added using add_project_link_arguments()
- extra_link_args += self.build.get_project_link_args(compiler, target.subproject)
+ extra_link_args += self.build.get_project_link_args(compiler, target.subproject, target.is_cross)
# Add link args added using add_global_link_arguments()
# These override per-project link arguments
- extra_link_args += self.build.get_global_link_args(compiler)
+ extra_link_args += self.build.get_global_link_args(compiler, target.is_cross)
if not target.is_cross:
# Link args added from the env: LDFLAGS. We want these to
# override all the defaults but not the per-target link args.
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index c1cb8a8..caaadd8 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -108,6 +108,10 @@ class Build:
self.projects_args = {}
self.global_link_args = {}
self.projects_link_args = {}
+ self.cross_global_args = {}
+ self.cross_projects_args = {}
+ self.cross_global_link_args = {}
+ self.cross_projects_link_args = {}
self.tests = []
self.benchmarks = []
self.headers = []
@@ -168,20 +172,25 @@ class Build:
def get_install_subdirs(self):
return self.install_dirs
- def get_global_args(self, compiler):
- return self.global_args.get(compiler.get_language(), [])
+ def get_global_args(self, compiler, for_cross):
+ d = self.cross_global_args if for_cross else self.global_args
+ return d.get(compiler.get_language(), [])
- def get_project_args(self, compiler, project):
- args = self.projects_args.get(project)
+ def get_project_args(self, compiler, project, for_cross):
+ d = self.cross_projects_args if for_cross else self.projects_args
+ args = d.get(project)
if not args:
return []
return args.get(compiler.get_language(), [])
- def get_global_link_args(self, compiler):
- return self.global_link_args.get(compiler.get_language(), [])
+ def get_global_link_args(self, compiler, for_cross):
+ d = self.cross_global_link_args if for_cross else self.global_link_args
+ return d.get(compiler.get_language(), [])
- def get_project_link_args(self, compiler, project):
- link_args = self.projects_link_args.get(project)
+ def get_project_link_args(self, compiler, project, for_cross):
+ d = self.cross_projects_link_args if for_cross else self.projects_link_args
+
+ link_args = d.get(project)
if not link_args:
return []
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index c7092b8..436f699 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -16,6 +16,8 @@ import re
import glob
import os.path
import subprocess
+import functools
+import itertools
from pathlib import Path
from .. import mlog
@@ -49,6 +51,7 @@ gnu_compiler_internal_libs = ('m', 'c', 'pthread', 'dl', 'rt')
class CCompiler(Compiler):
+ # TODO: Replace this manual cache with functools.lru_cache
library_dirs_cache = {}
program_dirs_cache = {}
find_library_cache = {}
@@ -144,6 +147,30 @@ class CCompiler(Compiler):
'''
return self.get_no_optimization_args()
+ def get_allow_undefined_link_args(self):
+ '''
+ Get args for allowing undefined symbols when linking to a shared library
+ '''
+ if self.id == 'clang':
+ if self.clang_type == compilers.CLANG_OSX:
+ # Apple ld
+ return ['-Wl,-undefined,dynamic_lookup']
+ else:
+ # GNU ld and LLVM lld
+ return ['-Wl,--allow-shlib-undefined']
+ elif self.id == 'gcc':
+ if self.gcc_type == compilers.GCC_OSX:
+ # Apple ld
+ return ['-Wl,-undefined,dynamic_lookup']
+ else:
+ # GNU ld and LLVM lld
+ return ['-Wl,--allow-shlib-undefined']
+ elif self.id == 'msvc':
+ # link.exe
+ return ['/FORCE:UNRESOLVED']
+ # FIXME: implement other linkers
+ return []
+
def get_output_args(self, target):
return ['-o', target]
@@ -172,42 +199,47 @@ class CCompiler(Compiler):
def get_std_shared_lib_link_args(self):
return ['-shared']
- def get_library_dirs_real(self):
- env = os.environ.copy()
- env['LC_ALL'] = 'C'
- stdo = Popen_safe(self.exelist + ['--print-search-dirs'], env=env)[1]
+ @functools.lru_cache()
+ def _get_search_dirs(self, env):
+ extra_args = ['--print-search-dirs']
+ stdo = None
+ with self._build_wrapper('', env, extra_args, None, 'compile', True) as p:
+ stdo = p.stdo
+ return stdo
+
+ @staticmethod
+ def _split_fetch_real_dirs(pathstr, sep=':'):
paths = []
- for line in stdo.split('\n'):
- if line.startswith('libraries:'):
- libstr = line.split('=', 1)[1]
- paths = [os.path.realpath(p) for p in libstr.split(':') if os.path.exists(os.path.realpath(p))]
+ for p in pathstr.split(sep):
+ p = Path(p)
+ if p.exists():
+ paths.append(p.resolve().as_posix())
return paths
- def get_library_dirs(self):
- key = tuple(self.exelist)
+ def get_compiler_dirs(self, env, name):
+ '''
+ Get dirs from the compiler, either `libraries:` or `programs:`
+ '''
+ stdo = self._get_search_dirs(env)
+ for line in stdo.split('\n'):
+ if line.startswith(name + ':'):
+ return CCompiler._split_fetch_real_dirs(line.split('=', 1)[1])
+ return []
+
+ def get_library_dirs(self, env):
+ key = (tuple(self.exelist), env)
if key not in self.library_dirs_cache:
- self.library_dirs_cache[key] = self.get_library_dirs_real()
+ self.library_dirs_cache[key] = self.get_compiler_dirs(env, 'libraries')
return self.library_dirs_cache[key][:]
- def get_program_dirs_real(self):
- env = os.environ.copy()
- env['LC_ALL'] = 'C'
- stdo = Popen_safe(self.exelist + ['--print-search-dirs'], env=env)[1]
- paths = []
- for line in stdo.split('\n'):
- if line.startswith('programs:'):
- libstr = line.split('=', 1)[1]
- paths = [os.path.realpath(p) for p in libstr.split(':')]
- return paths
-
- def get_program_dirs(self):
+ def get_program_dirs(self, env):
'''
Programs used by the compiler. Also where toolchain DLLs such as
libstdc++-6.dll are found with MinGW.
'''
- key = tuple(self.exelist)
+ key = (tuple(self.exelist), env)
if key not in self.program_dirs_cache:
- self.program_dirs_cache[key] = self.get_program_dirs_real()
+ self.program_dirs_cache[key] = self.get_compiler_dirs(env, 'programs')
return self.program_dirs_cache[key][:]
def get_pic_args(self):
@@ -908,7 +940,8 @@ class CCompiler(Compiler):
# Only try to find std libs if no extra dirs specified.
if not extra_dirs or libname in self.internal_libs:
args = ['-l' + libname]
- if self.links(code, env, extra_args=args):
+ largs = self.linker_to_compiler_args(self.get_allow_undefined_link_args())
+ if self.links(code, env, extra_args=(args + largs)):
return args
# Don't do a manual search for internal libs
if libname in self.internal_libs:
@@ -916,35 +949,19 @@ class CCompiler(Compiler):
# Not found or we want to use a specific libtype? Try to find the
# library file itself.
patterns = self.get_library_naming(env, libtype)
- for d in extra_dirs:
+ # Search in the specified dirs, and then in the system libraries
+ for d in itertools.chain(extra_dirs, self.get_library_dirs(env)):
for p in patterns:
trial = self._get_trials_from_pattern(p, d, libname)
if not trial:
continue
+ # We just check whether the library exists. We can't do a link
+ # check because the library might have unresolved symbols that
+ # require other libraries.
trial = self._get_file_from_list(trial)
if not trial:
continue
return [trial]
- # Search in the system libraries too
- for d in self.get_library_dirs():
- for p in patterns:
- trial = self._get_trials_from_pattern(p, d, libname)
- if not trial:
- continue
- trial = self._get_file_from_list(trial)
- if not trial:
- continue
- # When searching the system paths used by the compiler, we
- # need to check linking with link-whole, as static libs
- # (.a) need to be checked to ensure they are the right
- # architecture, e.g. 32bit or 64-bit.
- # Just a normal test link won't work as the .a file doesn't
- # seem to be checked by linker if there are no unresolved
- # symbols from the main C file.
- extra_link_args = self.get_link_whole_for([trial])
- extra_link_args = self.linker_to_compiler_args(extra_link_args)
- if self.links(code, env, extra_args=extra_link_args):
- return [trial]
return None
def find_library_impl(self, libname, env, extra_dirs, code, libtype):
@@ -1230,7 +1247,10 @@ class VisualStudioCCompiler(CCompiler):
return ['/MDd']
def get_buildtype_args(self, buildtype):
- return compilers.msvc_buildtype_args[buildtype]
+ args = compilers.msvc_buildtype_args[buildtype]
+ if version_compare(self.version, '<18.0'):
+ args = [arg for arg in args if arg != '/Gw']
+ return args
def get_buildtype_linker_args(self, buildtype):
return compilers.msvc_buildtype_linker_args[buildtype]
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index b400478..d08671e 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -145,8 +145,8 @@ arm_buildtype_args = {'plain': [],
msvc_buildtype_args = {'plain': [],
'debug': ["/ZI", "/Ob0", "/Od", "/RTC1"],
'debugoptimized': ["/Zi", "/Ob1"],
- 'release': ["/Ob2"],
- 'minsize': ["/Zi", "/Ob1"],
+ 'release': ["/Ob2", "/Gw"],
+ 'minsize': ["/Zi", "/Gw"],
}
apple_buildtype_linker_args = {'plain': [],
@@ -267,7 +267,7 @@ msvc_optimization_args = {'0': [],
'1': ['/O1'],
'2': ['/O2'],
'3': ['/O3'],
- 's': ['/Os'],
+ 's': ['/O1'], # Implies /Os.
}
clike_debug_args = {False: [],
@@ -908,7 +908,7 @@ class Compiler:
def find_library(self, *args, **kwargs):
raise EnvironmentException('Language {} does not support library finding.'.format(self.get_display_language()))
- def get_library_dirs(self):
+ def get_library_dirs(self, *args, **kwargs):
return []
def has_multi_arguments(self, args, env):
@@ -995,7 +995,9 @@ class Compiler:
mlog.debug('Working directory: ', tmpdirname)
mlog.debug('Command line: ', ' '.join(commands), '\n')
mlog.debug('Code:\n', code)
- p, p.stdo, p.stde = Popen_safe(commands, cwd=tmpdirname)
+ os_env = os.environ.copy()
+ os_env['LC_ALL'] = 'C'
+ p, p.stdo, p.stde = Popen_safe(commands, cwd=tmpdirname, env=os_env)
mlog.debug('Compiler stdout:\n', p.stdo)
mlog.debug('Compiler stderr:\n', p.stde)
p.commands = commands
@@ -1353,10 +1355,12 @@ class ElbrusCompiler(GnuCompiler):
'b_ndebug', 'b_staticpic',
'b_lundef', 'b_asneeded']
- def get_library_dirs(self):
- env = os.environ.copy()
- env['LC_ALL'] = 'C'
- stdo = Popen_safe(self.exelist + ['--print-search-dirs'], env=env)[1]
+ # FIXME: use _build_wrapper to call this so that linker flags from the env
+ # get applied
+ def get_library_dirs(self, env):
+ os_env = os.environ.copy()
+ os_env['LC_ALL'] = 'C'
+ stdo = Popen_safe(self.exelist + ['--print-search-dirs'], env=os_env)[1]
paths = []
for line in stdo.split('\n'):
if line.startswith('libraries:'):
@@ -1366,10 +1370,10 @@ class ElbrusCompiler(GnuCompiler):
break
return paths
- def get_program_dirs(self):
- env = os.environ.copy()
- env['LC_ALL'] = 'C'
- stdo = Popen_safe(self.exelist + ['--print-search-dirs'], env=env)[1]
+ def get_program_dirs(self, env):
+ os_env = os.environ.copy()
+ os_env['LC_ALL'] = 'C'
+ stdo = Popen_safe(self.exelist + ['--print-search-dirs'], env=os_env)[1]
paths = []
for line in stdo.split('\n'):
if line.startswith('programs:'):
diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py
index 5648a6f..1ee1fcb 100644
--- a/mesonbuild/compilers/fortran.py
+++ b/mesonbuild/compilers/fortran.py
@@ -144,6 +144,9 @@ end program prog
def get_compiler_check_args(self):
return CCompiler.get_compiler_check_args(self)
+ def get_allow_undefined_link_args(self):
+ return CCompiler.get_allow_undefined_link_args(self)
+
def get_output_args(self, target):
return CCompiler.get_output_args(self, target)
@@ -177,11 +180,14 @@ end program prog
def get_std_shared_lib_link_args(self):
return CCompiler.get_std_shared_lib_link_args(self)
- def get_library_dirs_real(self):
- return CCompiler.get_library_dirs_real(self)
+ def _get_search_dirs(self, *args, **kwargs):
+ return CCompiler._get_search_dirs(self, *args, **kwargs)
+
+ def get_compiler_dirs(self, *args, **kwargs):
+ return CCompiler.get_compiler_dirs(self, *args, **kwargs)
- def get_library_dirs(self):
- return CCompiler.get_library_dirs(self)
+ def get_library_dirs(self, *args, **kwargs):
+ return CCompiler.get_library_dirs(self, *args, **kwargs)
def get_pic_args(self):
return CCompiler.get_pic_args(self)
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index afd39c8..4b32c19 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -19,6 +19,7 @@ from pathlib import PurePath
from collections import OrderedDict
from .mesonlib import MesonException
from .mesonlib import default_libdir, default_libexecdir, default_prefix
+from .wrap import WrapMode
import ast
import argparse
@@ -222,7 +223,7 @@ class CoreData:
self.base_options = {}
self.external_preprocess_args = {} # CPPFLAGS only
self.cross_file = self.__load_cross_file(options.cross_file)
- self.wrap_mode = options.wrap_mode
+ self.wrap_mode = options.wrap_mode if options.wrap_mode is not None else WrapMode.default
self.compilers = OrderedDict()
self.cross_compilers = OrderedDict()
self.deps = OrderedDict()
diff --git a/mesonbuild/dependencies/boost.py b/mesonbuild/dependencies/boost.py
index 17f9240..b06f62d 100644
--- a/mesonbuild/dependencies/boost.py
+++ b/mesonbuild/dependencies/boost.py
@@ -443,7 +443,7 @@ class BoostDependency(ExternalDependency):
if self.libdir:
libdirs = [self.libdir]
elif self.boost_root is None:
- libdirs = mesonlib.get_library_dirs()
+ libdirs = mesonlib.get_library_dirs(self.env)
else:
libdirs = [os.path.join(self.boost_root, 'lib')]
for libdir in libdirs:
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 707cf9e..04e963a 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -1808,11 +1808,11 @@ known_build_target_kwargs = (
{'target_type'}
)
-permitted_kwargs = {'add_global_arguments': {'language'},
- 'add_global_link_arguments': {'language'},
- 'add_project_link_arguments': {'language'},
+permitted_kwargs = {'add_global_arguments': {'language', 'native'},
+ 'add_global_link_arguments': {'language', 'native'},
'add_languages': {'required'},
- 'add_project_arguments': {'language'},
+ 'add_project_link_arguments': {'language', 'native'},
+ 'add_project_arguments': {'language', 'native'},
'add_test_setup': {'exe_wrapper', 'gdb', 'timeout_multiplier', 'env'},
'benchmark': {'args', 'env', 'should_fail', 'timeout', 'workdir', 'suite'},
'build_target': known_build_target_kwargs,
@@ -2279,21 +2279,19 @@ external dependencies (including libraries) must go to "dependencies".''')
return self.subprojects[dirname]
def get_option_internal(self, optname):
+ # Some base options are not defined in some environments, return the
+ # default value from compilers.base_options in that case.
+ for d in [self.coredata.base_options, compilers.base_options,
+ self.coredata.builtins, self.coredata.compiler_options]:
+ try:
+ return d[optname]
+ except KeyError:
+ pass
+
raw_optname = optname
- try:
- return self.coredata.base_options[optname]
- except KeyError:
- pass
- try:
- return self.coredata.builtins[optname]
- except KeyError:
- pass
- try:
- return self.coredata.compiler_options[optname]
- except KeyError:
- pass
- if not coredata.is_builtin_option(optname) and self.is_subproject():
+ if self.is_subproject():
optname = self.subproject + ':' + optname
+
try:
opt = self.coredata.user_options[optname]
if opt.yielding and ':' in optname and raw_optname in self.coredata.user_options:
@@ -2313,11 +2311,7 @@ external dependencies (including libraries) must go to "dependencies".''')
return opt
except KeyError:
pass
- # Some base options are not defined in some environments, return the default value.
- try:
- return compilers.base_options[optname]
- except KeyError:
- pass
+
raise InterpreterException('Tried to access unknown option "%s".' % optname)
@stringArgs
@@ -3653,25 +3647,45 @@ different subdirectory.
timeout_multiplier=timeout_multiplier,
env=env)
+ def get_argdict_on_crossness(self, native_dict, cross_dict, kwargs):
+ for_native = kwargs.get('native', not self.environment.is_cross_build())
+ if not isinstance(for_native, bool):
+ raise InterpreterException('Keyword native must be a boolean.')
+ if for_native:
+ return native_dict
+ else:
+ return cross_dict
+
@permittedKwargs(permitted_kwargs['add_global_arguments'])
@stringArgs
def func_add_global_arguments(self, node, args, kwargs):
- self.add_global_arguments(node, self.build.global_args, args, kwargs)
+ argdict = self.get_argdict_on_crossness(self.build.global_args,
+ self.build.cross_global_args,
+ kwargs)
+ self.add_global_arguments(node, argdict, args, kwargs)
@permittedKwargs(permitted_kwargs['add_global_link_arguments'])
@stringArgs
def func_add_global_link_arguments(self, node, args, kwargs):
- self.add_global_arguments(node, self.build.global_link_args, args, kwargs)
+ argdict = self.get_argdict_on_crossness(self.build.global_link_args,
+ self.build.cross_global_link_args,
+ kwargs)
+ self.add_global_arguments(node, argdict, args, kwargs)
@permittedKwargs(permitted_kwargs['add_project_arguments'])
@stringArgs
def func_add_project_arguments(self, node, args, kwargs):
- self.add_project_arguments(node, self.build.projects_args, args, kwargs)
+ argdict = self.get_argdict_on_crossness(self.build.projects_args,
+ self.build.cross_projects_args,
+ kwargs)
+ self.add_project_arguments(node, argdict, args, kwargs)
@permittedKwargs(permitted_kwargs['add_project_link_arguments'])
@stringArgs
def func_add_project_link_arguments(self, node, args, kwargs):
- self.add_project_arguments(node, self.build.projects_link_args, args, kwargs)
+ argdict = self.get_argdict_on_crossness(self.build.projects_link_args,
+ self.build.cross_projects_link_args, kwargs)
+ self.add_project_arguments(node, argdict, args, kwargs)
def add_global_arguments(self, node, argsdict, args, kwargs):
if self.is_subproject():
diff --git a/mesonbuild/mconf.py b/mesonbuild/mconf.py
index 513c238..2fd69b0 100644
--- a/mesonbuild/mconf.py
+++ b/mesonbuild/mconf.py
@@ -13,7 +13,6 @@
# limitations under the License.
import os
-import sys
import argparse
from . import (coredata, mesonlib, build)
@@ -172,7 +171,3 @@ def run(args):
print('Meson configurator encountered an error:')
raise e
return 0
-
-
-if __name__ == '__main__':
- sys.exit(run(sys.argv[1:]))
diff --git a/mesonbuild/mesonmain.py b/mesonbuild/mesonmain.py
index 68a2ddb..e8b7b30 100644
--- a/mesonbuild/mesonmain.py
+++ b/mesonbuild/mesonmain.py
@@ -36,7 +36,7 @@ def create_parser():
p.add_argument('-v', '--version', action='version',
version=coredata.version)
# See the mesonlib.WrapMode enum for documentation
- p.add_argument('--wrap-mode', default=WrapMode.default,
+ p.add_argument('--wrap-mode', default=None,
type=wrapmodetype, choices=WrapMode,
help='Special wrap mode to use')
p.add_argument('--profile-self', action='store_true', dest='profile',
@@ -71,18 +71,18 @@ class MesonApp:
if not os.path.exists(ndir2):
os.makedirs(ndir2)
if not stat.S_ISDIR(os.stat(ndir1).st_mode):
- raise RuntimeError('%s is not a directory' % dir1)
+ raise MesonException('%s is not a directory' % dir1)
if not stat.S_ISDIR(os.stat(ndir2).st_mode):
- raise RuntimeError('%s is not a directory' % dir2)
+ raise MesonException('%s is not a directory' % dir2)
if os.path.samefile(dir1, dir2):
- raise RuntimeError('Source and build directories must not be the same. Create a pristine build directory.')
+ raise MesonException('Source and build directories must not be the same. Create a pristine build directory.')
if self.has_build_file(ndir1):
if self.has_build_file(ndir2):
- raise RuntimeError('Both directories contain a build file %s.' % environment.build_filename)
+ raise MesonException('Both directories contain a build file %s.' % environment.build_filename)
return ndir1, ndir2
if self.has_build_file(ndir2):
return ndir2, ndir1
- raise RuntimeError('Neither directory contains a build file %s.' % environment.build_filename)
+ raise MesonException('Neither directory contains a build file %s.' % environment.build_filename)
def validate_dirs(self, dir1, dir2, handshake):
(src_dir, build_dir) = self.validate_core_dirs(dir1, dir2)
diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py
index 94bc00b..188459a 100644
--- a/mesonbuild/mintro.py
+++ b/mesonbuild/mintro.py
@@ -249,6 +249,3 @@ def run(args):
print('No command specified')
return 1
return 0
-
-if __name__ == '__main__':
- sys.exit(run(sys.argv[1:]))
diff --git a/mesonbuild/mlog.py b/mesonbuild/mlog.py
index 1654824..b8d3ccc 100644
--- a/mesonbuild/mlog.py
+++ b/mesonbuild/mlog.py
@@ -59,9 +59,12 @@ def set_timestamp_start(start):
def shutdown():
global log_file
if log_file is not None:
+ path = log_file.name
exception_around_goer = log_file
log_file = None
exception_around_goer.close()
+ return path
+ return None
class AnsiDecorator:
plain_code = "\033[0m"
diff --git a/mesonbuild/wrap/wraptool.py b/mesonbuild/wrap/wraptool.py
index 570e691..364452d 100644
--- a/mesonbuild/wrap/wraptool.py
+++ b/mesonbuild/wrap/wraptool.py
@@ -213,6 +213,4 @@ def run(args):
add_arguments(parser)
options = parser.parse_args(args)
options.wrap_func(options)
-
-if __name__ == '__main__':
- sys.exit(run(sys.argv[1:]))
+ return 0
diff --git a/run_tests.py b/run_tests.py
index 6e441d3..a5fd7a5 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -31,7 +31,32 @@ from mesonbuild import mesonlib
from mesonbuild import mesonmain
from mesonbuild import mtest
from mesonbuild import mlog
-from mesonbuild.environment import detect_ninja
+from mesonbuild.environment import Environment, detect_ninja
+
+
+# Fake classes and objects for mocking
+class FakeBuild:
+ def __init__(self, env):
+ self.environment = env
+
+class FakeCompilerOptions:
+ def __init__(self):
+ self.value = []
+
+def get_fake_options(prefix):
+ import argparse
+ opts = argparse.Namespace()
+ opts.cross_file = None
+ opts.wrap_mode = None
+ opts.prefix = prefix
+ opts.cmd_line_options = {}
+ return opts
+
+def get_fake_env(sdir, bdir, prefix):
+ env = Environment(sdir, bdir, get_fake_options(prefix))
+ env.coredata.compiler_options['c_args'] = FakeCompilerOptions()
+ return env
+
Backend = Enum('Backend', 'ninja vs xcode')
@@ -148,15 +173,6 @@ def ensure_backend_detects_changes(backend):
if backend is Backend.ninja:
time.sleep(1)
-def get_fake_options(prefix):
- import argparse
- opts = argparse.Namespace()
- opts.cross_file = None
- opts.wrap_mode = None
- opts.prefix = prefix
- opts.cmd_line_options = {}
- return opts
-
def run_mtest_inprocess(commandlist):
old_stdout = sys.stdout
sys.stdout = mystdout = StringIO()
diff --git a/run_unittests.py b/run_unittests.py
index 262bf7b..f4c50a5 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -41,24 +41,16 @@ from mesonbuild.mesonlib import (
windows_proof_rmtree, python_command, version_compare,
grab_leading_numbers, BuildDirLock
)
-from mesonbuild.environment import Environment, detect_ninja
+from mesonbuild.environment import detect_ninja
from mesonbuild.mesonlib import MesonException, EnvironmentException
from mesonbuild.dependencies import PkgConfigDependency, ExternalProgram
import mesonbuild.modules.pkgconfig
-from run_tests import exe_suffix, get_fake_options, get_meson_script
+from run_tests import exe_suffix, get_fake_env, get_meson_script
from run_tests import get_builddir_target_args, get_backend_commands, Backend
from run_tests import ensure_backend_detects_changes, run_configure_inprocess
from run_tests import run_mtest_inprocess
-
-# Fake classes for mocking
-class FakeBuild:
- def __init__(self, env):
- self.environment = env
-
-class FakeCompilerOptions:
- def __init__(self):
- self.value = []
+from run_tests import FakeBuild, FakeCompilerOptions
def get_dynamic_section_entry(fname, entry):
if is_cygwin() or is_osx():
@@ -563,7 +555,7 @@ class InternalTests(unittest.TestCase):
'windows-mingw': {'shared': ['lib{}.dll.a', 'lib{}.lib', 'lib{}.dll',
'{}.dll.a', '{}.lib', '{}.dll'],
'static': msvc_static}}
- env = Environment('', '', get_fake_options(''))
+ env = get_fake_env('', '', '')
cc = env.detect_c_compiler(False)
if is_osx():
self._test_all_naming(cc, env, patterns, 'darwin')
@@ -606,7 +598,7 @@ class InternalTests(unittest.TestCase):
'''
with tempfile.TemporaryDirectory() as tmpdir:
pkgbin = ExternalProgram('pkg-config', command=['pkg-config'], silent=True)
- env = Environment('', '', get_fake_options(''))
+ env = get_fake_env('', '', '')
compiler = env.detect_c_compiler(False)
env.coredata.compilers = {'c': compiler}
env.coredata.compiler_options['c_link_args'] = FakeCompilerOptions()
@@ -672,6 +664,8 @@ class DataTests(unittest.TestCase):
self.assertTrue(snippet_dir.is_dir())
for f in snippet_dir.glob('*'):
self.assertTrue(f.is_file())
+ if f.parts[-1].endswith('~'):
+ continue
if f.suffix == '.md':
with f.open() as snippet:
for line in snippet:
@@ -692,7 +686,7 @@ class DataTests(unittest.TestCase):
with open('docs/markdown/Builtin-options.md') as f:
md = f.read()
self.assertIsNotNone(md)
- env = Environment('', '', get_fake_options(''))
+ env = get_fake_env('', '', '')
# FIXME: Support other compilers
cc = env.detect_c_compiler(False)
cpp = env.detect_cpp_compiler(False)
@@ -738,7 +732,7 @@ class DataTests(unittest.TestCase):
Ensure that syntax highlighting files were updated for new functions in
the global namespace in build files.
'''
- env = Environment('', '', get_fake_options(''))
+ env = get_fake_env('', '', '')
interp = Interpreter(FakeBuild(env), mock=True)
with open('data/syntax-highlighting/vim/syntax/meson.vim') as f:
res = re.search(r'syn keyword mesonBuiltin(\s+\\\s\w+)+', f.read(), re.MULTILINE)
@@ -1172,7 +1166,7 @@ class AllPlatformTests(BasePlatformTests):
https://github.com/mesonbuild/meson/issues/1355
'''
testdir = os.path.join(self.common_test_dir, '3 static')
- env = Environment(testdir, self.builddir, get_fake_options(self.prefix))
+ env = get_fake_env(testdir, self.builddir, self.prefix)
cc = env.detect_c_compiler(False)
static_linker = env.detect_static_linker(cc)
if is_windows():
@@ -1459,7 +1453,7 @@ class AllPlatformTests(BasePlatformTests):
if not is_windows():
langs += [('objc', 'OBJC'), ('objcpp', 'OBJCXX')]
testdir = os.path.join(self.unit_test_dir, '5 compiler detection')
- env = Environment(testdir, self.builddir, get_fake_options(self.prefix))
+ env = get_fake_env(testdir, self.builddir, self.prefix)
for lang, evar in langs:
# Detect with evar and do sanity checks on that
if evar in os.environ:
@@ -1561,7 +1555,7 @@ class AllPlatformTests(BasePlatformTests):
def test_always_prefer_c_compiler_for_asm(self):
testdir = os.path.join(self.common_test_dir, '138 c cpp and asm')
# Skip if building with MSVC
- env = Environment(testdir, self.builddir, get_fake_options(self.prefix))
+ env = get_fake_env(testdir, self.builddir, self.prefix)
if env.detect_c_compiler(False).get_id() == 'msvc':
raise unittest.SkipTest('MSVC can\'t compile assembly')
self.init(testdir)
@@ -1819,7 +1813,7 @@ int main(int argc, char **argv) {
self.assertPathExists(os.path.join(testdir, i))
def detect_prebuild_env(self):
- env = Environment('', self.builddir, get_fake_options(self.prefix))
+ env = get_fake_env('', self.builddir, self.prefix)
cc = env.detect_c_compiler(False)
stlinker = env.detect_static_linker(cc)
if mesonbuild.mesonlib.is_windows():
@@ -1985,7 +1979,7 @@ int main(int argc, char **argv) {
'--libdir=' + libdir])
# Find foo dependency
os.environ['PKG_CONFIG_LIBDIR'] = self.privatedir
- env = Environment(testdir, self.builddir, get_fake_options(self.prefix))
+ env = get_fake_env(testdir, self.builddir, self.prefix)
kwargs = {'required': True, 'silent': True}
foo_dep = PkgConfigDependency('libfoo', env, kwargs)
# Ensure link_args are properly quoted
@@ -2292,7 +2286,7 @@ recommended as it is not supported on some platforms''')
testdirbase = os.path.join(self.unit_test_dir, '29 guessed linker dependencies')
testdirlib = os.path.join(testdirbase, 'lib')
extra_args = None
- env = Environment(testdirlib, self.builddir, get_fake_options(self.prefix))
+ env = get_fake_env(testdirlib, self.builddir, self.prefix)
if env.detect_c_compiler(False).get_id() != 'msvc':
# static libraries are not linkable with -l with msvc because meson installs them
# as .a files which unix_args_to_native will not know as it expects libraries to use
@@ -2746,7 +2740,7 @@ class FailureTests(BasePlatformTests):
'''
Test that when we can't detect objc or objcpp, we fail gracefully.
'''
- env = Environment('', self.builddir, get_fake_options(self.prefix))
+ env = get_fake_env('', self.builddir, self.prefix)
try:
env.detect_objc_compiler(False)
env.detect_objcpp_compiler(False)
@@ -2883,7 +2877,7 @@ class WindowsTests(BasePlatformTests):
ExternalLibraryHolder from build files.
'''
testdir = os.path.join(self.platform_test_dir, '1 basic')
- env = Environment(testdir, self.builddir, get_fake_options(self.prefix))
+ env = get_fake_env(testdir, self.builddir, self.prefix)
cc = env.detect_c_compiler(False)
if cc.id != 'msvc':
raise unittest.SkipTest('Not using MSVC')
@@ -2896,7 +2890,7 @@ class WindowsTests(BasePlatformTests):
testdir = os.path.join(self.platform_test_dir, '5 resources')
# resource compiler depfile generation is not yet implemented for msvc
- env = Environment(testdir, self.builddir, get_fake_options(self.prefix))
+ env = get_fake_env(testdir, self.builddir, self.prefix)
depfile_works = env.detect_c_compiler(False).get_id() != 'msvc'
self.init(testdir)
@@ -2985,7 +2979,7 @@ class LinuxlikeTests(BasePlatformTests):
'''
testdir = os.path.join(self.common_test_dir, '48 pkgconfig-gen')
self.init(testdir)
- env = Environment(testdir, self.builddir, get_fake_options(self.prefix))
+ env = get_fake_env(testdir, self.builddir, self.prefix)
kwargs = {'required': True, 'silent': True}
os.environ['PKG_CONFIG_LIBDIR'] = self.privatedir
foo_dep = PkgConfigDependency('libfoo', env, kwargs)
@@ -3241,7 +3235,7 @@ class LinuxlikeTests(BasePlatformTests):
an ordinary test because it requires passing options to meson.
'''
testdir = os.path.join(self.common_test_dir, '1 trivial')
- env = Environment(testdir, self.builddir, get_fake_options(self.prefix))
+ env = get_fake_env(testdir, self.builddir, self.prefix)
cc = env.detect_c_compiler(False)
self._test_stds_impl(testdir, cc, 'c')
@@ -3251,7 +3245,7 @@ class LinuxlikeTests(BasePlatformTests):
be an ordinary test because it requires passing options to meson.
'''
testdir = os.path.join(self.common_test_dir, '2 cpp')
- env = Environment(testdir, self.builddir, get_fake_options(self.prefix))
+ env = get_fake_env(testdir, self.builddir, self.prefix)
cpp = env.detect_cpp_compiler(False)
self._test_stds_impl(testdir, cpp, 'cpp')
@@ -3796,8 +3790,6 @@ endian = 'little'
The system library is found with cc.find_library() and pkg-config deps.
'''
- if not is_osx():
- raise unittest.SkipTest('workflow currently only works on macOS')
oldprefix = self.prefix
# Install external library so we can find it
testdir = os.path.join(self.unit_test_dir, '39 external, internal library rpath', 'external library')
@@ -3820,6 +3812,9 @@ endian = 'little'
self.build()
# test uninstalled
self.run_tests()
+ if not is_osx():
+ # Rest of the workflow only works on macOS
+ return
# test running after installation
self.install(use_destdir=False)
prog = os.path.join(self.installdir, 'bin', 'prog')
diff --git a/test cases/common/21 global arg/meson.build b/test cases/common/21 global arg/meson.build
index d7fd428..699dae6 100644
--- a/test cases/common/21 global arg/meson.build
+++ b/test cases/common/21 global arg/meson.build
@@ -3,9 +3,18 @@ project('global arg test', 'cpp', 'c')
add_global_arguments('-DMYTHING', language : 'c')
add_global_arguments('-DMYCPPTHING', language : 'cpp')
+add_global_arguments('-DGLOBAL_NATIVE', language : 'c', native : true)
+add_global_arguments('-DGLOBAL_CROSS', language : 'c', native : false)
+
+if meson.is_cross_build()
+ c_args = ['-DARG_CROSS']
+else
+ c_args = ['-DARG_NATIVE']
+endif
+
add_global_arguments('-DMYCANDCPPTHING', language: ['c', 'cpp'])
-exe1 = executable('prog', 'prog.c')
+exe1 = executable('prog', 'prog.c', c_args : c_args)
exe2 = executable('prog2', 'prog.cc')
test('prog1', exe1)
diff --git a/test cases/common/21 global arg/prog.c b/test cases/common/21 global arg/prog.c
index ace5a0a..fb014c7 100644
--- a/test cases/common/21 global arg/prog.c
+++ b/test cases/common/21 global arg/prog.c
@@ -10,6 +10,42 @@
#error "Global argument not set"
#endif
+#ifdef GLOBAL_NATIVE
+ #ifndef ARG_NATIVE
+ #error "Global is native but arg_native is not set."
+ #endif
+
+ #ifdef GLOBAL_CROSS
+ #error "Both global native and global cross set."
+ #endif
+#else
+ #ifndef GLOBAL_CROSS
+ #error "Neither global_cross nor glogal_native is set."
+ #endif
+
+ #ifndef ARG_CROSS
+ #error "Global is cross but arg_cross is not set."
+ #endif
+
+ #ifdef ARG_NATIVE
+ #error "Global is cross but arg_native is set."
+ #endif
+#endif
+
+#ifdef GLOBAL_CROSS
+ #ifndef ARG_CROSS
+ #error "Global is cross but arg_cross is not set."
+ #endif
+#else
+ #ifdef ARG_CROSS
+ #error "Global is cross but arg_native is set."
+ #endif
+
+ #ifdef ARG_CROSS
+ #error "Global is native but arg cross is set."
+ #endif
+#endif
+
int main(int argc, char **argv) {
return 0;
}
diff --git a/test cases/unit/39 external, internal library rpath/built library/meson.build b/test cases/unit/39 external, internal library rpath/built library/meson.build
index 2b422f4..f633996 100644
--- a/test cases/unit/39 external, internal library rpath/built library/meson.build
+++ b/test cases/unit/39 external, internal library rpath/built library/meson.build
@@ -1,12 +1,21 @@
project('built library', 'c')
cc = meson.get_compiler('c')
+
+if host_machine.system() != 'cygwin'
+ # bar_in_system has undefined symbols, but still must be found
+ bar_system_dep = cc.find_library('bar_in_system')
+endif
+
foo_system_dep = cc.find_library('foo_in_system')
+
faa_pkg_dep = dependency('faa_pkg')
l = shared_library('bar_built', 'bar.c',
install: true,
dependencies : [foo_system_dep, faa_pkg_dep])
-e = executable('prog', 'prog.c', link_with: l, install: true)
-test('testprog', e)
+if host_machine.system() == 'darwin'
+ e = executable('prog', 'prog.c', link_with: l, install: true)
+ test('testprog', e)
+endif
diff --git a/test cases/unit/39 external, internal library rpath/external library/bar.c b/test cases/unit/39 external, internal library rpath/external library/bar.c
new file mode 100644
index 0000000..c6f42d6
--- /dev/null
+++ b/test cases/unit/39 external, internal library rpath/external library/bar.c
@@ -0,0 +1,6 @@
+int some_undefined_func (void);
+
+int bar_system_value (void)
+{
+ return some_undefined_func ();
+}
diff --git a/test cases/unit/39 external, internal library rpath/external library/meson.build b/test cases/unit/39 external, internal library rpath/external library/meson.build
index 6dcc97e..3c311f5 100644
--- a/test cases/unit/39 external, internal library rpath/external library/meson.build
+++ b/test cases/unit/39 external, internal library rpath/external library/meson.build
@@ -1,9 +1,22 @@
-project('system library', 'c')
+project('system library', 'c', default_options : ['b_lundef=false'])
shared_library('foo_in_system', 'foo.c', install : true)
l = shared_library('faa_pkg', 'faa.c', install: true)
+if host_machine.system() == 'darwin'
+ frameworks = ['-framework', 'CoreFoundation', '-framework', 'CoreMedia']
+ allow_undef_args = ['-Wl,-undefined,dynamic_lookup']
+else
+ frameworks = []
+ allow_undef_args = []
+endif
+
pkg = import('pkgconfig')
pkg.generate(name: 'faa_pkg',
- libraries: [l, '-framework', 'CoreFoundation', '-framework', 'CoreMedia'],
+ libraries: [l] + frameworks,
description: 'FAA, a pkg-config test library')
+
+# cygwin DLLs can't have undefined symbols
+if host_machine.system() != 'cygwin'
+ shared_library('bar_in_system', 'bar.c', install : true, link_args : allow_undef_args)
+endif