Cmake和gcc的结合

8

我有许多源文件在源目录中。例如a.c,b.c,c.c,并希望使用gcc和-combine选项进行编译。

set(CMAKE_C_FLAGS "-combine")
set(SRC a.c b.c c.c)
add_executable(a.out ${SRC})

CMake会将每个*.c文件编译为目标文件,但我想将所有源代码编译为一个目标文件。我该如何实现?
就gcc而言:
gcc -combine a.c b.c c.c -o module.o
ar rcs library.a module.o

但是CMake使用逐模块的源代码翻译。
gcc a.c -o a.o
gcc b.c -o b.o
gcc c.c -o c.o
ar rcs library.a a.o b.o c.o

结合使用转换可以加速程序的性能。由于gcc版本过旧,我无法在cmake中使用LTO来解决相同的问题。

谢谢。


你确定存在一个选项 -combine 吗?我有一种感觉,这可能不是你想要做的。也许你指的是 -fwhole-program,它在道义上等同于将所有源文件连接在一起。但更有可能的是你只是想创建一个可重用的库。使用 -shared 来创建一个动态库,或者使用 ar 程序将大量的 .o 文件组合成一个静态库。CMake 可以为你自动化这两个过程。 - Kerrek SB
2
是的,我确定。这个选项存在于gcc版本4.4/4.5中。 - Igor Petushkov
有趣的是,在4.6版本中它消失了!:-) 它的目的是什么?你不能用“-fwhole-program”实现它吗? - Kerrek SB
2
是的,4.6版本没有-combine选项,但我们团队使用gcc-4.3和4.4。与combine一样,-fwhole-program也有同样的问题,因为它需要将所有源文件编译成一个编译单元以创建1个目标文件。 - Igor Petushkov
我也想知道答案。目前我使用的是自定义的Makefile系统,而不是CMake,但我想切换到CMake。但是通过模块间优化实现的性能比CMake更重要。 - Zan Lynx
显示剩余2条评论
1个回答

1
使用add_custom_target/add_custom_command命令。
这是非可移植结构,下面是一个简单的例子:
[项目根目录] 包含两个文件夹 [src] - 这里是 N 个文件,[build] 用于二进制文件,以及 CMakeLists.txt 文件。
cmake_minimum_required(VERSION 2.6.0 FATAL_ERROR)
set(TARGET_NAME whole)
project(${TARGET_NAME} C)

file(GLOB SRC_FILES src/*.c)

add_custom_target(${TARGET_NAME} ${CMAKE_C_COMPILER} -flto -fwhole-program ${SRC_FILES} -o ${TARGET_NAME})

在构建文件夹中运行 cmake ..; make VERBOSE=1 whole 这将为您完成工作。
但是,根据文档,-fwhole-program仅适用于可执行文件。
-fwhole-program假定当前编译单元代表正在编译的整个程序。除了main和由属性externally_visible合并的所有公共函数和变量之外,所有公共函数和变量都成为静态函数,并且实际上通过过程间优化器进行更积极的优化。
因此,您必须在源文件中的任何位置定义main。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接