繁体   English   中英

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

[英]Recursive CMake search for header and source files

我是 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解决方案文件,当我尝试构建它时,它显示找不到头文件的错误(没有这样的文件或目录)。

如果有人可以帮助我,我将不胜感激。 谢谢。

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

因此,在您的根目录中,假设您有 /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 重新生成。

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

此宏将递归扫描所有子目录(及其子目录等...)。 如果目录包含头 (.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()

用法:

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
)

宏观信用:克里斯托夫

用 Cmake 3.10 测试

只是为了进一步澄清弗雷泽的回答中的一点:

不应将标头传递给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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM