CMakeList文件从C源文件生成LLVM位代码文件 [英] CMakeList file to generate LLVM bitcode file from C source file

查看:79
本文介绍了CMakeList文件从C源文件生成LLVM位代码文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用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)

  1. 我是CMake的新手,不确定这是否正确.我在生成的MakeFile中找不到任何使* .bc的规则.请在这里纠正我.我也尝试过"-save-temps"

  1. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