Проблема с clang linker

Я просто опробовал последние версии llvm и clang trunk. Они скомпилированы без единого предупреждения из коробки, но у меня возникли проблемы с привязкой к приветствующему миру примеру. Мой код

#include  int main(){ printf("hello\n"); } 

Если я скомпилирую

 clang test.c 

Я получаю следующую ошибку

 /usr/bin/ld: crt1.o: No such file: No such file or directory clang: error: linker command failed with exit code 1 (use -v to see invocation) 

Использование -v показывает, что gnu ld вызывается как

 "/usr/bin/ld" --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o a.out crt1.o crti.o crtbegin.o -L -L/../../.. /tmp/cc-0XJTsG.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed crtend.o crtn.o 

Но у меня есть объектный файл crt1.o!

 $ locate crt1.o /usr/lib/Mcrt1.o /usr/lib/Scrt1.o /usr/lib/crt1.o /usr/lib/gcrt1.o 

Что также работает

 clang -c test.c gcc test.o 

и, конечно же,

 gcc test.c 

Что я еще пробовал:

 $ clang -Xlinker "-L /usr/lib" test.c /usr/bin/ld: crt1.o: No such file: No such file or directory clang: error: linker command failed with exit code 1 (use -v to see invocation) $ clang -Xlinker "-L /usr/lib" test.c -v "/usr/bin/ld" --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o a.out crt1.o crti.o crtbegin.o -L -L/../../.. -L /usr/lib /tmp/cc-YsI9ES.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed crtend.o 

Я также попытался скопировать файл crt1.o в текущий каталог. Казалось, это сработало. Ну это не скомпилировалось, потому что после этого crti.o не хватало.

Мой дистрибутив – Ubuntu.

Ну, я действительно не знаю, что попробовать дальше. Я не вижу, как я могу исправить clang, и у меня нет идеи о том, как вводить нужный путь в вызове ld. Есть идеи?

Кажется, это версия clang, которая не может определить версию Linux для Linux и версию gcc.

Этот код в clang, который должен добавить путь к crt *: llvm›tools›clang›lib›Driver›Tools.cpp

  CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt1.o"))); CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o"))); CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o"))); 

и GetFilePath попытается найти запрошенные файлы в getFilePaths() текущего ToolChain (файл clang/lib/Driver/ToolChains.cpp ). Если он не может найти файл, он вернет имя без изменений.

Пожалуйста, дайте мне версию вашего ubuntu ( uname -a , cat /etc/lsb-release ), точную версию (номер версии svn) clang и llvm и gcc -v output

Этот ужасный HACK «исправляет» компиляцию / соединение с clang 3.0 (r142716) на Ubuntu 11.10 (x86)

В файле, включенном в /usr/include/stdio.h:28:
/usr/include/features.h:323:10: фатальная ошибка: файл “bits / predefs.h” не найден

/ usr / bin / ld: не удается найти crt1.o: нет такого файла или каталога
/ usr / bin / ld: не удается найти crti.o: нет такого файла или каталога

 diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 75300b5..3e2be30 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -241,6 +241,7 @@ Compilation *Driver::BuildCompilation(ArrayRef ArgList) { // FIXME: Handle environment options which affect driver behavior, somewhere // (client?). GCC_EXEC_PREFIX, LIBRARY_PATH, LPATH, CC_PRINT_OPTIONS. + PrefixDirs.push_back("/usr/lib/i386-linux-gnu"); if (char *env = ::getenv("COMPILER_PATH")) { StringRef CompilerPath = env; while (!CompilerPath.empty()) { diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp index b066e71..c6ffee8 100644 --- a/lib/Frontend/InitHeaderSearch.cpp +++ b/lib/Frontend/InitHeaderSearch.cpp @@ -562,10 +562,12 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, AddPath("/usr/include/x86_64-linux-gnu", System, false, false, false); AddPath("/usr/include/i686-linux-gnu/64", System, false, false, false); AddPath("/usr/include/i486-linux-gnu/64", System, false, false, false); + AddPath("/usr/include/i386-linux-gnu/64", System, false, false, false); } else if (triple.getArch() == llvm::Triple::x86) { AddPath("/usr/include/x86_64-linux-gnu/32", System, false, false, false); AddPath("/usr/include/i686-linux-gnu", System, false, false, false); AddPath("/usr/include/i486-linux-gnu", System, false, false, false); + AddPath("/usr/include/i386-linux-gnu", System, false, false, false); } else if (triple.getArch() == llvm::Triple::arm) { AddPath("/usr/include/arm-linux-gnueabi", System, false, false, false); } 

В последнем выпуске (3.5) эта проблема возникла снова для всех, кто делает сборку, используя опцию configure --with-gcc-toolchain в системе с установленной библиотекой pre-gcc 4.7 libstdc ++.

Вы увидите это в двух вариантах:

 echo '#include ' | clang++ -xc++ - :1:10: fatal error: 'string' file not found #include  ^ 1 error generated. 

… а также не собираюсь находить различные файлы crt.

В обоих случаях следующее позволяет решить проблему до тех пор, пока она не будет исправлена:

 printf '#include \nint main( int argc, char *argv[] ) { return 0; }' > /tmp/blah.cc # Fixes issue not finding C++ headers; note that it must be gcc >= 4.7 clang++ --gcc-toolchain=/path/to/gcc/install -c -o /tmp/blah.o /tmp/blah.cc # Fixes the link error clang++ --gcc-toolchain=/path/to/gcc/install /tmp/blah.o /tmp/blah 

бежать:

 clang -v 

В моем примере вывод:

 clang version 3.0 (tags/RELEASE_30/final) Target: armv7l-unknown-linux-gnueabi Thread model: posix 

Выполните следующее как root, чтобы использовать цель для создания отсутствующей директории в качестве ссылки:

 ln -s /lib/arm-linux-gnueabi /lib/armv7l-unknown-linux-gnueabi ln -s /usr/lib/arm-linux-gnueabi /usr/lib/armv7l-unknown-linux-gnueabi ldconfig