How to replace llvm-ld with clang? - llvm

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

Related

Clang compilation : "Cannot execute binary file"

I am new to the clang++ compiler flags. I have an issue regarding compilation. Here is my cmd:
clang++ -I ../llvm-project/llvm/include -I ../llvm-project/clang/include
-I ../llvm-project/build/tools/clang/include -I ../llvm-project/build/include
-O3 -c $(llvm-config-7 --cxxflags)
projectToTestHeadersBuilding.cpp -o projectToTestHeadersBuilding
I am getting error:
./projectToTestHeadersBuilding: cannot execute binary file: Exec format error
After execution I have projectToTestHeadersBuilding file. But I can not run executable. Can you please help me to understand how to get executable, so I can run it using ./projectToTestHeadersBuilding ?
In your initial command you use the -c flag which makes clang output an object file. This is part of a compiled program but not a complete executable, in order to get the final executable you must perform a linking step, usually with other object files.
A simple compilation can be done as so:
clang++ projectToTestHeadersBuilding.cpp -c -o projectToTestHeadersBuilding.o
clang++ projectToTestHeadersBuilding.o -o projectToTestHeadersBuilding
./projectToTestHeadersBuilding
Generally we do not need to explicitly pass all those -I flags you have passed. If they are needed with your setup, add them to the commands I've included above.

LLVM C++ Program Compilation

Hi I have written a simple C++ code with the LLVM Api
#include <stdio.h>
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/IRBuilder.h"
int main()
{
llvm::LLVMContext& context = llvm::getGlobalContext();
llvm::Module* module = new llvm::Module("top", context);
llvm::IRBuilder<> builder(context);
module->dump( );
}
How do i compile this to get the LLVM IR file?
Thanks for any help
Compilation of the program itself to a native machine code binary is straightforward. On a Unix platform:
$ clang++ <c++ file> `llvm-config --cppflags --ldflags --libs core`
llvm-config is a tool providing the necessary compilation flags to include certain components of the llvm framework. In your case, it seems you only need the core component.
Adding the -v parameter to the command line requires clang to output all the used commands. Adding -S -emit-llvm (both parameters must be used together) will make it output an llvm IR translation of the source
$ clang++ -v file.cpp `llvm-config --cppflags --ldflags --libs core` -S -emit-llvm
The resulting file.s may be then directly interpreted with lli or further compiled to bitcode using llvm-as, which renders a .bc file.
$ llvm-as file.s
The same lli will gladly run that file as well:
$ lli file.s.bc
Running or interpreting any of these resulting files (llvm IR, bitcode or native program), will of course yield the same result, the dumping of the llvm IR code of the module top defined in your program (which is empty).
Documentation:
llvm-config
llvm-as
lli
The easiest thing to do is to forward the output into a file and then process that so something like this(assuming the compiled code above is compiled into an executable name 'parser'):
./parser >> test.ll
llvm-as test.ll
llc test.bc
clang -o test test.s
Hopefully that helps!
As a side note I have my parser to this internally via system() calls and command line options, so that may be something you want to think about as well^^

Unable to link PAPI library with opt llvm

