Build 头文件和源文件的递归CMake搜索
我是CMake的新手,想问一下是否有人可以帮助解决以下问题 我在他们的文件夹中有C++源文件和头文件,现在我想制作一个递归的CMAGE文本文件。 目前,我是这样做的:Build 头文件和源文件的递归CMake搜索,build,cmake,build-process,build-automation,Build,Cmake,Build Process,Build Automation,我是CMake的新手,想问一下是否有人可以帮助解决以下问题 我在他们的文件夹中有C++源文件和头文件,现在我想制作一个递归的CMAGE文本文件。 目前,我是这样做的: CMAKE_MINIMUM_REQUIRED(VERSION 2.8) PROJECT(CarDetectorDAISY) file(GLOB_RECURSE SRCS *.cpp) file(GLOB_RECURSE HDRS *.h) ADD_EXECUTABLE(stereo_framework ${SRCS} ${H
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解决方案文件,当我尝试构建它时,它会显示
未找到头文件的错误(没有此类文件或目录)
如果有人能帮助我,我将不胜感激。谢谢。您可能错过了一个或多个电话。在
add\u 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)
我应该提到的是,这不是收集源代码列表的推荐方法-您应该在CMakeLists.txt中明确添加每个文件。通过这样做,如果以后添加或删除源文件,则会修改CMakeLists.txt,并且下次尝试构建时,CMake会自动重新运行。从
文件的文档中
:
我们不建议使用GLOB从源代码树中收集源文件列表。如果在添加或删除源时没有更改CMakeLists.txt文件,则生成的生成系统无法知道何时要求CMake重新生成
只是为了进一步澄清弗雷泽回答中的一点: 标题不应传递给
添加可执行文件
原因是,例如,Linux上的预期编译命令是:
gcc main.c mylib.c
而不是:
gcc main.c mylib.c mylib.h
然后,C预处理器解析mylib.C
,看到一个#include“mylib.h”
,并使用它的搜索路径来搜索这些文件
通过使用include\u目录
,我们修改了cpp预处理器搜索路径,这是正确的方法。在GCC中,这转化为将-I
标志添加到命令行:
gcc -Inew/path/to/search/for/headers main.c mylib.c
我的答案主要是一个黑客,但如果您不想手动添加所有目录,我发现它很有用 此宏将递归扫描所有子目录(及其子目录等…)。如果目录包含头(.h)文件,它会将其路径附加到
返回\u列表
。然后,此列表可用于目标\u包含\u目录
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进行测试我对此持怀疑态度。我同意你的观点,但相反的论点通常是,很容易通过
ls
或dir
获得原始源列表,然后通常一次只添加一两个文件。如果你自己工作的话,环球旅行是相当安全的。如果您是团队的一员,您必须“培训”团队在添加文件或从远程VCS更新文件后始终运行CMake,以防其他团队成员添加文件。最好使用target\u include\u目录
,而不是include\u目录
,因为后者是全局性的,现代CMake实践不鼓励使用。在target_sources()
命令中列出标题可能会很方便,因为作为源代码列出的标题本身不会直接编译,但添加它们将在IDE中的项目文件中列出这些标题,即使没有直接包含它们的源文件。注意:显然,这只是对使用include\u directories()
commandCheckout这个答案的补充,这是金色的。朋友,你为我节省了很多时间,谢谢你!