“Hello, World!”的 Clang 链接器问题例子

发布于 2024-10-02 13:05:27 字数 2485 浏览 5 评论 0原文

我刚刚尝试了最新的 LLVMClang 主干版本。他们编译时没有任何警告,但我在链接 你好,世界!示例。我的代码是

#include <stdio.h>

int main(){
  printf("Hello, World!\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 丢失了。

我的 Linux 发行版是 Ubuntu

好吧,我真的不知道下一步该尝试什么。我不知道如何修复 clang,也不知道如何在 ld 调用中注入必要的路径。有什么想法吗?

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

#include <stdio.h>

int main(){
  printf("Hello, World!\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:

"/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!

locate crt1.o

Output:

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

This also works:

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.

My Linux distribution is 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

慈悲佛祖 2024-10-09 13:05:27

似乎是 Clang 版本无法检测主机的 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 将尝试在当前 ToolChain 的 getFilePaths() 列表中搜索请求的文件(文件 clang/lib/Driver/ToolChains.cpp)。如果找不到文件,它将返回名称不变。

It seems to be the Clang version which can't detect the host's Linux version and GCC version...

This code in Clang which must add path to the 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.

野鹿林 2024-10-09 13:05:27

在最新的 (3.5) 版本中,对于在具有 GCC 4.7 之前的 libstdc++ 的系统上使用 --with-gcc-toolchain 配置选项进行构建的任何人来说,此类问题再次出现。库已安装。

您会看到它有两种风格:

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

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-toolchain configure option on a system with a pre-GCC 4.7 libstdc++ library installed.

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.

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
迷离° 2024-10-09 13:05:27

这个可怕的黑客“修复”了 Ubuntu 11.10 x86 (Oneiric Ocelot)。

/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);
     }

This horrible hack "fixes" compiling/linking with Clang 3.0 (r142716) on Ubuntu 11.10 x86 (Oneiric Ocelot).

In the file included from /usr/include/stdio.h:28:

/usr/include/features.h:323:10: fatal error: 'bits/predefs.h' file not found

/usr/bin/ld: cannot find crt1.o: No such file or directory
/usr/bin/ld: cannot find crti.o: No such file or directory

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);
     }
小瓶盖 2024-10-09 13:05:27

运行:

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

Run:

clang -v

In my example, the 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 the missing directory as a link:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文