Linking with llvm clang llvm ld main not found - llvm

$ cat test.c
int printf(const char *, ...);
int main() { printf("ok\n");}
$ clang -c test.c
$ llvm-ld test.o -o test /usr/lib/crt1.o -lSystem
$ ./test
'main' function not found in module.
$ ld test.o -o test /usr/lib/crt1.o -lSystem
$ ./test
ok
I am trying to compile the simple program with clang, and then link it with llvm-ld, my goal is to avoid GNU ld. I must be using it in a wrong way?

llvm-ld uses bitcode files as inputs to either get an executable or combine all input files into a new bitcode file. For object files you need to use lld.

Related

2 Different LD errors when trying to link static library

I wrote a custom C++ library, which compiled correctly, and am trying to write a test program for some different accuracy checks.
When I compile it this way:
$ c++ -I./include/ -L./lib -lname test.cpp -c -o test.o
....[succeeds ]
$ c++ -I./include/ -L./lib -lname test.o -o test
I get:
ld: 1 duplicate symbol for... for the function I'm testing
But when I compile the test.o the same way & change the executable method:
c++ -I./include -L./lib test.o -o test
it returns: `ld: symbols() not found for ..." for the function I'm testing.
I am 100% sure about the way I compiled & built the library, so I don't understand exactly what I am doing wrong even after I've tried several different ways of compiling test.
Edits:
Fixed typo in test filename.
Removed -L & -l flags from step 1, and it compiled.
Removed -I from step 2, and it gave the error ld: library for -lname not found when compiled as:
c++ -L./lib -lname test.obj -o test

(clang / llvm-mc / lld) hello world (x86-64 windows & linux)

Is llvm able to compile, assemble and link x86-64 code on windows and/or linux using llvm-mc and lld?
If so, is there a hello-world level example out there? The documentation is pretty sparse at present.
I've tried building a simple hello world (main0.cpp) using trunk LLVM (with clang & lld).
main0.cpp:
int main(int argc, char const* argv[])
{ return 0; }
Compile (no errors):
[MY-LLVM]/clang -S -o main0.s main0.cpp
Assemble (no errors):
[MY-LLVM]/llvm-mc -arch=x86-64 -triple=x86_64-linux-gnu -o main0.o main0.s
Link (FAILS HERE!):
[MY-LLVM]/lld -flavor gnu --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -L/usr/lib/gcc/x86_64-linux-gnu/4.8 -L/usr/lib/x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib -L/<MY-LLVM>/lib -L/lib -L/usr/lib -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o /usr/lib/gcc/x86_64-linux-gnu/4.8/crtend.o /usr/lib/x86_64-linux-gnu/crtn.o -o main0.run main.o
Link error:
lld: unknown input file format for file main.o
I obtained the linker command via clang -o main0.run main0.cpp -### (replacing ld with [MY-LLVM]/lld -flavor gnu).
I assume that I'm either generating the wrong type of object file when assembling, or using the wrong parameters when linking.
Does anyone know how to do this right?
(My ultimate aim is to get full C++14 working on win64 (without massive hacks), but I'm struggling with getting trunk clang to work with the mingw tools so I thought I'd try pure LLVM).
lld developer here.
lld self hosts on both Linux and Windows, so I would expect them to work here. The way I generally get clang to use lld is to make a symlink to lld named ld and add it to PATH. lld will behave like gnu-ld in this case.
As for llvm-mc, it is not an assembler. It is a tool for testing the MC layer of llvm. By default it simply parses the assembly and prints it back out. This is why lld is rejecting the main0.o file, as it's actually a text file.
The correct thing to do here without having lld as ld in the path is either:
clang -c -o main0.o main0.cpp
or:
clang -S -o main0.s main0.cpp
clang -c -o main0.o main0.s
If you really want the assembly for some reason.

How to replace llvm-ld with clang?

Summary: llvm-ld has been removed from the LLVM 3.2 release. I am trying to figure out how to use clang in its place in my build system.
Note that I figured out the answer to my own question while writing it but I am still posting it in case it is useful to anyone else. Alternative answers are also welcome.
Details:
I have a build process which first generates bitcode using clang++ -emit-llvm. Then I take the bitcode files and link them together with llvm-link. Then I apply some standard optimization passes with opt. Then I apply another custom compiler pass with opt. Then I apply the standard optimization passes again using opt a third time. Finally I take the output from the last run of opt and use llvm-link to link with appropriate libraries to generate my executable. When I tried to replace llvm-link with clang++ in this process I get the error message: file not recognized: File format not recognized
To make this question more concrete I created a simplified example of what I am trying to do. First there are two files that I want to compile and link together
test1.cpp:
#include <stdio.h>
int getNum();
int main()
{
int value = getNum();
printf("value is %d\n", value);
return 0;
}
test2.cpp
int getNum()
{
return 5;
}
I executed the following sequence of commands:
clang++ -emit-llvm -c test1.cpp test2.cpp
llvm-link -o test.bc1 test1.o test2.o
opt test.bc1 -o test.bc2 -std-compile-opts
(Note that I am currently running llvm 3.1, but I'm trying to figure out the steps that will work for llvm 3.2. I assume that I should be able to make the LLVM 3.1 version work correctly using clang instead of llvm-ld)
Then if I run:
llvm-ld test.bc2 -o a.out -native
everything is fine and a.out prints out 5.
However, if I run:
clang++ test.bc2 -o a.out
Then I get the error message:
test.bc2: file not recognized: File format not recognized clang-3:
error: linker command failed with exit code 1 (use -v to see invocation)
Obviously I know that I can produce an executable file by running clang directly on the .cpp files. But I'm wondering what the best way to integrate clang with opt is.
The test case described in the question can be compiled using the following steps:
clang++ -emit-llvm -c test1.cpp test2.cpp
llvm-link -o test.bc1 test1.o test2.o
opt test.bc1 -o test.bc2 -std-compile-opts
llc -filetype=obj test.bc2 -o test.o
clang++ test.o
This produces a working a.out file.
It seems that llc is needed to convert from bitcode to machine code which can then be processed by clang as it normally would.
In general I've found that
llvm-ld x.bc y.bc
can be replaced with
llc x.bc
llc y.bc
clang x.s y.s

Cannot link LIBEVENT as C++

Why this does not work, file test.c:
#include <event.h>
int main(void)
{
event_init();
return 0;
}
Then:
gcc -o test.o -c test.c runs OK, but
Link:
g++ -o test -levent test.o produces
test.o: In function `main':
test.c:(.text+0x5): undefined reference to `event_init'
collect2: ld returned 1 exit status
So it cannot be linked as C++. How to solve this? I need to link it as C++ and compile as C.
This question has been asked many times. On Linux, you should put libraries after object and source files in the compilation command. So try
g++ -Wall -g -c mytest.cc
g++ -Wall -g mytest.o -levent -o mytest
Avoid calling your test program test which is an existing utility or shell builtin.
As a newbie, remember to always compile with all warnings asked -Wall and for debugging -g and learn to use gdb

Using exit() in c++

For one reason or another, I am messing around with the exit() function in c++. I am getting all kinds of strange errors from my mac running lion (64 bit). I am compiling using g++ -o -g -Wall.
Exhibit A:
#include <iostream>
int main(int arc, char *argv[]){
exit(1);
}
The Terminal output looks like this
$ g++ -o -g -Wall test main.cpp
ld: in test, can't link with a main executable for architecture x86_64
collect2: ld returned 1 exit status
but $ g++ -o test main.cpp compiles fine.
using #include<stdio.h> or #include<stdlib.h> result in the same compilation error.
I am just wondering if anyone might be able to see immediately what is going on here?
test is the name of the binary to produce, your first argument list should be:
> g++ -g -Wall -o test main.cpp
^^^^^^^ -o has test for an argument
-o is meant to be followed immediately by the name of the output file. It is probably trying to use your old binary 'test' as a source file, incorrectly.
Try this:
g++ -o test -g -Wall main.cpp