Linking C++ executable with Objective-C dynamic library fails
- Dominant language
- Python
- Stars
- 6.6k
- Forks
- 1.9k
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 33
Description
When linking a C++ application using C++11 threads to a library built from Objective-C sources, it seems like Meson incorrectly selects the Objective-C linker which leaves standard library symbols unresolved since no C++ standard library is linked. Linking a similar application with a library built from Objective-C++ sources works fine, because the Objective-C++ linker is selected (I believe this would be the correct behavior even in the first case).
Example:
```
project('test', ['cpp', 'objc', 'objcpp'], default_options: ['cpp_std=c++11'])
t = dependency('threads')
l1 = library('lib_1', 'lib.m')
d1 = declare_dependency(link_with: l1, include_directories: include_directories('.'))
e1 = executable('app_1', 'test.cpp', dependencies: [t, d1])
l2 = library('lib_2', 'lib.mm')
d2 = declare_dependency(link_with: l2, include_directories: include_directories('.'))
e2 = executable('app_2', 'test.cpp', dependencies: [t, d2])
```
The implementation of `lib.m` and `lib.mm` is irrelevant, but `test.cpp` must use C++11 threads or atomics. When building `app_2`, everything is fine, but building `app_1` yields the following:
```
[1/1] Linking target app_1.
FAILED: app_1
cc -o app_1 'app_1@exe/test.cpp.o' liblib_1.dylib -pthread -Wl,-rpath,/private/tmp/test/build/
clang: warning: argument unused during compilation: '-pthread' [-Wunused-command-line-argument]
Undefined symbols for architecture x86_64:
"std::__1::__thread_struct::__thread_struct()", referenced from:
std::__1::thread::thread(void (&&&)()) in test.cpp.o
"std::__1::__thread_struct::~__thread_struct()", referenced from:
std::__1::thread::thread(void (&&&)()) in test.cpp.o
void* std::__1::__thread_proxy >, void (*)()> >(void*) in test.cpp.o
"std::__1::__thread_local_data()", referenced from:
void* std::__1::__thread_proxy >, void (*)()> >(void*) in test.cpp.o
"std::__1::__throw_system_error(int, char const*)", referenced from:
std::__1::thread::thread(void (&&&)()) in test.cpp.o
"std::__1::thread::~thread()", referenced from:
_main in test.cpp.o
"operator delete(void*)", referenced from:
std::__1::thread::thread(void (&&&)()) in test.cpp.o
void* std::__1::__thread_proxy >, void (*)()> >(void*) in test.cpp.o
"operator new(unsigned long)", referenced from:
std::__1::thread::thread(void (&&&)()) in test.cpp.o
"___gxx_personality_v0", referenced from:
std::__1::thread::thread(void (&&&)()) in test.cpp.o
void* std::__1::__thread_proxy >, void (*)()> >(void*) in test.cpp.o
Dwarf Exception Unwind Info (__eh_frame) in test.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
```
Contributor guide
Research direction
Start by reproducing the shown Meson project with the two library targets, app_1 and app_2, and compare their generated link commands. Trace how the source language of linked libraries affects executable linker selection. Done means the app_1 C++11 threads example links successfully with the required C++ standard library, like app_2.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, objective-c
- Domain
- build-system, compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100