I'm having some troubles compiling a large C++ project that uses link time optimization. After some digging I managed to produce an (almost) minimal working example that exhibits the same issue.
Say that I have the following foo.cpp file:
//foo.cpp
#include <iostream>
#include "bar.h"
int main()
{
std::cout << "Hello world" << std::endl;
//bar(); //Everything works if this is uncommented
return 0;
}
Where bar.h and bar.cpp look like this:
//bar.h
#ifndef __BAR_H__
#define __BAR_H__
void bar();
#endif
and
//bar.cpp
#include "bar.h"
#include <thread>
void bar()
{
std::thread t([] {});
t.join();
}
The code is compiled like this:
$ g++ -std=c++11 -O3 -flto -c foo.cpp
$ g++ -std=c++11 -O3 -flto -c bar.cpp
But trying to link the object files results in a undefined reference error:
$ g++ -flto -Wl,-as-needed foo.o bar.o -lpthread
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/8/libstdc++.so: undefined reference to `pthread_create'
collect2: error: ld returned 1 exit status
Can somebody please explain what is going on here?
Some notes:
- Adding the -pthread flag makes no difference.
- I'm explicitly passing the option -Wl,-as-needed as, on my system, this is not the default. However, this is the default behavior in some other GNU/Linux distributions.
- Linking succeeds if I uncomment the call to bar() in foo.cpp.
- Linking succeeds if the option -Wl,--as-needed is removed (or -Wl,--no-as-needed is added).
- I'm using g++ 8.3.0 (Debian 8.3.0-6) but the same problem appears in g++ 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04).
Edit: clang with lld works fine.
$ clang++ -fuse-ld=lld -flto -Wl,-as-needed foo.o bar.o -lpthread
$ ./a.out
Hello world