Added "native" kwarg to add_XXX_args. Closes #3669.

pull/3998/head
Jussi Pakkanen 7 years ago
parent 6cd71a8033
commit 54aed1a92c
  1. 28
      docs/markdown/Reference-manual.md
  2. 34
      docs/markdown/snippets/native_args.md
  3. 4
      mesonbuild/backend/backends.py
  4. 20
      mesonbuild/backend/ninjabackend.py
  5. 4
      mesonbuild/backend/vs2010backend.py
  6. 25
      mesonbuild/build.py
  7. 36
      mesonbuild/interpreter.py
  8. 2
      run_unittests.py
  9. 11
      test cases/common/21 global arg/meson.build
  10. 36
      test cases/common/21 global arg/prog.c

@ -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()

@ -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.

@ -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.

@ -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.

@ -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.

@ -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 []

@ -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():

@ -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:

@ -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)

@ -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;
}

Loading…
Cancel
Save