10

我刚刚试用了最新的 llvm 和 clang trunk 版本。他们编译时没有一个开箱即用的警告,但我在链接一个 hello world 示例时遇到了麻烦。我的代码是

#include <stdio.h>
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 调用中注入必要的路径。有任何想法吗?

4

4 回答 4

3

似乎是无法检测主机的linux版本和gcc版本的clang版本..

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 (file clang/lib/Driver/ToolChains.cpp) 列表中搜索询问的文件。如果找不到文件,它将返回 Name 不变。

请给我你的 ubuntu ( uname -a, cat /etc/lsb-release) 版本,clang 和 llvm 的确切版本(svn 版本号),以及gcc -v输出

于 2010-11-11T23:36:54.793 回答
1

这个可怕的 HACK “修复”了在 Ubuntu 11.10 (x86) 上使用 clang 3.0(r142716) 编译/链接

在 /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<const char *> 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);
     }
于 2011-10-22T14:22:43.123 回答
1

在最近的 (3.5) 版本中,对于--with-gcc-toolchain在安装了 pre-gcc 4.7 libstdc++ 库的系统上使用配置选项进行构建的任何人,此类问题再次出现。

你会看到它有两种口味:

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

...以及不打算找到各种 crt 文件。

在这两种情况下,您都可以通过以下方式解决问题,直到问题得到解决:

printf '#include <string>\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
于 2014-10-03T22:46:14.443 回答
0

跑:

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
于 2012-01-23T17:11:07.467 回答