Cmake 如何在构建时始终运行命令,而不考虑任何依赖关系?
我想运行一个解析整个源代码树的cmake命令,因此我无法在cmake的add_custom_命令/add_custom_目标命令中列出所有可能的依赖项 有没有可能让cmake在没有任何条件的情况下运行命令?我尝试了在网络上找到的所有解决方案(包括SO),但它们都假设该命令依赖于少数已知的最新文件 我找到了一个解决方案,但它不能可靠地工作:Cmake 如何在构建时始终运行命令,而不考虑任何依赖关系?,cmake,Cmake,我想运行一个解析整个源代码树的cmake命令,因此我无法在cmake的add_custom_命令/add_custom_目标命令中列出所有可能的依赖项 有没有可能让cmake在没有任何条件的情况下运行命令?我尝试了在网络上找到的所有解决方案(包括SO),但它们都假设该命令依赖于少数已知的最新文件 我找到了一个解决方案,但它不能可靠地工作: cmake_minimum_required(VERSION 2.6) project(main) add_custom_command( OUTP
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。有时每跑2次,有时每跑3次,有时每跑4次。是虫子吗?在cmake中是否有其他方法可以运行没有任何依赖关系的命令
奇怪的是,如果我添加两个命令来重新接触file2,即只复制粘贴后期生成命令,它会可靠地工作。或者可能每跑1000次就会失败,我还不确定;-) 这是我的解决方案。我添加了一个假库:
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文件,这会导致每次都重建假库,并执行POST_build,所有这些都在主项目名称之前,因为它依赖于fake。虽然我对这个解决方案一点也不满意,但因为我无意中发现了这个页面,并且没有看到提到它,所以发布了 您可以添加引用丢失文件的自定义目标 例如: 这将继续运行自定义命令,因为找不到
\uu header.h
请参阅使用此语句的地方。ideasman42答案的一个转折点是创建一个带有空echo语句的虚拟输出。优点是您可以有多个自定义命令依赖于此虚拟输出 此外,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一样接近于无操作。我搜索了完全相同的结果,最终找到了一个“notSoWorkaround”解决方案
ADD_CUSTOM_TARGET(do_always ALL COMMAND yourCommandRegardlessOfAnyDependency)
这将添加一个最终将运行的目标。由于自定义目标始终被视为过时,因此它将始终运行
您可能需要依赖于a.out
,以便在生成后运行
我的资料来源:
create\u ad
指的是什么?互联网似乎不知道this@sehe名称并不重要,还链接到使用此名称的工作示例。酷。我只是感到困惑:)这个名字似乎很神奇,就像CMake语法中的许多东西一样。我必须承认,我开始越来越喜欢CMake了,但是做一些简单的事情是很难的。我发现其中的一个问题是,出于某种被上帝抛弃的原因,CMake会更新生成文件上的LM时间戳(如果生成了一些文件)。如果你不想在某些情况下修改它,它会抛出构建。具体取决于你正在做什么-一种解决方法是在临时位置生成一个文件,并且只在它们不同时复制它。(不太好,但比缓慢的构建时间要好!)不幸的是,只有在实际构建ALL
目标时(即,您没有明确设置目标),这才有效。如果您执行类似于使我的目标成为其他目标的操作,它将不会运行。虽然,公平地说,就我所能看到的所有其他答案都是如此,所以这绝对是最简单的。catkin build(它构建了CMake all目标)为我提供了极好的帮助。其他一切都失败了。如果我需要生成一个特定的文件(自动生成),这个解决方案将不起作用,而这个文件又将在项目中使用。@TarmoPikaro为什么不呢?此解决方案的目的是允许生成项目其他部分可以依赖的特定文件。我的解决方案中特定文件的名称为“custom_output”。我可能没有说清楚,或者你遇到了不同的问题?
ADD_CUSTOM_TARGET(do_always ALL COMMAND yourCommandRegardlessOfAnyDependency)