Skip to content

Commit

Permalink
both_libraries: Make sure to select the right linker for static lib
Browse files Browse the repository at this point in the history
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.
Netflix/vmaf#1107
  • Loading branch information
xclaesse authored and eli-schwartz committed Nov 1, 2022
1 parent 8d8ce4f commit 81763e6
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 4 deletions.
5 changes: 2 additions & 3 deletions mesonbuild/interpreter/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@
import textwrap
import importlib
import copy
import itertools

if T.TYPE_CHECKING:
import argparse
Expand Down Expand Up @@ -3093,8 +3092,8 @@ def build_both_libraries(self, node, args, kwargs):
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)

Expand Down
11 changes: 11 additions & 0 deletions test cases/common/178 bothlibraries/foo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <memory>
#include "mylib.h"

extern "C" {
DO_EXPORT int foo(void);
}

int foo(void) {
auto bptr = std::make_shared<int>(0);
return *bptr;
}
9 changes: 9 additions & 0 deletions test cases/common/178 bothlibraries/main2.c
Original file line number Diff line number Diff line change
@@ -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;
}
14 changes: 13 additions & 1 deletion test cases/common/178 bothlibraries/meson.build
Original file line number Diff line number Diff line change
@@ -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)
Expand Down Expand Up @@ -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)

0 comments on commit 81763e6

Please sign in to comment.