Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cmake 如何在构建时始终运行命令,而不考虑任何依赖关系?_Cmake - Fatal编程技术网

Cmake 如何在构建时始终运行命令,而不考虑任何依赖关系?

Cmake 如何在构建时始终运行命令,而不考虑任何依赖关系?,cmake,Cmake,我想运行一个解析整个源代码树的cmake命令,因此我无法在cmake的add_custom_命令/add_custom_目标命令中列出所有可能的依赖项 有没有可能让cmake在没有任何条件的情况下运行命令?我尝试了在网络上找到的所有解决方案(包括SO),但它们都假设该命令依赖于少数已知的最新文件 我找到了一个解决方案,但它不能可靠地工作: cmake_minimum_required(VERSION 2.6) project(main) add_custom_command( OUTP

我想运行一个解析整个源代码树的cmake命令,因此我无法在cmake的add_custom_命令/add_custom_目标命令中列出所有可能的依赖项

有没有可能让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。有时每跑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
,以便在生成后运行

我的资料来源:


此解决方案仅适用于unix平台。您可以使用cmake-E使其独立于平台,但这涉及到创建一个不必要的伪库。有关不涉及创建任何文件的解决方案,请参阅ideasman42的答案。
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)