我想运行一个解析整个源代码树的cmake命令,所以我无法在cmake的add_custom_command / add_custom_target命令中列出所有可能的依赖项。
是否可以告诉cmake只是在没有任何条件的情况下运行命令?我尝试了在网上找到的所有解决方案(包括SO),但他们都假设该命令依赖于几个已知的最新文件。
我找到了一个解决方案,但它无法可靠地运行:
cmake_minimum_required(VERSION 2.6)
project(main)
add_custom_command(
OUTPUT file1
COMMAND echo touching file1
COMMAND touch file1
DEPENDS file2)
add_custom_target(dep ALL DEPENDS file1 file2)
# this command re-touches file2 after dep target is "built"
# and thus forces its rebuild
ADD_CUSTOM_COMMAND(TARGET dep
POST_BUILD
COMMAND echo touching file2
COMMAND touch file2
)
这是输出:
queen3@queen3-home:~/testlib$ make
[100%] Generating file1
touching file1
touching file2
[100%] Built target dep
queen3@queen3-home:~/testlib$ make
[100%] Generating file1
touching file1
touching file2
[100%] Built target dep
queen3@queen3-home:~/testlib$ make
touching file2
[100%] Built target dep
queen3@queen3-home:~/testlib$
正如你所看到的,在第三次运行时它没有生成file1,即使之前触摸过file2。有时它会在每次第二次运行时发生,有时每隔三次运行一次这是一个错误吗?有没有其他方法可以在cmake中运行没有任何依赖的命令?
奇怪但是如果我添加 TWO 命令来重新触摸file2,即只是复制粘贴后构建命令,它就可以正常工作。或者也许它会在每1000次运行失败,我还不确定; - )
答案 0 :(得分:11)
虽然我对这个解决方案一点也不满意,但是因为我偶然发现了这个页面,并且没有看到它的提及。
您可以添加引用丢失文件的自定义目标
例如:
add_custom_target(
my_custom_target_that_always_runs ALL
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/__header.h
)
add_custom_command(
OUTPUT
${CMAKE_CURRENT_BINARY_DIR}/__header.h # fake! ensure we run!
${CMAKE_CURRENT_BINARY_DIR}/header.h # real header, we write.
# this command must generate: ${CMAKE_CURRENT_BINARY_DIR}/header.h
COMMAND some_command
)
这将继续运行自定义命令,因为找不到__header.h
。
查看使用此内容的working example。
答案 1 :(得分:11)
关于ideasman42的回答是创建一个带有空回声的虚拟输出。优点是你可以有几个自定义命令取决于这个虚拟输出。
此外,cmake构建系统将知道自定义命令的输出文件是什么,以便可以正确解析对该输出的任何依赖性。
# Custom target will always cause its dependencies to be evaluated and is
# run by default
add_custom_target(dummy_target ALL
DEPENDS
custom_output
)
# custom_output will always be rebuilt because it depends on always_rebuild
add_custom_command(
OUTPUT custom_output
COMMAND command_that_produces_custom_output
DEPENDS
always_rebuild
)
# Dummy output which is never actually produced. Anything that depends on
# this will always be rebuilt.
add_custom_command(
OUTPUT always_rebuild
COMMAND cmake -E echo
)
cmake -E echo
与cmake一样接近无操作。
答案 2 :(得分:7)
我搜索完全相同,我终于找到了“notSoWorkaround”解决方案。
ADD_CUSTOM_TARGET(do_always ALL COMMAND yourCommandRegardlessOfAnyDependency)
这会添加一个将在ALL之后运行的目标。由于自定义目标始终被视为过时,因此它将始终运行。
构建
后,您可能需要DEPENDS yourA.out
才能运行
我的消息来源:
答案 3 :(得分:0)
所以这是我的解决方案。我添加了一个假库:
add_subdirectory(fake)
add_dependencies(${PROJECT_NAME} fake)
在那里我这样做:
cmake_minimum_required (VERSION 2.6)
project(fake CXX)
add_library(${PROJECT_NAME} SHARED fake.cpp)
add_custom_command(TARGET fake
POST_BUILD
COMMAND ./mycommand.sh
COMMAND rm ${ROOT_BIN_DIR}/libfake.so
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
因为你可以看到我只是在构建之后删除.so文件,这导致每次重建假lib,POST_BUILD执行,所有这些都在主PROJECT_NAME之前,因为它依赖于假。