У меня проблемы с компиляцией большого проекта на 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 foo.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).
Редактировать: clang с lld работает нормально.
$ clang++ -fuse-ld=lld -flto -Wl,-as-needed foo.o bar.o -lpthread
$ ./a.out
Hello world