Оптимизация времени соединения Clang не работает должным образом на Fedora 18 - программирование
Подтвердить что ты не робот

Оптимизация времени соединения Clang не работает должным образом на Fedora 18

Я новичок, и я думаю, что я делаю что-то глупое. Но я потратил несколько часов на поиск решений, включая поиск здесь, где я не нашел вопросов, касающихся -flto с дистрибутированными пакетами. Подробное описание этого описания относится к Fedora 18, но у меня возникают аналогичные проблемы с Ubuntu 13.04, поэтому проблема не специфична для Fedora. Это либо я, либо clang.

Проблема: я пытаюсь скомпилировать простую программу hello-world, используя clang++ -flto, чтобы получить преимущества оптимизации времени ссылки. Без -flto работает отлично. С -flto он не связывается. Вызывая как clang -flto -o hello hello.o -v, чтобы увидеть полную командную строку компоновщика, я получаю:

$ clang++ -flto -o hello hello.o -v
clang version 3.2 (tags/RELEASE_32/final)
Target: x86_64-redhat-linux-gnu
Thread model: posix
 "/usr/bin/ld" --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o hello /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.7.2/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/4.7.2 -L/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../.. -L/lib -L/usr/lib -plugin /usr/bin/../lib/LLVMgold.so hello.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-redhat-linux/4.7.2/crtend.o /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crtn.o
/usr/bin/ld: /usr/bin/../lib/LLVMgold.so: error loading plugin
/usr/bin/ld: /usr/bin/../lib/LLVMgold.so: error in plugin cleanup (ignored)
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Кажется, есть две проблемы:

  • clang++ вызывает компоновщик как /usr/bin/ld, и это не золотой линкер. Fedora18 устанавливает золото как /usr/bin/ld.gold. Я попытался создать символическую ссылку от /usr/local/bin/ld до /usr/bin/ld.gold, подтвердил, что which ld говорит /usr/local/bin/ld, но clang++ не использует это. Кажется, это связано с /usr/bin/ld.

  • clang++ вызывает компоновщик с -plugin /usr/bin/../lib/LLVMgold.so. Это неверно, так как распространение клана Fedora помещает его в /usr/lib64/llvm/LLVMgold.so.

Я попытался вручную вызвать эту линию компоновщика выше со следующими настройками:

  • Замените -plugin /usr/bin/../lib/LLVMgold.so на -plugin /usr/lib64/llvm/LLVMgold.so. Это дает сообщение об ошибке hello.o: file not recognized: File format not recognized. Таким образом, не-золотой линкер, похоже, знает о плагинах, но не принимает .o, которые содержат бит-код LLVM.

  • Замените /usr/bin/ld на /usr/bin/ld.gold. Это работает, генерирует исполняемый файл, который работает как ожидалось.

  • Оба из указанных выше с --plugin вместо -plugin. Это изменение не имеет значения.

Итак, что лучший способ для тех, кто предпочитает придерживаться системных пакетов для использования clang -flto? Я надеюсь, что есть файл конфигурации, или недокументированные параметры или переменные среды, которые позволят мне переопределить их. Или лучше, что мне не хватает пакета, а "yum install..." исправит его.

Я бы предпочел не ссылаться на компоновщик напрямую, так как тогда мои make файлы должны знать системные объекты и библиотеки, о которых они не должны знать (например, crt1.o, crtbegin.o, crtend.o). Я мог бы также создать clang сам, но я ничего не вижу в его настройке script, который позволяет мне настроить путь к компоновщику и плагину.

Я запускаю Fedora 18. Единственными пакетами, не относящимися к дистрибутиву на компьютере, являются Google Chrome и VMware Tools (это гость в VMWare Fusion). Версии соответствующих пакетов Fedora (весь компьютер "обновлен yum" на сегодняшний день, 29 апреля 2013 года):

$ yum list --noplugins installed binutils* clang* llvm* gcc*
Installed Packages
binutils.x86_64                      2.23.51.0.1-6.fc18                 @updates
binutils-devel.x86_64                2.23.51.0.1-6.fc18                 @updates
clang.x86_64                         3.2-2.fc18                         @updates
clang-devel.x86_64                   3.2-2.fc18                         @updates
clang-doc.noarch                     3.2-2.fc18                         @updates
gcc.x86_64                           4.7.2-8.fc18                       @fedora 
gcc-c++.x86_64                       4.7.2-8.fc18                       @fedora 
llvm.x86_64                          3.2-2.fc18                         @updates
llvm-libs.x86_64                     3.2-2.fc18                         @updates
4b9b3361

Ответ 1

В Fedora есть утилита alternatives - она ​​позволяет подставлять один компоновщик с другим на системный уровень:

$ sudo alternatives --display ld
ld - status is auto.
link currently points to /usr/bin/ld.bfd
/usr/bin/ld.bfd - priority 50
/usr/bin/ld.gold - priority 30
Current `best' version is /usr/bin/ld.bfd.
$ sudo alternatives --set ld /usr/bin/ld.gold

О местоположении LLVMgold.so вы можете сообщить об ошибке в Fedora Bugzilla, так как путь встроен в источники clang:

lib/Driver/Tools.cpp: std::string Плагин = ToolChain.getDriver(). Dir + "/../lib/LLVMgold.so";

Ребята Fedora могут применить патч к исходному пакету Clang или создать символическую ссылку на LLVMgold.so. Пока нет изменений даже в Fedora 20.