I am working on a project where I need to generate just the bitcode using clang, run some optimization passes using opt and then create an executable and measure its hardware counters.
I am able to link through clang directly using:
clang -g -O0 -w -I/opt/apps/papi/5.3.0/include -Wl,-rpath,$PAPI_LIB -L$PAPI_LIB \
-lpapi /scratch/02681/user/papi_helper.c prog.c -o a.out
However now I want to link it after using the front end of clang and applying optimization passes using opt.
I am trying the following way:
clang -g -O0 -w -c -emit-llvm -I/opt/apps/papi/5.3.0/include -Wl,-rpath,$PAPI_LIB -L$PAPI_LIB \
-lpapi /scratch/02681/user/papi_helper.c prog.c -o prog.o
llvm-link prog.o papi_helper.o -o prog-link.o
// run optimization passes
opt -licm prog-link.o -o prog-opt.o
llc -filetype=obj prog-opt.o -o prog-exec.o
clang prog-exec.o
After going through the above process I get the following error:
undefined reference to `PAPI_event_code_to_name'
It's not able to resolve papi functions. Thanks in advance for any help.
Clearly, you need to add -lpapi to the last clang invocation. How else the linker would know about libpapi?

How do I compile C++ with Clang?

I have installed Clang by using apt-get in Ubuntu, and I can successfully compile C files using it. However, I have no idea how to compile C++ through it. What do I need to do to compile C++?
The command clang is for C, and the command clang++ is for C++.
I do not know why there is no answer directly addressing the problem. When you want to compile C++ program, it is best to use clang++, instead of using clang. For example, the following works for me:
clang++ -Wall -std=c++11 test.cc -o test
If compiled correctly, it will produce the executable file test, and you can run the file by using ./test.
Or you can just use clang++ test.cc to compile the program. It will produce a default executable file named a.out. Use ./a.out to run the file.
The whole process is a lot like g++ if you are familiar with g++. See this
post to check which warnings are included with -Wall option. This
page shows a list of diagnostic flags supported by Clang.
A note on using clang -x c++: Kim Gräsman says that you can also use
clang -x c++ to compile CPP programs, but that may not be always viable. For example, I am having a simple program below:
#include <iostream>
#include <vector>
int main() {
/* std::vector<int> v = {1, 2, 3, 4, 5}; */
std::vector<int> v(10, 5);
int sum = 0;
for (int i = 0; i < v.size(); i++){
sum += v[i]*2;
}
std::cout << "sum is " << sum << std::endl;
return 0;
}
clang++ test.cc -o test will compile successfully, but clang -x c++ will
not, showing a lot of undefined reference errors. So I guess they are not exactly equivalent. It is best to use clang++ instead of clang -x c++ when compiling c++ programs to avoid extra troubles.
clang version: 11.0.0
Platform: Ubuntu 16.04
Also, for posterity -- Clang (like GCC) accepts the -x switch to set the language of the input files, for example,
$ clang -x c++ some_random_file.txt
This mailing list thread explains the difference between clang and clang++ well: Difference between clang and clang++
Solution 1:
clang++ your.cpp
Solution 2:
clang your.cpp -lstdc++
Solution 3:
clang -x c++ your.cpp
I've had a similar problem when building Clang from source (but not with sudo apt-get install. This might depend on the version of Ubuntu which you're running).
It might be worth checking if clang++ can find the correct locations of your C++ libraries:
Compare the results of g++ -v <filename.cpp> and clang++ -v <filename.cpp>, under "#include < ... > search starts here:".
Open a Terminal window and navigate to your project directory. Run these sets of commands, depending on which compiler you have installed:
To compile multiple C++ files using clang++:
$ clang++ *.cpp
$ ./a.out
To compile multiple C++ files using g++:
$ g++ -c *.cpp
$ g++ -o temp.exe *.o
$ ./temp.exe

C++ programs, compiling with g++

I am very aware of compiling C++ programs with g++ in linux environment. But, may be I am missing something, I am getting this strange output/behaviour.
I have source file in test.cpp.
To compile this, I did
(1)
g++ -c test.cpp
g++ -o test test.o
./test
Everything works fine.
But when I did compling and linking in same stage, like this
(2)
g++ test.cpp -o test
./test => Works fine
(3)
g++ -c test.cpp -o test => Doesn't work
In my last case, test is generated but is no more executable; but in my guess it should work fine.
So, what is wrong or do I need to change some settings/configuration ??
I am using g++ 4.3.3
Thanks.
When you say:
g++ -c test.cpp -o test
The -c flag inhibits linking, so no executable is produced - you are renaming the .o file.
Basically, don't do that.
You are forcing compiler to produce an object file and name it like an executable.
Essentially your last line tells: compile this to an object file, but name it test, instead of test.obj.
-c flag means Compile Only
Try
g++ -o test test.cpp
Specifying -o in the g++ command line tells the compiler what name to give the output file. When you tried to do it all in one line, you just told the compiler to compile test.cpp as an object file named test, and no linking was done.
Have a look at the fabulous online manual for GCC for more details.
from the gcc manual:
-c Compile or assemble the source files, but do not link. The linking
stage simply is not done. The ultimate output is in the form of an
object file for each source file.
You must link the compiled object files to get the executable file.
More info about compiling and linking and stuff is here.
Read man g++. The switch -c is to compile only but not to link.
g++ -c test.cpp -o test
does what
g++ -c test.cpp
does but the object file will be test istead of the default name test.o. An object file cannot be executed.