CMake - 不必要地构建两次对象?

Posted

技术标签:

【中文标题】CMake - 不必要地构建两次对象?【英文标题】:CMake - objects being built twice unnecessarily? 【发布时间】:2017-09-26 12:24:04 【问题描述】:

我有一个需要为我的主要可执行文件编译的文件列表。我的测试也需要这些文件。构建测试可执行文件时,会再次构建目标文件,即使在构建的早期,它们是在构建主可执行文件时构建的。

我认为这不是必需的,我错了吗?如果是这样,有没有办法禁用它?

例子:

set(SOURCES
$SOURCE_DIR/file.c
$SOURCE_DIR/another_file.c)

set(MAIN $SOURCE_DIR/main.c)

add_executable(main_executable $SOURCES $MAIN)

add_executable(test1_ex $PROJECT_SOURCE_DIR/test/test1.cc $SOURCES)

【问题讨论】:

你能发布你的makefile的相关部分吗? 如果您为多个目标列出相同的源文件,它将为每个目标构建一次 CMake 将构建它们两次,因为您的主可执行文件和测试可执行文件可能有不同的编译器标志。您可以通过首先将它们编译到一个库,然后将该库链接到您的两个可执行文件来避免这种情况。 @HansPetterTaugbølKragset 将示例添加到帖子 构建应用程序库。将测试可执行文件和您的 main.cpp 与应用程序库链接。 【参考方案1】:

将通用代码放入库中,并将库链接到您的应用程序和测试。

# The application's sources - except main
set(SOURCES
        $SOURCE_DIR/file.c
        $SOURCE_DIR/another_file.c)

# build an application library
add_library(app_lib $SOURCES)

# build an executable in terms of the application library
set(MAIN $SOURCE_DIR/main.c)
add_executable(main_executable $MAIN)
target_link_libraries(main_executable PRIVATE app_lib)

# build a test executable in terms of the application library
add_executable(test1_ex $PROJECT_SOURCE_DIR/test/test1.cc)
target_link_libraries(test1_ex PRIVATE app_lib)

【讨论】:

【参考方案2】:

这可能是由于以下情况:

add_library(mylib1 file1.cpp common.cpp)
add_library(mylib2 file2.cpp common.cpp)

这给我带来了同样的问题,common.cpp 正在为每个库重建。我的解决方案是这样的:

add_library(common_lib common.cpp)
add_library(mylib1 file1.cpp)
add_library(mylib2 file2.cpp)
target_link_libraries(mylib1 common_lib)
target_link_libraries(mylib2 common_lib)

这解决了我的问题,因为构建(对象创建)只完成了一次,但它已链接到所有其他库。

【讨论】:

以上是关于CMake - 不必要地构建两次对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何告诉 cmake 在哪里输出其构建数据?

使用外部附加头文件构建 cmake 对象库

不必要地将函数标记为暂停以支持通用抽象

Firestore 和 SwiftUI - 我的快照阅读器是不是不必要地读取数据库?

不必要地实现 Serializable 的惩罚是啥?

值不必要地四舍五入