Оптимизация времени соединения 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
Ответы
Ответ 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.