Why doesn't CMake detect dependency on my generated file?

Rus*_*lan 3 dependencies cmake

I'm trying to generate a header with a custom command. The header should be updated on each rebuild, so that the source file which includes it would also be rebuilt. (Actual command is a script, but here is a simplified version.)

Here's my project:

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)
Run Code Online (Sandbox Code Playgroud)

test.c

#include <version.h>

int main()
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Now the problem is that the CMakeList.txt, as presented above, doesn't result in version.h being created at all. Only after I switch from add_custom_target to add_custom_command does it do. But then, if I change the file somehow, next make doesn't rebuild the project.

Looks like CMake doesn't recognize that test.c depends on version.h, although it does explicitly #include it. What am I doing wrong here?

Ant*_*nio 5

改变:

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)
Run Code Online (Sandbox Code Playgroud)

进入:

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)
Run Code Online (Sandbox Code Playgroud)

看:

  1. CMake 命令行工具模式
  2. add_custom_target

要看:

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

  1. add_dependencies

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

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