为什么CMake不检测对生成的文件的依赖?

时间:2016-12-01 15:28:48

标签: cmake dependencies

我正在尝试使用自定义命令生成标头。应在每次重建时更新标头,以便还可以重建包含它的源文件。 (实际命令是一个脚本,但这是一个简化版本。)

这是我的项目:

  

的CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
set(test_SOURCES test.c)
include_directories("${CMAKE_BINARY_DIR}")

set(VERSION_H_PATH "${CMAKE_BINARY_DIR}/version.h")
message("VERSION_H_PATH: ${VERSION_H_PATH}")
add_custom_command(OUTPUT "${VERSION_H_PATH}" COMMAND "touch" "${VERSION_H_PATH}")
#add_custom_target(GENERATE COMMAND "touch" "${VERSION_H_PATH}")
add_executable(myprog ${test_SOURCES})
add_dependencies(myprog GENERATE)
  

test.c的

#include <version.h>

int main()
{
    return 0;
}

现在的问题是CMakeList.txt如上所述,根本不会导致version.h被创建。只有在我从add_custom_target切换到add_custom_command后才会这样做。但是,如果我以某种方式更改文件,则下一个make不会重建项目。

看起来CMake无法识别test.c取决于version.h,尽管明确#include它。我在这里做错了什么?

4 个答案:

答案 0 :(得分:2)

变化:

add_custom_command(OUTPUT "${VERSION_H_PATH}" COMMAND "touch" "${VERSION_H_PATH}")
#add_custom_target(GENERATE COMMAND "touch" "${VERSION_H_PATH}")
add_executable(myprog ${test_SOURCES})
add_dependencies(myprog GENERATE)

分为:

add_custom_command(OUTPUT "${VERSION_H_PATH}" COMMAND ${CMAKE_COMMAND} -E touch "${VERSION_H_PATH}") #More reliable touch, use cmake itself to touch the file
add_custom_target(generate_version_h DEPENDS "${VERSION_H_PATH}")
add_executable(myprog ${test_SOURCES})
add_dependencies(myprog generate_version_h)

请参阅:

  1. CMake command line tool mode
  2. add_custom_target
  3.   

    依赖:

         

    使用add_custom_command()命令调用在同一目录(CMakeLists.txt文件)中创建的自定义命令的参考文件和输出。 在构建目标时,它们会被更新。

    1. add_dependencies
    2.   

      使顶级依赖于其他顶级目标,以确保它们之前构建。顶级目标是由add_executable(),add_library()或 add_custom_target()命令之一创建的目标(但不是由CMake生成的目标,如安装)。

      顺便说一句,我不知道您的具体情况,但您可以考虑使用configure_file来生成标题。

答案 1 :(得分:1)

问题似乎是用于可执行目标的名称test是CMake保留的名称。请参阅政策CMP0037。对可执行文件使用不同的名称似乎与自定义目标一样正常工作:

add_custom_target(GENERATE COMMAND "touch" "${VERSION_H_PATH}")
add_executable(testexe ${test_SOURCES})
add_dependencies(testexe GENERATE)

答案 2 :(得分:0)

每个自定义命令都需要一个驱动程序(取决于其输出的东西)。在您的情况下,最好的驱动程序是test可执行文件,这意味着您应该将生成的文件添加到可执行文件的源中:

add_executable(test ${test_SOURCES} ${VERSION_H_PATH})

答案 3 :(得分:-1)

好的,实际上这个问题从一开始就很糟糕。我不应该像我一样简化生成命令。但是我似乎已经通过删除构建目录的内容并重新运行cmake 解决了我遇到的问题。出于某种原因,CMakeLists.txt的某些更改对于cmake来说并不容易理解。所以这里的CMakeLists.txt确实有效,并且没有太多简化的生成器命令:

cmake_minimum_required(VERSION 2.8)
set(test_SOURCES test.c)
include_directories("${CMAKE_BINARY_DIR}")

set(VERSION_H_PATH "${CMAKE_BINARY_DIR}/version.h")
message("VERSION_H_PATH: ${VERSION_H_PATH}")
add_custom_target(GENERATE COMMAND "bash" "-c" "[ -e ${VERSION_H_PATH} ] \\|\\| touch ${VERSION_H_PATH}")
add_executable(myprog ${test_SOURCES})
add_dependencies(myprog GENERATE)

即使使用保留的test目标而不是myprog,这似乎也能正常工作。