CMakeList文件从C源文件生成LLVM位代码文件 [英] CMakeList file to generate LLVM bitcode file from C source file
问题描述
我正在尝试使用CMake从C源文件(hello.c)生成LLVM字节码文件.下面是我的CMakeLists文件.
I am trying to generate LLVM bytecode file from a C source file (hello.c) using CMake. And below is my CMakeLists file.
###### CMakelists.txt ############
cmake_minimum_required(VERSION 2.8.9)
set(CMAKE_C_COMPILER "clang")
set(CMAKE_C_FLAGS "-emit-llvm")
project (hello)
add_executable(hello hello.c)
-
我是CMake的新手,不确定这是否正确.我在生成的MakeFile中找不到任何使* .bc的规则.请在这里纠正我.我也尝试过"-save-temps"
I am new to CMake and not sure if this is the right way. I could not find any rules to make *.bc in the generated MakeFile . Please correct me here. I also tried "-save-temps"
将其视为单个.c文件.如果您能给我一些有关为完整的C项目生成相同内容的提示,那将真的很有帮助.
Considering this for a single .c file. It would be really helpful if you could give me some hints on generating the same for a complete C project.
推荐答案
我认为您最终想要的是能够构建C程序CMake和clang的项目,其中源文件被编译为LLVM位码并且可执行文件是从位码文件链接的.
I think what you ultimately want is to be able to build a C-program project with CMake and clang in which source files are compiled to LLVM bitcode and the executable is linked from the bitcode files.
对于CMake,要求clang链接位代码文件意味着要求其链接 LTO模式,使用 -flto
链接选项.
With CMake, asking clang to to link bitcode files means asking it to link in LTO mode,
with the -flto
linkage option.
您可以使用 -flto
编译使clang进行 compile 到LLVM位代码选项,或使用 -emit-llvm
选项.
And you can get clang to compile to LLVM bitcode with the -flto
compilation
option, or with the -emit-llvm
option.
为说明起见,这里是一个Hello World项目,其中包含两个源文件和一个标头:
For illustration here is a Hello World project comprising two source files and one header:
$ ls -R
.:
CMakeLists.txt hello.c hello.h main.c
这是:
CMakeLists.txt
cmake_minimum_required(VERSION 3.0.2)
project (hello)
set(CMAKE_C_COMPILER clang)
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} "-flto")
add_executable(hello main.c hello.c)
target_compile_options(hello PUBLIC ${CMAKE_C_FLAGS} -flto)
#target_compile_options(hello PUBLIC ${CMAKE_C_FLAGS} -emit-llvm)
它在以下情况下也能很好地工作:
It will work equally well with:
#target_compile_options(hello PUBLIC ${CMAKE_C_FLAGS} -flto)
target_compile_options(hello PUBLIC ${CMAKE_C_FLAGS} -emit-llvm)
为CMake创建构建目录,然后转到那里:
Make a build directory for CMake and go there:
$ mkdir build
$ cd build
生成构建系统:
$ cmake ..
内部版本:
$ make
Scanning dependencies of target hello
[ 33%] Building C object CMakeFiles/hello.dir/main.c.o
[ 66%] Building C object CMakeFiles/hello.dir/hello.c.o
[100%] Linking C executable hello
[100%] Built target hello
在Makefile文件中找不到任何 *.bc
目标,也没有任何 *.bc
文件生成:
You will not find any *.bc
targets in the Makefiles, nor any *.bc
files
generated:
$ egrep -r '.*\.bc'; echo Done
Done
$ find -name '*.bc'; echo Done
Done
因为编译选项 -flto
或 -emit-llvm
会导致输出文件:
because the compilation option -flto
or -emit-llvm
results in an output
file:
CMakeFiles/hello.dir/main.c.o
CMakeFiles/hello.dir/hello.c.o
符合通常的CMake命名约定,但实际上不是目标文件但您看到的是LLVM位代码文件:
that adheres to the usual CMake naming convention but is in fact not an object file but an LLVM bitcode file, as you see:
$ file $(find -name '*.o')
./CMakeFiles/hello.dir/hello.c.o: LLVM IR bitcode
./CMakeFiles/hello.dir/main.c.o: LLVM IR bitcode
程序执行常规操作:
$ ./hello
Hello World!
稍后
当我尝试"make hello.o"时,它应该生成目标文件吗?cmd执行成功,但是找不到生成的目标文件.我做对了吗?
When I try " make hello.o " it should generate the object file right? the cmd executes successfully but, could not find the generated object file. Am I doing it right?
您正在以一种正确的方式进行操作,尽管这不是唯一正确的方式,但是您的期望是错误的.再看一下:
You are doing it in one way that is right, though not the only way that is right, but your expectations are wrong. Look again at:
$ file $(find -name '*.o')
./CMakeFiles/hello.dir/hello.c.o: LLVM IR bitcode
./CMakeFiles/hello.dir/main.c.o: LLVM IR bitcode
您可以在那里看到由 hello.c
和 main.c
制成的 .o
文件由CMake生成的makefile所生成的文件不是 hello.o
和 main.o
,而是 hello.c.o
和 main.c.o
.CMake更喜欢使用编译后的文件名来保留扩展名.源文件,并附加 .o
.这是相当普遍的做法.所以如果你想使用makefile来编译 hello.c
,最明显的正确方法是制作hello.c.o
.
You can see there that the .o
files that are made from hello.c
and main.c
by the CMake-generated makefile are not called hello.o
and main.o
but hello.c.o
and main.c.o
. CMake prefers a compiled filename to preserve the extension of the
source file, and append .o
. That is a fairly common practice. So if you wanted
to use the makefile to compile hello.c
, the most obviously right way would be
make hello.c.o
.
让我们看看实际发生了什么.在我的CMake构建目录中:
Let's see what actually happens. In my CMake build directory:
$ make VERBOSE=1 hello.c.o
make -f CMakeFiles/hello.dir/build.make CMakeFiles/hello.dir/hello.c.o
make[1]: Entering directory '/home/imk/develop/so/scrap/build'
make[1]: 'CMakeFiles/hello.dir/hello.c.o' is up to date.
make[1]: Leaving directory '/home/imk/develop/so/scrap/build'
没有什么可做的,因为我的 hello.c.o
是最新的.所以我会删除并重复:
There was nothing to be done, because my hello.c.o
was up to date. So I'll
delete it and repeat:
$ rm CMakeFiles/hello.dir/hello.c.o
$ make VERBOSE=1 hello.c.o
make -f CMakeFiles/hello.dir/build.make CMakeFiles/hello.dir/hello.c.o
make[1]: Entering directory '/home/imk/develop/so/scrap/build'
Building C object CMakeFiles/hello.dir/hello.c.o
clang -flto -o CMakeFiles/hello.dir/hello.c.o -c /home/imk/develop/so/scrap/hello.c
make[1]: Leaving directory '/home/imk/develop/so/scrap/build'
现在,它已经重新编译.
Now it has been recompiled.
但是,因为很多人-像您一样-希望 hello.o
能够被编译来自 hello.c
的CMake有助于将 hello.o
定义为
However, because many people - like you - would expect hello.o
to be compiled
from hello.c
, CMake helpfully defines hello.o
as a .PHONY
target
that depends on hello.c.o
:
$ egrep -A3 'hello.o.*:.*hello.c.o' Makefile
hello.o: hello.c.o
.PHONY : hello.o
实际上,我可以这样做:
So in fact I can do:
$ rm CMakeFiles/hello.dir/hello.c.o
$ make VERBOSE=1 hello.o
make -f CMakeFiles/hello.dir/build.make CMakeFiles/hello.dir/hello.c.o
make[1]: Entering directory '/home/imk/develop/so/scrap/build'
Building C object CMakeFiles/hello.dir/hello.c.o
clang -flto -o CMakeFiles/hello.dir/hello.c.o -c /home/imk/develop/so/scrap/hello.c
make[1]: Leaving directory '/home/imk/develop/so/scrap/build'
制作hello.o
是制作 hello.c.o
这篇关于CMakeList文件从C源文件生成LLVM位代码文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!