Skip to content

Commit

Permalink
interpreter: add <lang>_(static|shared)_args
Browse files Browse the repository at this point in the history
Which allow passing arguments specifically to the static or shared
libraries (but not shared_modules).

For design, this is all handled in the interpreter, by the build layer
the arguments are combined into the existing fields. This limits changes
required in the mid and backend layers
  • Loading branch information
dcbaker committed Jul 13, 2023
1 parent 5f0f707 commit cfdbb44
Show file tree
Hide file tree
Showing 11 changed files with 79 additions and 11 deletions.
5 changes: 5 additions & 0 deletions docs/markdown/snippets/shared_static_only_args.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## `<lang>_(shared|static)_args` for both_library

We now allow passing arguments like `c_static_args` and `c_shared_args`. This
allows a `both_library` to have arguments specific to either the shared or
static library, as well as common arguments to both.
5 changes: 5 additions & 0 deletions docs/yaml/functions/shared_library.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,8 @@ kwargs:
description: |
Specify a Microsoft module definition file for controlling symbol exports,
etc., on platforms where that is possible (e.g. Windows).
<lang>_shared_args:
type: str | file
description:
Arguments that are only passed to a shared library
5 changes: 5 additions & 0 deletions docs/yaml/functions/static_library.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,8 @@ kwargs:
If `true` the object files in the target will be prelinked,
meaning that it will contain only one prelinked
object file rather than the individual object files.
<lang>_static_args:
type: str | file
description:
Arguments that are only passed to a static library
5 changes: 3 additions & 2 deletions mesonbuild/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@
cs_kwargs)

known_exe_kwargs = known_build_target_kwargs | {'implib', 'export_dynamic', 'pie'}
known_shlib_kwargs = known_build_target_kwargs | {'version', 'soversion', 'vs_module_defs', 'darwin_versions'}
known_shlib_kwargs = known_build_target_kwargs | {f'{l}_shared_args' for l in all_languages} | {'version', 'soversion', 'vs_module_defs', 'darwin_versions'}
known_shmod_kwargs = known_build_target_kwargs | {'vs_module_defs'}
known_stlib_kwargs = known_build_target_kwargs | {'pic', 'prelink'}
known_stlib_kwargs = known_build_target_kwargs | {f'{l}_static_args' for l in all_languages} | {'pic', 'prelink'}
known_jar_kwargs = known_exe_kwargs | {'main_class', 'java_resources'}

