本文使用的相关软件环境信息如下:
软件名称 | 软件版本 |
---|---|
Linux操作系统 | Ubuntu 22.04 LTS(X64) |
cmake | 3.22.1 |
-
include_directories
命令格式:
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
该命令主要是将目录添加到编译器的头文件的搜索目录之下,具体介绍见这里。执行该命令后,会将指定的目录添加到当前CMakeLists.txt文件的INCLUDE_DIRECTORIES目录属性和INCLUDE_DIRECTORIES目标文件属性中。接下来看一个实例,看include_directories添加目录之后,INCLUDE_DIRECTORIES属性内容的变化。目录结构如下,后续没有特殊说明,执行命令的目录为include_directories:
include_directories/ ├── CMakeLists.txt ├── main.cpp ├── testdir1 │ ├── CMakeLists.txt │ ├── test1.cpp │ └── test1.h │ └── testdir1_subdir └── testdir2 ├── CMakeLists.txt ├── test2.cpp └── test2.hs
include_directories/CMakeLists.txt内容如下:
cmake_minimum_required(VERSION 3.22) project(dir_test) include_directories(testdir1) message("--$ include_directories: testdir1") # 获取当前文件的INCLUDE_DIRECTORIES目录属性 get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) message("--$ in directory: ${CMAKE_CURRENT_SOURCE_DIR}, include dir list: ${dirs}") # 编译testdir1下的库 add_subdirectory(testdir1) message("--$ after compile lib test1") get_property(dirs TARGET test1 PROPERTY INCLUDE_DIRECTORIES) message("--$ lib test1 include dir list: ${dirs}") get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) message("--$ current file include dir list: ${dirs}") # 编译testdir2下的库 add_subdirectory(testdir2) message("--$ after compile lib test2") get_property(dirs TARGET test1 PROPERTY INCLUDE_DIRECTORIES) message("--$ lib test1 include dir list: ${dirs}") get_property(dirs TARGET test2 PROPERTY INCLUDE_DIRECTORIES) message("--$ lib test2 include dir list: ${dirs}") get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) message("--$ current file include dir list: ${dirs}") add_executable(main main.cpp) message("--$ after add exe main") get_property(dirs TARGET test1 PROPERTY INCLUDE_DIRECTORIES) message("--$ lib test1 include dir list: ${dirs}") get_property(dirs TARGET test2 PROPERTY INCLUDE_DIRECTORIES) message("--$ lib test2 include dir list: ${dirs}") get_property(dirs TARGET main PROPERTY INCLUDE_DIRECTORIES) message("--$ executable main include dir list: ${dirs}") get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) message("--$ current file include dir list: ${dirs}") message("---") target_link_libraries(main test1) message("--$ after add lib test1") get_property(dirs TARGET test1 PROPERTY INCLUDE_DIRECTORIES) message("--$ lib test1 include dir list: ${dirs}") get_property(dirs TARGET test2 PROPERTY INCLUDE_DIRECTORIES) message("--$ lib test2 include dir list: ${dirs}") get_property(dirs TARGET main PROPERTY INCLUDE_DIRECTORIES) message("--$ executable main include dir list: ${dirs}") get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) message("--$ current file include dir list: ${dirs}") message("---") target_link_libraries(main test2) message("--$ after add lib test2") get_property(dirs TARGET test1 PROPERTY INCLUDE_DIRECTORIES) message("--$ lib test1 include dir list: ${dirs}") get_property(dirs TARGET test2 PROPERTY INCLUDE_DIRECTORIES) message("--$ lib test2 include dir list: ${dirs}") get_property(dirs TARGET main PROPERTY INCLUDE_DIRECTORIES) message("--$ executable main include dir list: ${dirs}") get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) message("--$ current file include dir list: ${dirs}") message("---") include_directories(testdir2) message("--$ include_directories: testdir2") get_property(dirs TARGET test1 PROPERTY INCLUDE_DIRECTORIES) message("--$ lib test1 include dir list: ${dirs}") get_property(dirs TARGET test2 PROPERTY INCLUDE_DIRECTORIES) message("--$ lib test2 include dir list: ${dirs}") get_property(dirs TARGET main PROPERTY INCLUDE_DIRECTORIES) message("--$ executable main include dir list: ${dirs}") get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) message("--$ current file include dir list: ${dirs}") message("---")
include_directories/main.cpp内容:
#include "test1.h" #include "test2.h" int main(int argc, char** argv) { test1_print(); test2_print(); }
include_directories/testdir1/CMakeLists.txt内容如下:
message("---") message("---Enter directory: ${CMAKE_CURRENT_SOURCE_DIR}") include_directories(testdir1_subdir) # 获取当前文件的INCLUDE_DIRECTORIES目录属性 get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) message(" --$ include dir list: ${dirs}") add_library(test1 test1.cpp) message(" --$ after add lib test1") get_property(dirs TARGET test1 PROPERTY INCLUDE_DIRECTORIES) message(" --$ lib test1 include dir list: ${dirs}") get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) message(" --$ current file include dir list: ${dirs}") message("---Exist directory: ${CMAKE_CURRENT_SOURCE_DIR}") message("---")
include_directories/testdir1/test1.cpp和include_directories/testdir1/test1.h文件内容如下:
// test1.h #ifndef __TEST1_T__ #define __TEST1_T__ void test1_print(); #endif // test1.cpp #include "test1.h" #include <iostream> void test1_print() { std::cout << "From test1: hello!" << std::endl; }
include_directories/testdir2/CMakeLists.txt内容如下:
message("---") message("---Enter directory: ${CMAKE_CURRENT_SOURCE_DIR}") # 获取当前文件的INCLUDE_DIRECTORIES目录属性 get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) message(" --$ include dir list: ${dirs}") add_library(test2 test2.cpp) message(" --$ after add lib test2") get_property(dirs TARGET test2 PROPERTY INCLUDE_DIRECTORIES) message(" --$ lib test2 include dir list: ${dirs}") get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) message(" --$ current file include dir list: ${dirs}") message("---Exist directory: ${CMAKE_CURRENT_SOURCE_DIR}") message("---")
include_directories/testdir2/test2.cpp和include_directories/testdir2/test2.h文件内容如下:
// test2.h #ifndef __TEST2_T__ #define __TEST2_T__ void test2_print(); #endif // test2.cpp #include "test2.h" #include <iostream> void test2_print() { std::cout << "From test2: hello!" << std::endl; }
运行
cmake .
、make
以及./main
等命令,关键输出如下:$cmake . …… --$ include_directories: testdir1 --$ in directory: /XXX/include_directories, include dir list: /XXX/include_directories/testdir1 --- ---Enter directory: /XXX/include_directories/testdir1 --$ include dir list: /XXX/include_directories/testdir1;/XXX/include_directories/testdir1/testdir1_subdir --$ after add lib test1 --$ lib test1 include dir list: /XXX/include_directories/testdir1;/XXX/include_directories/testdir1/testdir1_subdir --$ current file include dir list: /XXX/include_directories/testdir1;/XXX/include_directories/testdir1/testdir1_subdir ---Exist directory: /XXX/include_directories/testdir1 --- --$ after compile lib test1 --$ lib test1 include dir list: /XXX/include_directories/testdir1;/XXX/include_directories/testdir1/testdir1_subdir --$ current file include dir list: /XXX/include_directories/testdir1 --- ---Enter directory: /XXX/include_directories/testdir2 --$ include dir list: /XXX/include_directories/testdir1 --$ after add lib test2 --$ lib test2 include dir list: /XXX/include_directories/testdir1 --$ current file include dir list: /XXX/include_directories/testdir1 ---Exist directory: /XXX/include_directories/testdir2 --- --$ after compile lib test2 --$ lib test1 include dir list: /XXX/include_directories/testdir1;/XXX/include_directories/testdir1/testdir1_subdir --$ lib test2 include dir list: /XXX/include_directories/testdir1 --$ current file include dir list: /XXX/include_directories/testdir1 --$ after add exe main --$ lib test1 include dir list: /XXX/include_directories/testdir1;/XXX/include_directories/testdir1/testdir1_subdir --$ lib test2 include dir list: /XXX/include_directories/testdir1 --$ executable main include dir list: /XXX/include_directories/testdir1 --$ current file include dir list: /XXX/include_directories/testdir1 --- --$ after add lib test1 --$ lib test1 include dir list: /XXX/include_directories/testdir1;/XXX/include_directories/testdir1/testdir1_subdir --$ lib test2 include dir list: /XXX/include_directories/testdir1 --$ executable main include dir list: /XXX/include_directories/testdir1 --$ current file include dir list: /XXX/include_directories/testdir1 --- --$ after add lib test2 --$ lib test1 include dir list: /XXX/include_directories/testdir1;/XXX/include_directories/testdir1/testdir1_subdir --$ lib test2 include dir list: /XXX/include_directories/testdir1 --$ executable main include dir list: /XXX/include_directories/testdir1 --$ current file include dir list: /XXX/include_directories/testdir1 --- --$ include_directories: testdir2 --$ lib test1 include dir list: /XXX/include_directories/testdir1;/XXX/include_directories/testdir1/testdir1_subdir --$ lib test2 include dir list: /XXX/include_directories/testdir1 --$ executable main include dir list: /XXX/include_directories/testdir1;/XXX/include_directories/testdir2 --$ current file include dir list: /XXX/include_directories/testdir1;/XXX/include_directories/testdir2 --- -- Configuring done -- Generating done -- Build files have been written to: /XXX/include_directories $ make Consolidate compiler generated dependencies of target test2 [ 16%] Building CXX object testdir2/CMakeFiles/test2.dir/test2.cpp.o [ 33%] Linking CXX static library libtest2.a [ 33%] Built target test2 Consolidate compiler generated dependencies of target test1 [ 66%] Built target test1 Consolidate compiler generated dependencies of target main [ 83%] Building CXX object CMakeFiles/main.dir/main.cpp.o [100%] Linking CXX executable main [100%] Built target main $ ./main From test1: hello! From test2: hello!
以上结果表明了几点:
1、include_directories添加的目录,会自动添加到当前所在的CMakeLists.txt文件的INCLUDE_DIRECTORIES目录属性,以及在当前CMakeLists.txt文件中定义的目标(通过add_executable/add_library等添加的目标)属性INCLUDE_DIRECTORIES中。
2、include_directories添加的目录,会传递到当前所在CMakeLists.txt文件中通过add_subdirectory增加的下层CMakeLists.txt中(add_subdirectory语句之后调用的include_directories添加的目录无法传递)。
3、下层CMakeLists.txt文件中调用的include_directories添加的目录,不会传递到调用它的上层CMakeLists.txt文件。
4、上层CMakeLists.txt中的include_directories与add_subdirectory相对位置对子CMakeLists.txt中能看到的目录有影响。
对我们的例子来说:
1、可执行文件main能看到目录:testdir1、testdir2
2、库文件test1能看到目录:testdir1、testdir1_subdir,无法看到testdir2,是因为调用add_subdirectory添加子目录testdir1时,还未通过include_directories包含testdir2
3、库文件test2能看到目录:testdir1,没错!这意味对于本文的例子来说,test2.cpp可以直接包含test1.h文件并调用test1_print()接口