I am working on creating a single llvm ir file for the open source software ardupilot. They use a build system called waf, so I edited the wscript and changed g++ to clang++ and gcc to clang. I then added flags to emit ir llvm. This successfully goes through each file, creates the ir code and stores it in a .o file. I changed all the extensions to be .ll and then attempted to use llvm-link -S … to link the files into one ir file.
It is worth mentioning that ArduPilot consists of subprojects such as ArduCopter and ArduPlane etc. You can compile any of these projects individually for different systems such as a quadcopter or rc plane (where ArduCopter is for the quadcopter and ArduPlane is for fixed wing aircrafts). The project structure also has a bunch of libraries that are used by the main code for whatever you are compiling, be it ArduCopter or ArduPlane. (See below for a glimpse at the structure. Of particular note is ArduCopter and the libraries folder.)
I am personally working with ArduCopter. After running the build script, I get the ir files for the main ArduCopter code and the libraries.
However, when I use llvm-link -S folder_with_ir_files/*.ll -o file_name.ll
, I get the following: “error: Linking globals named 'main': symbol multiply defined!
”
This is probably due to the fact that the libraries each have a main function leading to the symbol conflict.
If I try to resolve this issue by adding the flag --only-needed
, all references to library functions get removed and instead simply a definition for the library class name appears. For example, references to a function selectHeightForFusion
are removed and a define for AP_NavEKF3_PosVelFusion.cpp
appears.
Ex. The function name is not found in the output ir file, but a reference to the class is.
define internal void @_GLOBAL__sub_I_AP_NavEKF3_PosVelFusion.cpp() #6 section ".text.startup" {
I instead tried using the flag --internalize
to solve this problem. It seems to work where the references are now to the library functions themselves instead of the file, but it does not feel like the best way to go about solving this issue. (See below.)
Ex. These appear in the output ir file when searching for the function name.
call void @_ZN12NavEKF3_core21selectHeightForFusionEv(%class.NavEKF3_core.8709* %this1)
define internal void @_ZN12NavEKF3_core21selectHeightForFusionEv(%class.NavEKF3_core.8709* %this) #0 align 2 {
Ultimately, I wanted to get any feedback I could on the proper way to link multiple ir files in a project that uses libraries with multiple mains while not losing any ir code from the libraries.
It is also likely that I simply do not understand the process of linking these files and perhaps there is a reason for the references to selectHeightForFusion
to be removed when using --only-needed
.
Any guidance would be much appreciated.