From 81763e610fac24c7a9720fa37630e7660111c4a6 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Sun, 30 Oct 2022 09:59:07 -0400 Subject: [PATCH] both_libraries: Make sure to select the right linker for static lib Regression test: libccpp has both C and C++ sources. The executable only has C sources. It should still link using the C++ compiler. When using both_libraries the static has no sources and thus no compilers, resulting in the executable linking using the C compiler. https://github.com/Netflix/vmaf/issues/1107 --- mesonbuild/interpreter/interpreter.py | 5 ++--- test cases/common/178 bothlibraries/foo.cpp | 11 +++++++++++ test cases/common/178 bothlibraries/main2.c | 9 +++++++++ test cases/common/178 bothlibraries/meson.build | 14 +++++++++++++- 4 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 test cases/common/178 bothlibraries/foo.cpp create mode 100644 test cases/common/178 bothlibraries/main2.c diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 056cc3298..0bab57ebd 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -101,7 +101,6 @@ import typing as T import textwrap import importlib import copy -import itertools if T.TYPE_CHECKING: import argparse @@ -3093,8 +3092,8 @@ Try setting b_lundef to false instead.'''.format(self.coredata.options[OptionKey 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)) + # Keep only compilers used for linking + static_lib.compilers = {k: v for k, v in static_lib.compilers.items() if k in compilers.clink_langs} return build.BothLibraries(shared_lib, static_lib) diff --git a/test cases/common/178 bothlibraries/foo.cpp b/test cases/common/178 bothlibraries/foo.cpp new file mode 100644 index 000000000..a705cbc5b --- /dev/null +++ b/test cases/common/178 bothlibraries/foo.cpp @@ -0,0 +1,11 @@ +#include +#include "mylib.h" + +extern "C" { + DO_EXPORT int foo(void); +} + +int foo(void) { + auto bptr = std::make_shared(0); + return *bptr; +} diff --git a/test cases/common/178 bothlibraries/main2.c b/test cases/common/178 bothlibraries/main2.c new file mode 100644 index 000000000..e1f4bf8f5 --- /dev/null +++ b/test cases/common/178 bothlibraries/main2.c @@ -0,0 +1,9 @@ +#include "mylib.h" + +DO_IMPORT int func(void); +DO_IMPORT int foo(void); +DO_IMPORT int retval; + +int main(void) { + return func() + foo() == retval ? 0 : 1; +} diff --git a/test cases/common/178 bothlibraries/meson.build b/test cases/common/178 bothlibraries/meson.build index f3191cc5d..bb3a2bced 100644 --- a/test cases/common/178 bothlibraries/meson.build +++ b/test cases/common/178 bothlibraries/meson.build @@ -1,4 +1,4 @@ -project('both libraries linking test', 'c') +project('both libraries linking test', 'c', 'cpp') both_libs = both_libraries('mylib', 'libfile.c') dep = declare_dependency(link_with: both_libs) @@ -48,3 +48,15 @@ assert(both_libs3.get_static_lib().name() == 'mylib') test('runtest-shared-2', exe_shared2) test('runtest-static-2', exe_static2) test('runtest-both-2', exe_both2) + +# Regression test: libccpp has both C and C++ sources. The executable only has +# C sources. It should still link using the C++ compiler. When using +# both_libraries the static has no sources and thus no compilers, resulting in +# the executable linking using the C compiler. +# https://github.com/Netflix/vmaf/issues/1107 +libccpp = both_libraries('ccpp', 'foo.cpp', 'libfile.c') +exe = executable('prog-ccpp', 'main2.c', + link_with: libccpp.get_static_lib(), + c_args : ['-DSTATIC_COMPILATION'], +) +test('runtest-ccpp', exe)