如何解决cmake add_custom_command 引入了错误的依赖,除非还使用了 add_custom_target
我正在使用 cmake 构建一些库,所有这些库都生成了它们的一些文件。
我已经使用 add_custom_command() 创建了生成的文件,但我发现了一些似乎是错误依赖的东西。如果下游库具有生成的文件并链接到上游库,则在上游库完全构建之前,下游库源不会开始编译。由于我的项目中有许多库(超过 50 个),这种错误的依赖会导致构建中的序列化。
奇怪的是,我还注意到,如果生成文件的显式 add_custom_target() 与 add_dependencies() 一起使用,则虚假依赖不再存在,下游库中的文件将与上游图书馆。所以我有一个解决方法,但这是预期的行为吗?
使用 Cmake 1.19,Ninja 1.10.2。
以下是显示发生了什么的最小 CMakeLists.txt 文件。 WORKS 选项有条件地添加 add_custom_target() 和 add_dependencies() 子句,使其工作(快速)。文件 foo.c 和 bar.c 是空的,我在 CMakeLists.txt 目录的子目录中构建。
我放置了一个名为 /tmp/x 的文件,它是 cc 的包装器,它休眠以显示序列化发生:
#!/bin/bash -e
echo "mycc" $(date)
sleep 4
exec /usr/bin/cc $*
这是 CMakeLists.txt:
cmake_minimum_required(VERSION 3.19)
project(test)
option(WORKS "false dependency gone if WORKS set to ON" OFF)
add_library(foo
foo.c
)
add_library(bar
bar.c
bargen.h
)
target_include_directories(bar PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
add_custom_command(OUTPUT bargen.h
COMMAND touch bargen.h
)
if (${WORKS})
add_custom_target(generate_file
DEPENDS bargen.h
)
add_dependencies(bar generate_file)
endif()
target_link_libraries(bar PUBLIC foo)
像这样构建,您将看到序列化:bar.c 将在 foo.c 编译完成后才开始编译(实际上,直到 foo 库构建完成后才会开始编译)。 (我明确选择了“-j 4”以确保 Ninja 会尝试并行构建)。
cmake -DWORKS=OFF -G Ninja -DCMAKE_C_COMPILER=/tmp/x .. && ninja clean && ninja -j 4 -v | grep mycc
这显示了以下输出:
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/rhb/Downloads/cmake-anomaly/build
[1/1] Cleaning all built files...
Cleaning... 5 files.
mycc Sat Jan 2 15:15:25 EST 2021
mycc Sat Jan 2 15:15:29 EST 2021
现在像这样构建它,你会看到 bar.c 与 foo.c 同时编译:
cmake -DWORKS=ON -G Ninja -DCMAKE_C_COMPILER=/tmp/x .. && ninja clean && ninja -j 4 -v | grep mycc
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/rhb/Downloads/cmake-anomaly/build
[1/1] Cleaning all built files...
Cleaning... 5 files.
mycc Sat Jan 2 15:15:37 EST 2021
mycc Sat Jan 2 15:15:37 EST 2021
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。