Skip to content

Commit

Permalink
Added "native" kwarg to add_XXX_args. Closes #3669.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpakkane committed Jul 22, 2018
1 parent f67630d commit a52bd24
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 36 deletions.
26 changes: 17 additions & 9 deletions docs/markdown/Reference-manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,20 @@ 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 omitted, the flags
are added to native targets if compiling natively and cross targets
if 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
Expand Down Expand Up @@ -60,8 +67,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()

Expand Down
34 changes: 34 additions & 0 deletions docs/markdown/snippets/native_args.md
Original file line number Diff line number Diff line change
@@ -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 yodo 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 cross 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.
4 changes: 2 additions & 2 deletions mesonbuild/backend/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -520,10 +520,10 @@ def generate_basic_compiler_args(self, target, compiler, no_warn_args=False):
# Add buildtype args: optimization level, debugging, etc.
commands += compiler.get_buildtype_args(self.get_option_for_target('buildtype', 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.
Expand Down
12 changes: 6 additions & 6 deletions mesonbuild/backend/ninjabackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -1066,8 +1066,8 @@ def generate_cs_target(self, target, outfile):

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)
Expand All @@ -1080,8 +1080,8 @@ def generate_single_java_compile(self, src, target, compiler, outfile):
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()
Expand Down Expand Up @@ -2601,10 +2601,10 @@ def generate_link(self, target, outfile, outname, obj_list, linker, extra_args=[

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.
Expand Down
4 changes: 2 additions & 2 deletions mesonbuild/backend/vs2010backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -963,10 +963,10 @@ def gen_vcxproj(self, target, ofname, guid):
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.
Expand Down
25 changes: 17 additions & 8 deletions mesonbuild/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ def __init__(self, environment):
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 = []
Expand Down Expand Up @@ -167,20 +171,25 @@ def get_data(self):
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 []

Expand Down
36 changes: 28 additions & 8 deletions mesonbuild/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -1803,11 +1803,11 @@ def get_cross_property_method(self, args, 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,
Expand Down Expand Up @@ -3624,25 +3624,45 @@ def func_add_test_setup(self, node, args, kwargs):
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():
Expand Down
2 changes: 2 additions & 0 deletions run_unittests.py
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,8 @@ def test_snippets(self):
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:
Expand Down
11 changes: 10 additions & 1 deletion test cases/common/23 global arg/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
23 changes: 23 additions & 0 deletions test cases/common/23 global arg/prog.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,29 @@
#error "Global argument not set"
#endif

#ifdef GLOBAL_NATIVE
#ifndef ARG_NATIVE
#error "Global is native but arg_native is not set."
#endif
#else
#ifndef GLOBAL_CROSS
#error "Neither global_cross nor glogal_native is set."
#endif
#ifdef ARG_CROSS
#error "Global is native but arg_cross 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
#endif

int main(int argc, char **argv) {
return 0;
}

0 comments on commit a52bd24

Please sign in to comment.