def _process_install_tag(install_tag: T.Optional[T.List[T.Optional[str]]],
Expand All @@ -141,6 +141,7 @@ def get_target_macos_dylib_install_name(ld) -> str:
class InvalidArguments(MesonException):
pass


@dataclass(eq=False)
class DependencyOverride(HoldableObject):
dep: dependencies.Dependency
Expand Down
20 changes: 14 additions & 6 deletions mesonbuild/interpreter/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@
OVERRIDE_OPTIONS_KW,
PRESERVE_PATH_KW,
REQUIRED_KW,
SHARED_LIB_LANGUAGE_KWS,
SOURCES_KW,
STATIC_LIB_LANGUAGE_KWS,
VARIABLES_KW,
TEST_KWS,
NoneType,
Expand Down Expand Up @@ -1815,15 +1817,15 @@ def func_executable(self, node: mparser.BaseNode,

@permittedKwargs(build.known_stlib_kwargs)
@typed_pos_args('static_library', str, varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList, build.StructuredSources, build.ExtractedObjects, build.BuildTarget))
@typed_kwargs('static_library', *LANGUAGE_KWS, OVERRIDE_OPTIONS_KW, allow_unknown=True)
@typed_kwargs('static_library', *LANGUAGE_KWS, *STATIC_LIB_LANGUAGE_KWS, OVERRIDE_OPTIONS_KW, allow_unknown=True)
def func_static_lib(self, node: mparser.BaseNode,
args: T.Tuple[str, T.List[BuildTargetSource]],
kwargs) -> build.StaticLibrary:
return self.build_target(node, args, kwargs, build.StaticLibrary)

@permittedKwargs(build.known_shlib_kwargs)
@typed_pos_args('shared_library', str, varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList, build.StructuredSources, build.ExtractedObjects, build.BuildTarget))
@typed_kwargs('shared_library', *LANGUAGE_KWS, OVERRIDE_OPTIONS_KW, allow_unknown=True)
@typed_kwargs('shared_library', *LANGUAGE_KWS, *SHARED_LIB_LANGUAGE_KWS, OVERRIDE_OPTIONS_KW, allow_unknown=True)
def func_shared_lib(self, node: mparser.BaseNode,
args: T.Tuple[str, T.List[BuildTargetSource]],
kwargs) -> build.SharedLibrary:
Expand All @@ -1833,7 +1835,7 @@ def func_shared_lib(self, node: mparser.BaseNode,

@permittedKwargs(known_library_kwargs)
@typed_pos_args('both_libraries', str, varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList, build.StructuredSources, build.ExtractedObjects, build.BuildTarget))
@typed_kwargs('both_libraries', *LANGUAGE_KWS, OVERRIDE_OPTIONS_KW, allow_unknown=True)
@typed_kwargs('both_libraries', *LANGUAGE_KWS, *STATIC_LIB_LANGUAGE_KWS, *SHARED_LIB_LANGUAGE_KWS, OVERRIDE_OPTIONS_KW, allow_unknown=True)
def func_both_lib(self, node: mparser.BaseNode,
args: T.Tuple[str, T.List[BuildTargetSource]],
kwargs) -> build.BothLibraries:
Expand All @@ -1842,15 +1844,15 @@ def func_both_lib(self, node: mparser.BaseNode,
@FeatureNew('shared_module', '0.37.0')
@permittedKwargs(build.known_shmod_kwargs)
@typed_pos_args('shared_module', str, varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList, build.StructuredSources, build.ExtractedObjects, build.BuildTarget))
@typed_kwargs('shared_module', *LANGUAGE_KWS, OVERRIDE_OPTIONS_KW, allow_unknown=True)
@typed_kwargs('shared_module', *LANGUAGE_KWS, *SHARED_LIB_LANGUAGE_KWS, OVERRIDE_OPTIONS_KW, allow_unknown=True)
def func_shared_module(self, node: mparser.BaseNode,
args: T.Tuple[str, T.List[BuildTargetSource]],
kwargs) -> build.SharedModule:
return self.build_target(node, args, kwargs, build.SharedModule)

