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

时间:2013-07-15 11:58:52

标签: build cmake build-process build-automation

我是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) 

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

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

3 个答案:

答案 0 :(得分:23)

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

所以,在你的root中,假设你有/my_lib/foo.h,并且想要将它包含在源文件中

#include "my_lib/foo.h"

然后在您的CMakeLists.txt中,您需要执行以下操作:

include_directories(${CMAKE_SOURCE_DIR})

如果您只想做

#include "foo.h"

然后在CMakeLists.txt中,执行

include_directories(${CMAKE_SOURCE_DIR}/my_lib)


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

  

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

答案 1 :(得分:1)

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

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

MARO(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()

用法:

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
)

宏观信用:Christoph

通过Cmake 3.10测试

答案 2 :(得分:0)

进一步澄清弗雷泽答案中的一点:

标题不应传递给ADD_EXECUTABLE

原因是Linux上的目标编译命令就是:

gcc main.c mylib.c

而不是:

gcc main.c mylib.c mylib.h

然后,C预处理器解析mylib.c,并看到#include "mylib.h",并使用它的搜索路径查找这些文件。

通过使用include_directories,我们改为修改cpp预处理器搜索路径,这是正确的方法。在GCC中,这转换为将-I标志添加到命令行:

gcc -Inew/path/to/search/for/headers main.c mylib.c