aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/interpreter/interpreter.py22
-rw-r--r--test cases/common/254 generated header dep/foo.c1
-rw-r--r--test cases/common/254 generated header dep/meson.build22
3 files changed, 35 insertions, 10 deletions
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index 1f9a99a..d4f185f 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -101,6 +101,7 @@ import typing as T
import textwrap
import importlib
import copy
+import itertools
if T.TYPE_CHECKING:
import argparse
@@ -3050,6 +3051,7 @@ Try setting b_lundef to false instead.'''.format(self.coredata.options[OptionKey
@FeatureNew('both_libraries', '0.46.0')
def build_both_libraries(self, node, args, kwargs):
shared_lib = self.build_target(node, args, kwargs, build.SharedLibrary)
+ static_lib = self.build_target(node, args, kwargs, build.StaticLibrary)
# Check if user forces non-PIC static library.
pic = True
@@ -3071,16 +3073,16 @@ Try setting b_lundef to false instead.'''.format(self.coredata.options[OptionKey
reuse_object_files = pic
if reuse_object_files:
- # Exclude sources from args and kwargs to avoid building them twice
- static_args = [args[0]]
- static_kwargs = kwargs.copy()
- static_kwargs['sources'] = []
- static_kwargs['objects'] = shared_lib.extract_all_objects()
- else:
- static_args = args
- static_kwargs = kwargs
-
- static_lib = self.build_target(node, static_args, static_kwargs, build.StaticLibrary)
+ # Replace sources with objects from the shared library to avoid
+ # building them twice. We post-process the static library instead of
+ # removing sources from args because sources could also come from
+ # any InternalDependency, see BuildTarget.add_deps().
+ static_lib.objects.append(build.ExtractedObjects(shared_lib, shared_lib.sources, shared_lib.generated, []))
+ static_lib.sources = []
+ static_lib.generated = []
+ # Compilers with no corresponding sources confuses the backend.
+ # Keep only the first compiler because it is the linker.
+ static_lib.compilers = dict(itertools.islice(static_lib.compilers.items(), 1))
return build.BothLibraries(shared_lib, static_lib)
diff --git a/test cases/common/254 generated header dep/foo.c b/test cases/common/254 generated header dep/foo.c
new file mode 100644
index 0000000..f4de601
--- /dev/null
+++ b/test cases/common/254 generated header dep/foo.c
@@ -0,0 +1 @@
+#include "foo.h"
diff --git a/test cases/common/254 generated header dep/meson.build b/test cases/common/254 generated header dep/meson.build
new file mode 100644
index 0000000..195d082
--- /dev/null
+++ b/test cases/common/254 generated header dep/meson.build
@@ -0,0 +1,22 @@
+project('generated header dep', 'c')
+
+# Regression test case for a very specific case:
+# - Uses both_libraries(), or library() with default_library=both.
+# - A header file is generated by a custom_target() and passed as source.
+# - A C file that uses that header is passed as a declare_dependency() source.
+# Under those specific conditions, the static library used to miss an order
+# dependency on the header file. This happened in GLib:
+# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2917.
+
+python = import('python').find_installation()
+header = custom_target(
+ output: 'foo.h',
+ capture: true,
+ command: [python, '-c', 'print("#define FOO")'],
+)
+
+sources_dep = declare_dependency(sources: files('foo.c'))
+
+both_libraries('foo', header,
+ dependencies: sources_dep,
+)