Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

clang linker problem

Tags:

c

linker

clang

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\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
/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.

My distro 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?

like image 470
Ben04 Avatar asked Nov 11 '10 23:11

Ben04


2 Answers

Seems to be clang version which can't detect 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.

Please, give me version of your ubuntu (uname -a, cat /etc/lsb-release), exact release (svn revision number) of clang and llvm, and gcc -v output

like image 60
osgx Avatar answered Nov 27 '22 17:11

osgx


This horrible HACK "fixes" compiling/linking with clang 3.0(r142716) on Ubuntu 11.10 (x86)

In 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);
     }
like image 42
Peter Avatar answered Nov 27 '22 19:11

Peter