summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/snippets/cmake_only_public_link_flags_in_dep.md8
-rw-r--r--mesonbuild/cmake/interpreter.py10
-rw-r--r--mesonbuild/cmake/tracetargets.py4
3 files changed, 20 insertions, 2 deletions
diff --git a/docs/markdown/snippets/cmake_only_public_link_flags_in_dep.md b/docs/markdown/snippets/cmake_only_public_link_flags_in_dep.md
new file mode 100644
index 000000000..83ccfd439
--- /dev/null
+++ b/docs/markdown/snippets/cmake_only_public_link_flags_in_dep.md
@@ -0,0 +1,8 @@
+## Dependencies from CMake subprojects now use only PUBLIC link flags
+
+Any [[@dep]] obtained from a CMake subproject (or `.wrap` with `method = cmake`)
+now only includes link flags marked in CMake as `PUBLIC` or `INTERFACE`.
+Flags marked as `PRIVATE` are now only applied when building the subproject
+library and not when using it as a dependency. This better matches how CMake
+handles link flags and fixes link errors when using some CMake projects as
+subprojects.
diff --git a/mesonbuild/cmake/interpreter.py b/mesonbuild/cmake/interpreter.py
index 5e6cde653..1f82f875b 100644
--- a/mesonbuild/cmake/interpreter.py
+++ b/mesonbuild/cmake/interpreter.py
@@ -223,6 +223,7 @@ class ConverterTarget:
self.install_dir: T.Optional[Path] = None
self.link_libraries = target.link_libraries
self.link_flags = target.link_flags + target.link_lang_flags
+ self.public_link_flags: T.List[str] = []
self.depends_raw: T.List[str] = []
self.depends: T.List[T.Union[ConverterTarget, ConverterCustomTarget]] = []
@@ -347,6 +348,7 @@ class ConverterTarget:
rtgt = resolve_cmake_trace_targets(self.cmake_name, trace, self.env)
self.includes += [Path(x) for x in rtgt.include_directories]
self.link_flags += rtgt.link_flags
+ self.public_link_flags += rtgt.public_link_flags
self.public_compile_opts += rtgt.public_compile_opts
self.link_libraries += rtgt.libraries
@@ -1167,12 +1169,18 @@ class CMakeInterpreter:
# declare_dependency kwargs
dep_kwargs: TYPE_mixed_kwargs = {
- 'link_args': tgt.link_flags + tgt.link_libraries,
'link_with': id_node(tgt_var),
'compile_args': tgt.public_compile_opts,
'include_directories': id_node(inc_var),
}
+ # Static libraries need all link options and transient dependencies, but other
+ # libraries should only use the link flags from INTERFACE_LINK_OPTIONS.
+ if tgt_func == 'static_library':
+ dep_kwargs['link_args'] = tgt.link_flags + tgt.link_libraries
+ else:
+ dep_kwargs['link_args'] = tgt.public_link_flags
+
if dependencies:
generated += dependencies
diff --git a/mesonbuild/cmake/tracetargets.py b/mesonbuild/cmake/tracetargets.py
index 5a9d35284..2cc0c1722 100644
--- a/mesonbuild/cmake/tracetargets.py
+++ b/mesonbuild/cmake/tracetargets.py
@@ -42,6 +42,7 @@ class ResolvedTarget:
def __init__(self) -> None:
self.include_directories: T.List[str] = []
self.link_flags: T.List[str] = []
+ self.public_link_flags: T.List[str] = []
self.public_compile_opts: T.List[str] = []
self.libraries: T.List[str] = []
@@ -111,7 +112,8 @@ def resolve_cmake_trace_targets(target_name: str,
res.include_directories += [x for x in tgt.properties['INTERFACE_INCLUDE_DIRECTORIES'] if x]
if 'INTERFACE_LINK_OPTIONS' in tgt.properties:
- res.link_flags += [x for x in tgt.properties['INTERFACE_LINK_OPTIONS'] if x]
+ res.public_link_flags += [x for x in tgt.properties['INTERFACE_LINK_OPTIONS'] if x]
+ res.link_flags += res.public_link_flags
if 'INTERFACE_COMPILE_DEFINITIONS' in tgt.properties:
res.public_compile_opts += ['-D' + re.sub('^-D', '', x) for x in tgt.properties['INTERFACE_COMPILE_DEFINITIONS'] if x]