为什么';CMake检测对我生成的文件的依赖性吗?
我正在尝试使用自定义命令生成标题。每次重新生成时都应更新头文件,以便包含它的源文件也将重新生成。(实际命令是一个脚本,但这里是一个简化版本。) 以下是我的项目: CMakeLists.txt 测试c为什么';CMake检测对我生成的文件的依赖性吗?,cmake,dependencies,Cmake,Dependencies,我正在尝试使用自定义命令生成标题。每次重新生成时都应更新头文件,以便包含它的源文件也将重新生成。(实际命令是一个脚本,但这里是一个简化版本。) 以下是我的项目: CMakeLists.txt 测试c #包括 int main() { 返回0; } 现在的问题是,如上所述的CMakeList.txt,根本不会创建version.h。只有在我从add_custom_target切换到add_custom_命令后,它才会执行此操作。但是,如果我以某种方式更改了文件,nextmake不会重建项目 看起
#包括
int main()
{
返回0;
}
现在的问题是,如上所述的CMakeList.txt
,根本不会创建version.h
。只有在我从add_custom_target
切换到add_custom_命令
后,它才会执行此操作。但是,如果我以某种方式更改了文件,nextmake
不会重建项目
看起来CMake没有意识到
test.c
依赖于version.h
,尽管它明确地包含了。我做错了什么?每个自定义命令都需要一个驱动程序(取决于它的输出)。在您的情况下,最好的驱动程序是test
可执行文件,这意味着您应该将生成的文件添加到可执行文件的源中:
add_executable(test ${test_SOURCES} ${VERSION_H_PATH})
问题似乎是用于可执行目标的名称test
是CMake保留的名称。见政策。为可执行文件使用不同的名称似乎与自定义目标的预期效果一样:
add_custom_target(GENERATE COMMAND "touch" "${VERSION_H_PATH}")
add_executable(testexe ${test_SOURCES})
add_dependencies(testexe GENERATE)
更改:
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)
进入:
见:
:
取决于:
使用同一目录(CMakeLists.txt文件)中的add_custom_command()命令调用创建的自定义命令的参考文件和输出它们将在目标建立时更新。
:
使顶层目标依赖于其他顶层目标,以确保它们在构建之前就构建。顶级目标是由add_executable()、add_library()或add_custom_target()命令之一创建的目标(但不是由CMake like install生成的目标)
顺便说一下,我不知道你的具体情况,但是你可以考虑用它来生成你的页眉。 < P>好的,实际上问题从一开始就很糟糕。我不应该像以前那样简化生成命令。但是通过删除build目录的内容并重新运行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
时,如果我从命令行触摸version.h
,或者在构建后删除version.h
并再次尝试生成test.c.o
,它仍然无法重建test.c.o
。@Ruslan奇怪。它是否包含正确的version.h
文件?这是一个相当普通的名字,它可能是用了一个不相关的名字吗?是的。我已经完成了echo asdfdsaf>version.h;rm cmakfiles/test.dir/test.c.o;rm试验;生成
,并获得预期的编译失败。但是如果不删除二进制文件,就无法正常工作:您的变体无条件地重建test.c.o
。此外,如果我在版本中更改目标名称,症状仍然存在,因此这似乎不是原因。因此,我将编辑OP以避免使用保留的目标名称以防止进一步混淆。@Ruslan我不明白您的意思:事实上,无条件(始终)构建test.c.o是您所要求的。您要求在每次构建时都会触及.h版本,因此必须重新构建包含该版本的文件。你能澄清一下吗?@Antonio我现在觉得自己很愚蠢。现在,当我测试它时,当我切换到(注释掉)add\u custom\u target
时,它甚至可以与OP中的代码一起工作。我确实希望在每个构建中都能运行该命令,但我不应该将该命令简化那么多——它只应该有时更改标题。在我从构建目录中删除所有内容并重新运行cmake
之前,这一切都不起作用。我甚至不知道现在该怎么处理这个问题…@Ruslan看来这毕竟是正确的答案,你应该接受它(也许可以把你的问题退回去)。你也可以奖励其他有用的答案。顺便说一句,您使用的是哪个cmake版本?@Antonio它不是:更改目标名称不会导致任何结果,除了更改二进制文件的名称。我的cmake版本是2.8.12.2(Kubuntu 14.04的默认版本)。因此,您可以获得赏金和追加投票,但我接受我自己的答案,因为它描述了我在自己的案例中为解决(愚蠢地表述)问题所必须做的事。谢谢你指出我的错误。这解决了我的问题。我花了好几个小时认为自己做错了,于是搜索了无数条线索。在创建新的生成文件夹时,CMake检测到生成的目标对生成的文件所包含的头文件的依赖关系。
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)
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)