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

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

Проблема: я пытаюсь скомпилировать простую программу приветствия, используя 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)

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

  1. 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.

  2. clang++ вызвал компоновщик с -plugin /usr/bin/../lib/LLVMgold.so. Это неправильно, так как дистрибутив Clang в 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 самостоятельно, но я не вижу в его скрипте configure ничего, что позволило бы мне настроить путь компоновщика и плагина.

Я использую Fedora 18. Единственными пакетами, не являющимися дистрибутивами на компьютере, являются Google Chrome и VMware Tools (это гость внутри VMWare Fusion). Версии соответствующих пакетов Fedora (весь компьютер «ням обновлен» на сегодняшний день, 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

person SnoopyLane    schedule 30.04.2013    source источник


Ответы (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 sources:

lib/Driver/Tools.cpp: std::string Plugin = ToolChain.getDriver().Dir + "/../lib/LLVMgold.so";

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

person abyss.7    schedule 11.11.2013
comment
Просто для экономии времени, как видите, он ищет в lib, а не lib64. Символическая ссылка, которая сработала для меня, была sudo ln -s /usr/lib64/llvm/LLVMgold.so /usr/lib/LLVMgold.so. - person Jerska; 26.07.2014