summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2023-07-13 10:26:14 -0700
committerEli Schwartz <eschwartz93@gmail.com>2023-10-09 17:33:48 -0400
commit013536fcb45dc40c4f592f5c5821ee6d38d331ed (patch)
treeee7cddf43778f63a5f102de1225ce62e1ff5f419
parente24f43051255d3978002f39d08149c3088cb67f9 (diff)
downloadmeson-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.md9
-rw-r--r--docs/yaml/functions/library.yaml34
-rw-r--r--mesonbuild/interpreter/interpreter.py17
-rw-r--r--mesonbuild/interpreter/kwargs.py29
-rw-r--r--mesonbuild/interpreter/type_checking.py11
-rw-r--r--test cases/common/178 bothlibraries/meson.build10
-rw-r--r--test cases/common/3 static/lib3.c11
-rw-r--r--test cases/common/3 static/meson.build7
-rw-r--r--test cases/common/4 shared/libfile2.c22
-rw-r--r--test cases/common/4 shared/meson.build7
-rw-r--r--unittests/allplatformstests.py2
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()