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.py4
-rw-r--r--mesonbuild/backend/ninjabackend.py20
-rw-r--r--mesonbuild/backend/vs2010backend.py4
-rw-r--r--mesonbuild/build.py25
-rw-r--r--mesonbuild/interpreter.py36
-rwxr-xr-xrun_unittests.py2
-rw-r--r--test cases/common/21 global arg/meson.build11
-rw-r--r--test cases/common/21 global arg/prog.c36
10 files changed, 160 insertions, 40 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 df72eff..bdc3fad 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -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.
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 824145a..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)
@@ -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/interpreter.py b/mesonbuild/interpreter.py
index 707cf9e..0b4cbce 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,
@@ -3653,25 +3653,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/run_unittests.py b/run_unittests.py
index 513a11f..f4c50a5 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -664,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:
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;
}