gpt4 book ai didi

linux - 从 C 源文件生成 LLVM 位码文件的 CMakeList 文件

转载 作者:太空狗 更新时间:2023-10-29 11:40:30 24 4
gpt4 key购买 nike

我正在尝试使用 CMake 从 C 源文件 (hello.c) 生成 LLVM 字节码文件。下面是我的 CMakeLists 文件。

###### 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”

  2. 为单个 .c 文件考虑这一点。如果您能给我一些关于为完整的 C 项目生成相同内容的提示,那将非常有帮助。

最佳答案

我认为你最终想要的是能够构建一个 C 程序使用 CMake 和 clang 的项目,其中源文件被编译为 LLVM 位码并且可执行文件是从位代码文件链接的。

使用 CMake,要求 clang 链接位码文件意味着要求它链接到 LTO mode ,使用 -flto 链接选项。

并且您可以使用 -flto 编译将 clang 编译 为 LLVM 位码选项,或使用 -emit-llvm 选项。

这里是一个包含两个源文件和一个头文件的 Hello World 项目:

$ 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)

它同样适用于:

#target_compile_options(hello PUBLIC ${CMAKE_C_FLAGS} -flto)
target_compile_options(hello PUBLIC ${CMAKE_C_FLAGS} -emit-llvm)

为 CMake 创建一个构建目录并转到那里:

$ 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 文件生成:

$ egrep -r '.*\.bc'; echo Done
Done
$ find -name '*.bc'; echo Done
Done

因为编译选项 -flto-emit-llvm 导致输出文件:

CMakeFiles/hello.dir/main.c.o
CMakeFiles/hello.dir/hello.c.o

遵守通常的 CMake 命名约定但实际上不是目标文件但是一个 LLVM 位码文件,如您所见:

$ 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!

稍后

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?

你正在以一种正确的方式做事,虽然不是唯一正确的方式,但你的期望是错误的。再看看:

$ file $(find -name '*.o')
./CMakeFiles/hello.dir/hello.c.o: LLVM IR bitcode
./CMakeFiles/hello.dir/main.c.o: LLVM IR bitcode

你可以看到 .o 文件由 hello.cmain.c 组成由 CMake 生成的 makefile 不称为 hello.omain.o 而是 hello.c.omain.c.o。 CMake 更喜欢编译后的文件名来保留扩展名源文件,并附加 .o。这是一种相当普遍的做法。所以如果你想使用 makefile 编译 hello.c,最明显正确的方法是制作 hello.c.o

让我们看看实际发生了什么。在我的 CMake 构建目录中:

$ 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 是最新的。所以我会删除它并重复:

$ 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'

现在已经重新编译了。

然而,因为很多人——像你一样——希望 hello.o 被编译从 hello.c,CMake 帮助将 hello.o 定义为 .PHONY target这取决于 hello.c.o:

$ egrep  -A3 'hello.o.*:.*hello.c.o' Makefile 
hello.o: hello.c.o

.PHONY : hello.o

所以事实上我可以这样做:

$ 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'

make hello.o 是制作 hello.c.o

的另一种方法

关于linux - 从 C 源文件生成 LLVM 位码文件的 CMakeList 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54864924/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com