用cmake处理头文件的依赖关系

我正在一个小型的C ++项目上使用CMake,到目前为止,它的工作很好…一个扭曲:x

当我更改头文件时,通常需要重新编译一些源文件(包括直接或间接包含的文件),但似乎cmake只检测到一些源文件需要重新编译,导致损坏的状态。 我可以通过清除项目并从头开始重build来解决这个问题,但是这样规避了使用make实用程序的目标:只重新编译需要的内容。

所以,我想我做错了什么。

我的项目非常简单:

  • 一个顶级目录,所有资源都坐在那里,主CMakeLists.txt位于那里
  • 一个包含所有公共头文件的“include”目录(在各种子目录中)
  • 一个源文件的所有子目录的“src”目录,src CMakeLists.txt位于那里
  • 每个“src”目录下的子目录都有一个CMakeLists.txt文件

主目录有:

cmake_minimum_required(VERSION 2.8) project(FOO) set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin) # Compiler Options set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -std=c++0x -Wall -Wextra -Werror") include_directories($(FOO_SOURCE_DIR)/include) add_subdirectory(src) 

“src”目录:

 add_subdirectory(sub1) add_subdirectory(sub2) add_subdirectory(sub3) add_subdirectory(sub4) add_executable(foo main.cpp) target_link_libraries(foo sub1 sub2 sub3 sub4) 

其中, sub4取决于sub3 ,取决于sub1取决于sub1

和一个子目录(sub3)的例子:

 set(SUB3_SRCS File1.cpp File2.cpp File3.cpp File4.cpp File5.cpp File6.cpp ) add_library(sub3 ${SUB3_SRCS}) target_link_libraries(sub3 sub1 sub2) 

我会很高兴,如果有人能把我的错误指向我,在这里search或在CMake没有产生任何东西,所以我想这很容易,或应该开箱即用…

(仅供参考,我在MSYS上使用cmake 2.8.2版本)

编辑

感谢Bill的build议,我检查了CMake生成的depend.make文件,确实缺乏(严重)。 这里是一个例子:

 src/sub3/CMakeFiles/sub3.dir/File1.cpp.obj: ../src/sub3/File1.cpp 

是的,就是这样,所有的包括都被引用:x

您应该查看二叉树中的depend.make文件。 它将在CMakeFiles/target.dir/depend.make 。 尝试find那些缺less一个你认为应该有的.h文件。 然后为cmake创build一个错误报告或通过电子邮件发送cmake邮件列表。

我刚刚遇到同样的问题。 将include_directories()path从绝对path更改为相对path后,添加了适当的依赖关系。

看起来像CMake试图猜测哪些头是系统,哪些是项目相关的。 我怀疑那些以/ -isystem /some/path开头的目录,因此不会显示在生成的依赖关系中。

如果不能用相对pathreplace${FOO_SOURCE_DIR} ,可以尝试使用适当的CMake函数来计算相对path。 即:

 file(RELATIVE_PATH FOO_SOURCE_REL_DIR ${CMAKE_CURRENT_SOURCE_DIR} ${FOO_SOURCE_DIR}/.) include_directories(${FOO_SOURCE_REL_DIR}/include) 

你添加包括你的cpp文件之前或之后运行cmake吗?

我碰到这个问题,并重新运行cmake修复它。 我已经添加了包括后cmake。

显然cmake从依赖关系树中删除系统包括path(谢谢@ony这个提示)。 这在大多数情况下可能是有意义的,但有时cmake不知道编译器认为是系统path还是不是。 我们正在使用一个忽略/usr/include的自定义gcc版本,但cmake认为它不会忽略它。 为了强制cmake使/usr/include未被优化的依赖,请试试这个技巧:prepend /. 到path。

我试图使所有的库依赖使用cmake依赖项function,包括某些“第三”党的库,并不总是默认安装在Linux上,甚至可用。 例如,Z-lib压缩。

下面的接口目标工作正常,如果Z lib包含不在/usr/include ,但会中断。

 find_package(ZLIB REQUIRED) message(status "found zlib ${ZLIB_LIBRARIES}") message(status "found zlib includes ${ZLIB_INCLUDE_DIRS}") target_link_libraries(zlib_target INTERFACE ${ZLIB_LIBRARIES}) target_include_directories(zlib_target INTERFACE ${ZLIB_INCLUDE_DIRS}) 

我改变了最后一行

 target_include_directories(zlib_target INTERFACE /.${ZLIB_INCLUDE_DIRS}) 

它的工作。 现在,依赖于zlib_target目标将在编译期间自动获取-I/./usr/include