C语言 叮当链接器问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4160262/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
clang linker problem
提问by Ben04
I just tried out the latest llvm and clang trunk versions. They compiled without a single warning out of the box but I'm having trouble linking a hello world example. My Code is
我刚刚尝试了最新的 llvm 和 clang 主干版本。他们编译时没有开箱即用的警告,但我在链接 hello world 示例时遇到了麻烦。我的代码是
#include <stdio.h>
int main(){
printf("hello\n");
}
If I compile using
如果我编译使用
clang test.c
I get the following error
我收到以下错误
/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)
Using -v shows that the gnu ld is invoked as
使用 -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
But I have the crt1.o object file!
但是我有 crt1.o 目标文件!
$ locate crt1.o
/usr/lib/Mcrt1.o
/usr/lib/Scrt1.o
/usr/lib/crt1.o
/usr/lib/gcrt1.o
What also works is
同样有效的是
clang -c test.c
gcc test.o
and of course
而且当然
gcc test.c
What I further tried:
我进一步尝试过的:
$ 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
I also tried copying the crt1.o file into the current directory. That seemed to work. Well it didn't compile because after that crti.o was missing.
我还尝试将 crt1.o 文件复制到当前目录中。那似乎奏效了。好吧,它没有编译,因为在那之后 crti.o 丢失了。
My distro is Ubuntu.
我的发行版是 Ubuntu。
Well I don't really know what to try next. I don't see how I could fix clang nor do I have an idea on how to inject the necessary path in the ld invocation. Any ideas?
好吧,我真的不知道接下来要尝试什么。我不知道如何修复 clang,也不知道如何在 ld 调用中注入必要的路径。有任何想法吗?
采纳答案by osgx
Seems to be clang version which can't detect host's linux version and gcc version..
似乎是无法检测主机的linux版本和gcc版本的clang版本..
This code in clang which must add path to the crt*:
llvm?tools?clang?lib?Driver?Tools.cpp
这段代码必须添加到 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")));
and the GetFilePath will try to search asked files in getFilePaths()list of current ToolChain (file clang/lib/Driver/ToolChains.cpp). If it can't find a file it will return the Name unchanged.
并且 GetFilePath 将尝试在getFilePaths()当前 ToolChain (file clang/lib/Driver/ToolChains.cpp)列表中搜索询问的文件。如果找不到文件,它将返回名称不变。
Please, give me version of your ubuntu (uname -a, cat /etc/lsb-release), exact release (svn revision number) of clang and llvm, and gcc -voutput
请给我你的 ubuntu ( uname -a, cat /etc/lsb-release) 版本,clang 和 llvm 的确切版本(svn 修订号),以及gcc -v输出
回答by Peter
This horrible HACK "fixes" compiling/linking with clang 3.0(r142716) on Ubuntu 11.10 (x86)
这个可怕的黑客“修复”了在 Ubuntu 11.10 (x86) 上使用 clang 3.0(r142716) 编译/链接
In file included from /usr/include/stdio.h:28:
/usr/include/features.h:323:10: fatal error: 'bits/predefs.h' file not found
在 /usr/include/stdio.h:28 包含的文件中:
/usr/include/features.h:323:10: 致命错误:'bits/predefs.h' 文件未找到
/usr/bin/ld: cannot find crt1.o: No such file or directory
/usr/bin/ld: cannot find crti.o: No such file or directory
/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);
}
回答by Brian Vandenberg
On the most recent (3.5) release this sort of problem has cropped up again for anyone who does a build using the --with-gcc-toolchainconfigure option on a system with a pre-gcc 4.7 libstdc++ library installed.
在最近的 (3.5) 版本中,对于--with-gcc-toolchain在安装了 pre-gcc 4.7 libstdc++ 库的系统上使用配置选项进行构建的任何人,此类问题再次出现。
You'll see it in two flavors:
你会看到它有两种口味:
echo '#include <string>' | clang++ -xc++ -
<stdin>:1:10: fatal error: 'string' file not found
#include <string>
^
1 error generated.
... as well as not being about to find the various crt files.
...以及不会找到各种 crt 文件。
In both cases, the following allows you to work around the problem until it gets fixed:
在这两种情况下,您都可以通过以下方式解决问题,直到问题得到解决:
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
回答by user340994
run:
跑:
clang -v
In my example output is:
在我的示例输出中:
clang version 3.0 (tags/RELEASE_30/final)
Target: armv7l-unknown-linux-gnueabi
Thread model: posix
Run the following as root to use the target to create missing directory as a link:
以 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

