递归CMake搜索头文件和源文件

San*_*hit 19 build-automation build-process build cmake

我是CMake的新手,想问一下是否有人可以帮助解决以下问题.

我在各自的文件夹中有C++源代码和头文件,现在,我想制作一个递归搜索它们的CMake文本文件.

目前,我这样做:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(CarDetectorDAISY)

file(GLOB_RECURSE SRCS *.cpp)
file(GLOB_RECURSE HDRS *.h)

ADD_EXECUTABLE(stereo_framework  ${SRCS} ${HDRS})
TARGET_LINK_LIBRARIES(stereo_framework) 
Run Code Online (Sandbox Code Playgroud)

这将创建我的CarDetectorDAISY.sln解决方案文件,当我尝试构建它时,它会显示找不到头文件的错误(没有这样的文件或目录).

如果有人能帮助我,真的很感激.谢谢.

Fra*_*ser 23

你可能错过了一个或多个include_directories电话.将标题添加到add_executable调用中的文件列表实际上并没有添加到编译器的搜索路径 - 这是一个方便的功能,它只是添加到IDE中项目的文件夹结构中.

因此,在您的根目录中,假设您有/my_lib/foo.h,并且您希望将其包含在源文件中

#include "my_lib/foo.h"
Run Code Online (Sandbox Code Playgroud)

然后在你的CMakeLists.txt中,你需要做:

include_directories(${CMAKE_SOURCE_DIR})
Run Code Online (Sandbox Code Playgroud)

如果,而你只是想做

#include "foo.h"
Run Code Online (Sandbox Code Playgroud)

然后在CMakeLists.txt中,做

include_directories(${CMAKE_SOURCE_DIR}/my_lib)
Run Code Online (Sandbox Code Playgroud)


我应该提一下,这file(GLOB...)不是收集源列表的推荐方法 - 您应该只在CMakeLists.txt中显式添加每个文件.通过执行此操作,如果稍后添加或删除源文件,则会修改CMakeLists.txt,并在下次尝试生成时自动重新运行CMake.来自以下文档file:

我们不建议使用GLOB从源树中收集源文件列表.如果在添加或删除源时没有更改CMakeLists.txt文件,则生成的构建系统无法知道何时请求CMake重新生成.

  • 但我宁愿手动重新运行CMake而不是键入每个源文件... (28认同)
  • 我正准备这个.我同意你的观点,但反驳的论点通常是用'ls`或`dir`来获取初始的源列表很容易,然后你通常只是一次添加一个或两个文件.如果你自己工作,那么全球安全是非常安全的.如果您是团队成员,则必须"训练"团队,以便在添加文件或从远程VCS更新后始终运行CMake,以防其他团队成员添加文件. (5认同)
  • 最好使用“target_include_directories”而不是“include_directories”,因为后者是全局的并且不被现代 CMake 实践所鼓励。 (3认同)

小智 6

我的回答主要是一个 hack,但如果您不想手动添加所有目录,我发现它很有用。

此宏将递归扫描所有子目录(及其子目录等...)。如果目录包含头 (.h) 文件,它会将其路径附加到 .h 文件中return_list。然后可以将此列表与target_include_directories.

MACRO(HEADER_DIRECTORIES return_list)
    FILE(GLOB_RECURSE new_list *.h)
    SET(dir_list "")
    FOREACH(file_path ${new_list})
        GET_FILENAME_COMPONENT(dir_path ${file_path} PATH)
        SET(dir_list ${dir_list} ${dir_path})
    ENDFOREACH()
    LIST(REMOVE_DUPLICATES dir_list)
    SET(${return_list} ${dir_list})
ENDMACRO()
Run Code Online (Sandbox Code Playgroud)

用法:

HEADER_DIRECTORIES(header_dir_list)

list(LENGTH header_dir_list header_dir_list_count)
message(STATUS "[INFO] Found ${header_dir_list_count} header directories.")

target_include_directories(
    my_program
    PUBLIC
    ${header_dir_list} # Recursive
)
Run Code Online (Sandbox Code Playgroud)

宏观信用:克里斯托夫

用 Cmake 3.10 测试

  • 这是金色的。我的朋友,你节省了我很多时间,谢谢你! (2认同)