diff options
| author | Dylan Baker <dylan@pnwbakers.com> | 2023-07-13 10:26:14 -0700 |
|---|---|---|
| committer | Eli Schwartz <eschwartz93@gmail.com> | 2023-10-09 17:33:48 -0400 |
| commit | 013536fcb45dc40c4f592f5c5821ee6d38d331ed (patch) | |
| tree | ee7cddf43778f63a5f102de1225ce62e1ff5f419 | |
| parent | e24f43051255d3978002f39d08149c3088cb67f9 (diff) | |
| download | meson-013536fcb45dc40c4f592f5c5821ee6d38d331ed.tar.gz | |
interpreter: add <lang>_(static|shared)_args
Which allow passing arguments specifically to the static or shared
libraries.
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
| -rw-r--r-- | docs/markdown/snippets/shared_static_only_args.md | 9 | ||||
| -rw-r--r-- | docs/yaml/functions/library.yaml | 34 | ||||
| -rw-r--r-- | mesonbuild/interpreter/interpreter.py | 17 | ||||
| -rw-r--r-- | mesonbuild/interpreter/kwargs.py | 29 | ||||
| -rw-r--r-- | mesonbuild/interpreter/type_checking.py | 11 | ||||
| -rw-r--r-- | test cases/common/178 bothlibraries/meson.build | 10 | ||||
| -rw-r--r-- | test cases/common/3 static/lib3.c | 11 | ||||
| -rw-r--r-- | test cases/common/3 static/meson.build | 7 | ||||
| -rw-r--r-- | test cases/common/4 shared/libfile2.c | 22 | ||||
| -rw-r--r-- | test cases/common/4 shared/meson.build | 7 | ||||
| -rw-r--r-- | unittests/allplatformstests.py | 2 |
11 files changed, 153 insertions, 6 deletions
diff --git a/docs/markdown/snippets/shared_static_only_args.md b/docs/markdown/snippets/shared_static_only_args.md new file mode 100644 index 000000000..0963c714b --- /dev/null +++ b/docs/markdown/snippets/shared_static_only_args.md @@ -0,0 +1,9 @@ +## `<lang>_(shared|static)_args` for both_library, library, and build_target + +We now allow passing arguments like `c_static_args` and `c_shared_args`. This +allows a [[both_libraries]] to have arguments specific to either the shared or +static library, as well as common arguments to both. + +There is a drawback to this, since Meson now cannot re-use object files between +the static and shared targets. This could lead to much higher compilation time +when using a [[both_libraries]] if there are many sources. diff --git a/docs/yaml/functions/library.yaml b/docs/yaml/functions/library.yaml index f9e336b9b..1d406f13c 100644 --- a/docs/yaml/functions/library.yaml +++ b/docs/yaml/functions/library.yaml @@ -16,6 +16,12 @@ description: | The keyword arguments for this are the same as for [[build_target]] +warnings: + - using <lang>_shared_args and/or <lang>_static_args may lead to much higher + compilation times with both_library, as object files cannot be shared between + the static and shared targets. It is guaranteed to not duplicate the build if + these arguments are empty arrays + posargs_inherit: _build_target_base varargs_inherit: _build_target_base kwargs_inherit: @@ -32,3 +38,31 @@ kwargs: type being build. - 'c': Create a "cdylib" or "staticlib" crate depending on the library type being build. + + <lang>_static_args: + type: list[str] + since: 1.3.0 + description: + Arguments that are only passed to a static library + + vala_static_args: + type: list[str | file] + since: 1.3.0 + description: + Arguments that are only passed to a static library + + Like `vala_args`, [[files]] is allowed in addition to string + + <lang>_shared_args: + type: list[str] + since: 1.3.0 + description: + Arguments that are only passed to a shared library + + vala_shared_args: + type: list[str | file] + since: 1.3.0 + description: + Arguments that are only passed to a shared library + + Like `vala_args`, [[files]] is allowed in addition to string diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 5ff5c0b50..23ce14620 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -216,7 +216,9 @@ class Summary: known_library_kwargs = ( build.known_shlib_kwargs | - build.known_stlib_kwargs + build.known_stlib_kwargs | + {f'{l}_shared_args' for l in compilers.all_languages - {'java'}} | + {f'{l}_static_args' for l in compilers.all_languages - {'java'}} ) known_build_target_kwargs = ( @@ -3202,6 +3204,9 @@ class Interpreter(InterpreterBase, HoldableObject): # FIXME: rustc supports generating both libraries in a single invocation, # but for now compile twice. reuse_object_files = False + elif any(k.endswith(('static_args', 'shared_args')) and v for k, v in kwargs.items()): + # Ensure not just the keyword arguments exist, but that they are non-empty. + reuse_object_files = False else: reuse_object_files = static_lib.pic @@ -3336,6 +3341,16 @@ class Interpreter(InterpreterBase, HoldableObject): raise RuntimeError('Unreachable code') self.kwarg_strings_to_includedirs(kwargs) self.__process_language_args(kwargs) + if targetclass is build.StaticLibrary: + for lang in compilers.all_languages - {'java'}: + deps, args = self.__convert_file_args(kwargs.get(f'{lang}_static_args', [])) + kwargs['language_args'][lang].extend(args) + kwargs['depend_files'].extend(deps) + elif targetclass is build.SharedLibrary: + for lang in compilers.all_languages - {'java'}: + deps, args = self.__convert_file_args(kwargs.get(f'{lang}_shared_args', [])) + kwargs['language_args'][lang].extend(args) + kwargs['depend_files'].extend(deps) # Filter out kwargs from other target types. For example 'soversion' # passed to library() when default_library == 'static'. diff --git a/mesonbuild/interpreter/kwargs.py b/mesonbuild/interpreter/kwargs.py index 45cb07b3d..2f3f37f67 100644 --- a/mesonbuild/interpreter/kwargs.py +++ b/mesonbuild/interpreter/kwargs.py @@ -397,6 +397,35 @@ class Library(_BuildTarget, _SharedLibMixin, _StaticLibMixin, _LibraryMixin): """For library, both_library, and as a base for build_target""" + c_static_args: NotRequired[T.List[str]] + c_shared_args: NotRequired[T.List[str]] + cpp_static_args: NotRequired[T.List[str]] + cpp_shared_args: NotRequired[T.List[str]] + cuda_static_args: NotRequired[T.List[str]] + cuda_shared_args: NotRequired[T.List[str]] + fortran_static_args: NotRequired[T.List[str]] + fortran_shared_args: NotRequired[T.List[str]] + d_static_args: NotRequired[T.List[str]] + d_shared_args: NotRequired[T.List[str]] + objc_static_args: NotRequired[T.List[str]] + objc_shared_args: NotRequired[T.List[str]] + objcpp_static_args: NotRequired[T.List[str]] + objcpp_shared_args: NotRequired[T.List[str]] + rust_static_args: NotRequired[T.List[str]] + rust_shared_args: NotRequired[T.List[str]] + vala_static_args: NotRequired[T.List[T.Union[str, File]]] # Yes, Vala is really special + vala_shared_args: NotRequired[T.List[T.Union[str, File]]] # Yes, Vala is really special + cs_static_args: NotRequired[T.List[str]] + cs_shared_args: NotRequired[T.List[str]] + swift_static_args: NotRequired[T.List[str]] + swift_shared_args: NotRequired[T.List[str]] + cython_static_args: NotRequired[T.List[str]] + cython_shared_args: NotRequired[T.List[str]] + nasm_static_args: NotRequired[T.List[str]] + nasm_shared_args: NotRequired[T.List[str]] + masm_static_args: NotRequired[T.List[str]] + masm_shared_args: NotRequired[T.List[str]] + class BuildTarget(Library): diff --git a/mesonbuild/interpreter/type_checking.py b/mesonbuild/interpreter/type_checking.py index 4b3a8a422..153a0d9e9 100644 --- a/mesonbuild/interpreter/type_checking.py +++ b/mesonbuild/interpreter/type_checking.py @@ -665,7 +665,7 @@ STATIC_LIB_KWS = [ _EXCLUSIVE_SHARED_LIB_KWS: T.List[KwargInfo] = [ _DARWIN_VERSIONS_KW, KwargInfo('soversion', (str, int, NoneType), convertor=lambda x: str(x) if x is not None else None), - KwargInfo('version', (str, NoneType), validator=_validate_shlib_version) + KwargInfo('version', (str, NoneType), validator=_validate_shlib_version), ] # The total list of arguments used by SharedLibrary @@ -712,6 +712,13 @@ JAR_KWS = [ for a in _LANGUAGE_KWS], ] +_SHARED_STATIC_ARGS: T.List[KwargInfo[T.List[str]]] = [ + *[l.evolve(name=l.name.replace('_', '_static_'), since='1.3.0') + for l in _LANGUAGE_KWS], + *[l.evolve(name=l.name.replace('_', '_shared_'), since='1.3.0') + for l in _LANGUAGE_KWS], +] + # Arguments used by both_library and library LIBRARY_KWS = [ *_BUILD_TARGET_KWS, @@ -719,6 +726,7 @@ LIBRARY_KWS = [ *_EXCLUSIVE_SHARED_LIB_KWS, *_EXCLUSIVE_SHARED_MOD_KWS, *_EXCLUSIVE_STATIC_LIB_KWS, + *_SHARED_STATIC_ARGS, _VS_MODULE_DEFS_KW, _JAVA_LANG_KW, ] @@ -730,6 +738,7 @@ BUILD_TARGET_KWS = [ *_EXCLUSIVE_SHARED_MOD_KWS, *_EXCLUSIVE_STATIC_LIB_KWS, *_EXCLUSIVE_EXECUTABLE_KWS, + *_SHARED_STATIC_ARGS, *[a.evolve(deprecated='1.3.0', deprecated_message='The use of "jar" in "build_target()" is deprecated, and this argument is only used by jar()') for a in _EXCLUSIVE_JAR_KWS], KwargInfo( diff --git a/test cases/common/178 bothlibraries/meson.build b/test cases/common/178 bothlibraries/meson.build index 843a607a1..62f2061f8 100644 --- a/test cases/common/178 bothlibraries/meson.build +++ b/test cases/common/178 bothlibraries/meson.build @@ -55,9 +55,17 @@ test('runtest-both-2', exe_both2) # the executable linking using the C compiler. # https://github.com/Netflix/vmaf/issues/1107 libccpp = both_libraries('ccpp', 'foo.cpp', 'libfile.c', - cpp_args : ['-std=c++11']) + cpp_args : ['-std=c++11'], + c_static_args : ['-DSTATIC_COMPILATION'], + cpp_static_args : ['-DSTATIC_COMPILATION'], +) exe = executable('prog-ccpp', 'main2.c', link_with: libccpp.get_static_lib(), c_args : ['-DSTATIC_COMPILATION'], ) test('runtest-ccpp', exe) + +exe = executable('prog-ccpp-shared', 'main2.c', + link_with: libccpp.get_shared_lib(), +) +test('runtest-ccpp-shared', exe) diff --git a/test cases/common/3 static/lib3.c b/test cases/common/3 static/lib3.c new file mode 100644 index 000000000..f834cf8b8 --- /dev/null +++ b/test cases/common/3 static/lib3.c @@ -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 diff --git a/test cases/common/3 static/meson.build b/test cases/common/3 static/meson.build index 04ff2f6f3..1127ecb44 100644 --- a/test cases/common/3 static/meson.build +++ b/test cases/common/3 static/meson.build @@ -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. @@ -12,3 +12,8 @@ endif assert(has_not_changed, 'Static library has changed.') assert(not is_disabler(lib), 'Static library is a disabler.') + +if get_option('default_library') == 'static' + library('lib2', 'lib3.c', c_static_args : ['-DWORK'], c_shared_args : ['-DBREAK']) +endif +build_target('lib4', 'lib3.c', c_static_args : ['-DWORK'], target_type : 'static_library') diff --git a/test cases/common/4 shared/libfile2.c b/test cases/common/4 shared/libfile2.c new file mode 100644 index 000000000..fee1d1efd --- /dev/null +++ b/test cases/common/4 shared/libfile2.c @@ -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; +} diff --git a/test cases/common/4 shared/meson.build b/test cases/common/4 shared/meson.build index 1c88bc587..7f79ad630 100644 --- a/test cases/common/4 shared/meson.build +++ b/test cases/common/4 shared/meson.build @@ -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') @@ -11,3 +11,8 @@ endif assert(has_not_changed, 'Shared library has changed.') assert(not is_disabler(lib), 'Shared library is a disabler.') + +if get_option('default_library') == 'shared' + library('mylib5', 'libfile2.c', c_shared_args : ['-DWORK']) +endif +build_target('mylib4', 'libfile2.c', target_type: 'shared_library', c_shared_args : ['-DWORK'], c_static_args : ['-DBREAK']) diff --git a/unittests/allplatformstests.py b/unittests/allplatformstests.py index f5048837f..18ed3bf5c 100644 --- a/unittests/allplatformstests.py +++ b/unittests/allplatformstests.py @@ -394,7 +394,7 @@ class AllPlatformTests(BasePlatformTests): self.init(testdir) # Get name of static library targets = self.introspect('--targets') - self.assertEqual(len(targets), 1) + self.assertGreaterEqual(len(targets), 1) libname = targets[0]['filename'][0] # Build and get contents of static library self.build() |
