Неопределенная ссылка с оптимизацией времени ссылки и флагом --as-required ld
У меня возникли некоторые проблемы при компиляции большого проекта C++, который использует оптимизацию времени ссылки. После некоторых раскопок мне удалось создать (почти) минимальный рабочий пример, демонстрирующий ту же проблему.
Скажите, что у меня есть следующий файл foo.cpp:
//foo.cpp
#include <iostream>
#include "bar.h"
int main()
{
std::cout << "Hello world" << std::endl;
//bar(); //Everything works if this is uncommented
return 0;
}
Где bar.h и bar.cpp выглядят так:
//bar.h
#ifndef __BAR_H__
#define __BAR_H__
void bar();
#endif
а также
//bar.cpp
#include "bar.h"
#include <thread>
void bar()
{
std::thread t([] {});
t.join();
}
Код скомпилирован так:
$ g++ -std=c++11 -O3 -flto -c for.cpp
$ g++ -std=c++11 -O3 -flto -c bar.cpp
Но попытка связать объектные файлы приводит к неопределенной ошибке ссылки:
$ 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
Может кто-нибудь объяснить, что здесь происходит?
Некоторые заметки:
- Добавление флага -pthread не имеет значения.
- Я явно передаю опцию -Wl,-as-required, так как в моей системе это не значение по умолчанию. Однако это поведение по умолчанию в некоторых других дистрибутивах GNU/Linux.
- Связывание будет успешным, если я раскомментирую вызов bar() в foo.cpp.
- Связывание завершается успешно, если удалена опция -Wl,- по мере необходимости (или -Wl,- добавлена без необходимости).
- Я использую g++ 8.3.0 (Debian 8.3.0-6), но та же проблема появляется в g++ 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04).