Skip to content

Commit

Permalink
Allow passing dict to <lang>_args kwargs
Browse files Browse the repository at this point in the history
The dict must map a target type to a list of compiler args. This makes
possible to pass different c_args to static and shared libraries when
using both_libraries(). In that case sources will be compiled twice.

Closes #3304.
  • Loading branch information
xclaesse committed Sep 11, 2018
1 parent 6f05618 commit 6231ee7
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 5 deletions.
27 changes: 25 additions & 2 deletions mesonbuild/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -999,10 +999,28 @@ def add_include_dirs(self, args):
ids.append(a)
self.include_dirs += ids

def add_compiler_args(self, language, args):
def validate_target_dict(self, d):
known_build_targets = ['static_library', 'shared_library',
'shared_module', 'executable', 'jar']
for k in d.keys():
if k not in known_build_targets:
raise MesonException('Dictionary keys must be in ' + str(known_build_targets));

def validate_compiler_args(self, args):
result = []
for a in args:
if not isinstance(a, (str, File)):
if isinstance(a, dict):
self.validate_target_dict(a)
l = extract_as_list(a, self.target_type)
result += self.validate_compiler_args(l)
elif isinstance(a, (str, File)):
result.append(a)
else:
raise InvalidArguments('A non-string passed to compiler args.')
return result

def add_compiler_args(self, language, args):
args = self.validate_compiler_args(args)
if language in self.extra_args:
self.extra_args[language] += args
else:
Expand Down Expand Up @@ -1262,6 +1280,7 @@ def get_extra_args(self):

class Executable(BuildTarget):
known_kwargs = known_exe_kwargs
target_type = 'executable'

def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs)
Expand Down Expand Up @@ -1344,6 +1363,7 @@ def is_linkable_target(self):

class StaticLibrary(BuildTarget):
known_kwargs = known_stlib_kwargs
target_type = 'static_library'

def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
if 'pic' not in kwargs and 'b_staticpic' in environment.coredata.base_options:
Expand Down Expand Up @@ -1397,6 +1417,7 @@ def is_linkable_target(self):

class SharedLibrary(BuildTarget):
known_kwargs = known_shlib_kwargs
target_type = 'shared_library'

def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
self.soversion = None
Expand Down Expand Up @@ -1689,6 +1710,7 @@ def is_linkable_target(self):
# into something else.
class SharedModule(SharedLibrary):
known_kwargs = known_shmod_kwargs
target_type = 'shared_module'

def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
if 'version' in kwargs:
Expand Down Expand Up @@ -1987,6 +2009,7 @@ def type_suffix(self):

class Jar(BuildTarget):
known_kwargs = known_jar_kwargs
target_type = 'jar'

def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs)
Expand Down
13 changes: 12 additions & 1 deletion mesonbuild/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3950,7 +3950,18 @@ def build_both_libraries(self, node, args, kwargs):
elif 'b_staticpic' in self.environment.coredata.base_options:
pic = self.environment.coredata.base_options['b_staticpic'].value

if pic:
# Check if compiler args are the same for both libraries
def has_different_args():
for lang in shared_holder.held_object.compilers.keys():
args = extract_as_list(kwargs, lang + '_args')
for a in args:
if not isinstance(a, dict):
continue
if 'static_library' in a or 'shared_library' in a:
return True
return False

if pic and not has_different_args():
# Exclude sources from args and kwargs to avoid building them twice
static_args = [args[0]]
static_kwargs = kwargs.copy()
Expand Down
4 changes: 4 additions & 0 deletions test cases/common/184 bothlibraries/libfile.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#include "mylib.h"

#ifdef STATIC_COMPILATION
DO_EXPORT int retval = 42;
#else
DO_EXPORT int retval = 43;
#endif

DO_EXPORT int func() {
return retval;
Expand Down
11 changes: 9 additions & 2 deletions test cases/common/184 bothlibraries/main.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
#include <stdlib.h>
#include "mylib.h"

DO_IMPORT int func();
DO_IMPORT int retval;

int main(int argc, char **arg) {
return func() == retval ? 0 : 1;
int main(int argc, char *argv[]) {
if (func() != retval)
return 1;

if (argc > 1 && atoi(argv[1]) != retval)
return 1;

return 0;
}
14 changes: 14 additions & 0 deletions test cases/common/184 bothlibraries/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,17 @@ exe_both = executable('prog-both', 'main.c', link_with : both_libs)
test('runtest-shared', exe_shared)
test('runtest-static', exe_static)
test('runtest-both', exe_both)

cargs = {
'static_library' : ['-DSTATIC_COMPILATION'],
'executable' : ['-DSTATIC_COMPILATION'],
}
both_libs = both_libraries('mylib-diffargs', 'libfile.c', c_args : cargs)
exe_shared = executable('prog-shared-diffargs', 'main.c',
link_with : both_libs.get_shared_lib())
exe_static = executable('prog-static-diffargs', 'main.c',
c_args : cargs,
link_with : both_libs.get_static_lib())

test('runtest-shared-diffargs', exe_shared, args : '43')
test('runtest-static-diffargs', exe_static, args : '42')

0 comments on commit 6231ee7

Please sign in to comment.