Неопределенная ссылка с оптимизацией времени ссылки и флагом --as-required ld - PullRequest
1 голос
/ 30 мая 2019

У меня проблемы с компиляцией большого проекта на 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
...