大约一年前,我问过CMake中的头依赖关系。

我最近意识到,问题似乎是CMake认为这些头文件是项目的外部文件。至少,在生成Code::Blocks项目时,头文件不会出现在项目中(源文件会出现)。因此,在我看来,CMake认为这些头文件是项目的外部,并没有在依赖项中跟踪它们。

在CMake教程中快速搜索只指向include_directories,这似乎不是我想要的…

向CMake发出特定目录包含要包含的头文件,以及生成的Makefile应该跟踪这些头文件的正确方法是什么?


当前回答

首先,使用include_directories()告诉CMake将目录作为-I添加到编译命令行。其次,在add_executable()或add_library()调用中列出头文件。

举个例子,如果你的项目源在src中,你需要include中的头文件,你可以这样做:

include_directories(include)

add_executable(MyExec
  src/main.c
  src/other_source.c
  include/header1.h
  include/header2.h
)

其他回答

在更新的CMake版本中,我们可以将包含路径限制为target,例如:

target_include_directories(MyApp PRIVATE "${CMAKE_CURRENT_LIST_DIR}/myFolder")

我的意思是,如果CMakeLists.txt有多个目标,否则,包含路径不与其他CMakeLists.txt脚本共享,它足以做一些事情,如:

include_directories("${CMAKE_CURRENT_LIST_DIR}/myFolder")

然而,也许我们可以模拟target_include_directories(…)在CMake 2.8.10或更老版本中的作用,比如:

set_property(
    TARGET MyApp
    APPEND PROPERTY
        INCLUDE_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}/myFolder"
)

所有这些都完成了,但似乎如果你想要源文件被重新编译,一旦他们使用的任何头文件被改变,所有这样的头文件也需要添加到每个目标,比如:

set(SOURCES src/main.cpp)

set(HEADERS
    ${CMAKE_CURRENT_LIST_DIR}/myFolder/myHeaderFile.h
    ${CMAKE_CURRENT_LIST_DIR}/myFolder/myOtherHeader.h
)

add_executable(MyApp ${SOURCES} ${HEADERS})

我的意思是,如果CMake愿意,它可以自动检测到这样的头文件,因为它无论如何都会解析项目的C/ c++文件。

不要忘记包含${CMAKE_CURRENT_LIST_DIR}。 这就是给我带来麻烦的原因。

示例应该是这样的:

target_include_directories(projectname
    PUBLIC "${CMAKE_CURRENT_LIST_DIR}/include"                          
)

PUBLIC用于您想要包含在父项目中的依赖项。 对于那些你不喜欢的人来说是私密的。

你有两个选择。

旧:

include_directories(${PATH_TO_DIRECTORY})

而新的

target_include_directories(executable-name PRIVATE ${PATH_TO_DIRECTORY})

要使用target_include_directories,您需要定义可执行文件- add_executable(executable-name sourcefiles)。

所以你的代码应该是这样的

add_executable(executable-name sourcefiles)
target_include_directories(executable-name PRIVATE ${PATH_TO_DIRECTORY})

你可以在这里阅读更多内容https://cmake.org/cmake/help/latest/command/target_include_directories.html

这招对我很管用:

set(SOURCE main.cpp)
add_executable(${PROJECT_NAME} ${SOURCE})

# target_include_directories must be added AFTER add_executable
target_include_directories(${PROJECT_NAME} PUBLIC ${INTERNAL_INCLUDES})

首先,使用include_directories()告诉CMake将目录作为-I添加到编译命令行。其次,在add_executable()或add_library()调用中列出头文件。

举个例子,如果你的项目源在src中,你需要include中的头文件,你可以这样做:

include_directories(include)

add_executable(MyExec
  src/main.c
  src/other_source.c
  include/header1.h
  include/header2.h
)