大约一年前,我问过CMake中的头依赖关系。
我最近意识到,问题似乎是CMake认为这些头文件是项目的外部文件。至少,在生成Code::Blocks项目时,头文件不会出现在项目中(源文件会出现)。因此,在我看来,CMake认为这些头文件是项目的外部,并没有在依赖项中跟踪它们。
在CMake教程中快速搜索只指向include_directories,这似乎不是我想要的…
向CMake发出特定目录包含要包含的头文件,以及生成的Makefile应该跟踪这些头文件的正确方法是什么?
大约一年前,我问过CMake中的头依赖关系。
我最近意识到,问题似乎是CMake认为这些头文件是项目的外部文件。至少,在生成Code::Blocks项目时,头文件不会出现在项目中(源文件会出现)。因此,在我看来,CMake认为这些头文件是项目的外部,并没有在依赖项中跟踪它们。
在CMake教程中快速搜索只指向include_directories,这似乎不是我想要的…
向CMake发出特定目录包含要包含的头文件,以及生成的Makefile应该跟踪这些头文件的正确方法是什么?
当前回答
我使用的是CLion,我的项目结构如下:
--main.cpp
--Class.cpp
--Class.h
--CMakeLists.txt
修改前的CMakeLists.txt:
add_executable(ProjectName main.cpp)
修改后的CMakeLists.txt:
add_executable(ProjectName main.cpp Class.cpp Class.h)
通过这样做,程序编译成功。
其他回答
首先,使用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
)
必须做两件事。
首先添加要包含的目录:
target_include_directories(test PRIVATE ${YOUR_DIRECTORY})
如果你被一个非常旧的CMake版本(2.8.10或更老)所困,不支持target_include_directories,你也可以使用遗留的include_directories来代替:
include_directories(${YOUR_DIRECTORY})
然后你还必须将头文件添加到当前目标的源文件列表中,例如:
set(SOURCES file.cpp file2.cpp ${YOUR_DIRECTORY}/file1.h ${YOUR_DIRECTORY}/file2.h)
add_executable(test ${SOURCES})
这样,头文件将作为依赖项出现在Makefile中,例如,如果生成了一个Visual Studio项目,头文件也将作为依赖项出现在生成的Visual Studio项目中。
如何使用这些头文件的几个目标:
set(HEADER_FILES ${YOUR_DIRECTORY}/file1.h ${YOUR_DIRECTORY}/file2.h)
add_library(mylib libsrc.cpp ${HEADER_FILES})
target_include_directories(mylib PRIVATE ${YOUR_DIRECTORY})
add_executable(myexec execfile.cpp ${HEADER_FILES})
target_include_directories(myexec PRIVATE ${YOUR_DIRECTORY})
在更新的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++文件。
我也有同样的问题。
我的项目目录是这样的:
--project
---Classes
----Application
-----.h and .c files
----OtherFolders
--main.cpp
我在这些文件夹中存放文件的方法是:
file(GLOB source_files CONFIGURE_DEPENDS
"*.h"
"*.cpp"
"Classes/*/*.cpp"
"Classes/*/*.h"
)
add_executable(Server ${source_files})
这完全奏效了。
你有两个选择。
旧:
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