@permittedKwargs(known_library_kwargs)
@typed_pos_args('library', str, varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList, build.StructuredSources, build.ExtractedObjects, build.BuildTarget))
@typed_kwargs('library', *LANGUAGE_KWS, OVERRIDE_OPTIONS_KW, allow_unknown=True)
@typed_kwargs('library', *LANGUAGE_KWS, *STATIC_LIB_LANGUAGE_KWS, *SHARED_LIB_LANGUAGE_KWS, OVERRIDE_OPTIONS_KW, allow_unknown=True)
def func_library(self, node: mparser.BaseNode,
args: T.Tuple[str, T.List[BuildTargetSource]],
kwargs) -> build.Executable:
Expand All @@ -1867,7 +1869,7 @@ def func_jar(self, node: mparser.BaseNode,
@FeatureNewKwargs('build_target', '0.40.0', ['link_whole', 'override_options'])
@permittedKwargs(known_build_target_kwargs)
@typed_pos_args('build_target', str, varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList, build.StructuredSources, build.ExtractedObjects, build.BuildTarget))
@typed_kwargs('build_target', *LANGUAGE_KWS, OVERRIDE_OPTIONS_KW, allow_unknown=True)
@typed_kwargs('build_target', *LANGUAGE_KWS, *STATIC_LIB_LANGUAGE_KWS, *SHARED_LIB_LANGUAGE_KWS, OVERRIDE_OPTIONS_KW, allow_unknown=True)
def func_build_target(self, node: mparser.BaseNode,
args: T.Tuple[str, T.List[BuildTargetSource]],
kwargs) -> T.Union[build.Executable, build.StaticLibrary, build.SharedLibrary,
Expand Down Expand Up @@ -3263,6 +3265,12 @@ def build_target_decorator_caller(self, node, args, kwargs):
raise RuntimeError('Unreachable code')
self.kwarg_strings_to_includedirs(kwargs)
self.__extract_language_args(kwargs)
if targetclass is build.StaticLibrary:
for lang in compilers.all_languages:
kwargs['language_args'][lang].extend(kwargs[f'{lang}_static_args'])
elif targetclass is build.SharedLibrary:
for lang in compilers.all_languages:
kwargs['language_args'][lang].extend(kwargs[f'{lang}_shared_args'])

# Filter out kwargs from other target types. For example 'soversion'
# passed to library() when default_library == 'static'.
Expand Down
3 changes: 3 additions & 0 deletions mesonbuild/interpreter/type_checking.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,3 +486,6 @@ def link_whole_validator(values: T.List[T.Union[StaticLibrary, CustomTarget, Cus
]
LANGUAGE_KWS.append(KwargInfo(
'rust_args', ContainerTypeInfo(list, str), listify=True, default=[], since='0.41.0'))

STATIC_LIB_LANGUAGE_KWS = [l.evolve(name=f'{l.name.split("_", 1)[0]}_static_args', since='1.3.0') for l in LANGUAGE_KWS]
SHARED_LIB_LANGUAGE_KWS = [l.evolve(name=f'{l.name.split("_", 1)[0]}_shared_args', since='1.3.0') for l in LANGUAGE_KWS]
11 changes: 11 additions & 0 deletions test cases/common/3 static/lib3.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
int func3(const int x) {
return x + 1;
}

#ifndef WORK
# error "did not get static only C args"
#endif

#ifdef BREAK
# error "got shared only C args, but shouldn't have"
#endif
6 changes: 5 additions & 1 deletion test cases/common/3 static/meson.build
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
project('static library test', 'c')
project('static library test', 'c', default_options : ['default_library=static'])

lib = static_library('mylib', get_option('source'),
link_args : '-THISMUSTNOBEUSED') # Static linker needs to ignore all link args.
Expand All @@ -12,3 +12,7 @@ endif
assert(has_not_changed, 'Static library has changed.')

assert(not is_disabler(lib), 'Static library is a disabler.')

library('lib2', 'lib3.c', c_static_args : ['-DWORK'], c_shared_args : ['-DBREAK'])
static_library('lib3', 'lib3.c', c_static_args : ['-DWORK'])
build_target('lib4', 'lib3.c', c_static_args : ['-DWORK'], target_type : 'static_library')
22 changes: 22 additions & 0 deletions test cases/common/4 shared/libfile2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#if defined _WIN32 || defined __CYGWIN__
#define DLL_PUBLIC __declspec(dllexport)
#else
#if defined __GNUC__
#define DLL_PUBLIC __attribute__ ((visibility("default")))
#else
#pragma message ("Compiler does not support symbol visibility.")
#define DLL_PUBLIC
#endif
#endif

#ifndef WORK
# error "Did not get shared only arguments"
#endif

#ifdef BREAK
# error "got static only C args, but shouldn't have"
#endif

int DLL_PUBLIC libfunc(void) {
return 3;
}
6 changes: 5 additions & 1 deletion test cases/common/4 shared/meson.build
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
project('shared library test', 'c')
project('shared library test', 'c', default_options : ['default_library=shared'])
lib = shared_library('mylib', 'libfile.c')
build_target('mylib2', 'libfile.c', target_type: 'shared_library')

Expand All @@ -11,3 +11,7 @@ endif
assert(has_not_changed, 'Shared library has changed.')

assert(not is_disabler(lib), 'Shared library is a disabler.')

shared_library('mylib3', 'libfile2.c', c_shared_args : ['-DWORK'])
build_target('mylib4', 'libfile2.c', target_type: 'shared_library', c_shared_args : ['-DWORK'], c_static_args : ['-DBREAK'])
library('mylib5', 'libfile2.c', c_shared_args : ['-DWORK'])
2 changes: 1 addition & 1 deletion unittests/allplatformstests.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ def test_static_library_overwrite(self):
self.init(testdir)
# Get name of static library
targets = self.introspect('--targets')
self.assertEqual(len(targets), 1)
self.assertTrue(len(targets) >= 1)
libname = targets[0]['filename'][0]
# Build and get contents of static library
self.build()
Expand Down

0 comments on commit cfdbb44

Please sign in to comment.