I am successfully compiling, using clang, from source code to IR bitcode and generating a static library. The problem I need to solve is that the IR refers to external global variables in their library internal global name. I need to modify these internal global names to the external global name. For example, in libc.a, in LLVM format:
@atoi = alias i32 (i8*), i32 (i8*)* @__GI_atoi
define hidden i32 @__GI_atoi(i8* nonnull) #0 {
...
%4 call i64 @__GI_strtol(i8* %3, i8** null, i32 10) #2
...
}
declare hidden i64 @__GI_strtol(i8*, i8**, i32) #1
The __GI_strtol
is external to the atoi
module, but is internal to the libc.a
archive. The strtol
module has a @strtol = alias ... @__GI_strtol
definition and a hidden
function called GI_strtol
.
What I need to do is when compiling the source files (atoi.c
in the above example), I need to do the following:
.ll
(LLVM) format.declare hidden
s that do not have an associated alias
statement, to their external global value (basically, hidden
--> dso_local
and __GI_*
to just *
)..ll
file to its IR bitcode (.bc
) equivalent..bc
file into the libc.a
archive.Is this possible?
I have a number of add_custom_target
s and add_custom_command
s in the CMake file, but none when compiling from .c
to .bc
.
If this were a make
build, I'd simply add definitions to compile from .c
to .ll
and .ll
to .bc
, and in the last stage perform the changes indicated above.
I expect to be able to perform the above steps in the most efficient way possible using CMake. I'd like to be able to do it without having to have, literally, 1000s of add_custom_command/target
s.
I could not find a way to be able to do the conversion as part of the compilation. So, I used add_custom_command
with a POST_LINK
on the archive itself. Then I process each entry in the archive, doing the required conversion, and then updating the archive.
It is a sort of get a bigger hammer
solution, but it works and does not add 100s of custom targets.