CMake的INCLUDE_DIRECTORIES
官方解释如下:
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
添加编译器用于查找头文件的文件夹,如果文件夹路径是相对路径,则认为该路径是基于当前源文件的路径。
默认情况下,路径是被追加到已存在的文件路径列表中。使用AFTER
和BEFORE
可以追加或者插入。
如果指定了SYSTEM
,则编译器认为在某些平台下,该路径为系统头文件路径,会做一些特殊处理(比如忽略警告等)。
使用了
SYSTEM
选项,则生成的CMake
描述文件中,路径是以-isystem
指定的;如果不使用,则是通过-I
指定的。
现在,有如下文件结构:
.
├── CMakeLists.txt
├── include
│ └── Person.h
├── lib
│ ├── CMakeLists.txt
│ └── Person.cpp
└── main.cpp
main.cpp
文件内容如下:
#include <Person.h>
#include <stdio.h>
int main(int argc, char **argv) {
Person p;
char *name = "LQ";
p.setName(name);
char *result = p.getName();
printf("%s",result);
}
在之前,我以为当include <...>
,则编译器会去系统头文件搜索或者通过-isystem
指定的路径;而include "..."
则搜索-I
指定的路径。
那么,如果我想找到include <Person.h>
,则CMakeLists.txt
文件中需要这么指定:
INCLUDE_DIRECTORIES(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/include)
然而,经过测试发现,不管-isystem
还是-I
,编译器都可以找到Person.h
。
那么这两个参数的区别到底是什么?
根据gcc
的文档:
-
-iquote
指定的路径仅被include "..."
使用; -
-I
、-isystem
或者-idirafter
指定的路径,使用include "..."
和include <...>
都会被搜索。
默认的搜索路径如下:
- 双引号引用的头文件,比如
include "..."
,当前文件夹是默认的搜索路径; - 双引号引用的头文件,会去
-iquote
指定的路径搜索; - 去
-I
指定的路径搜索; - 去
-isystem
指定的路径搜索; - 去标准系统路径搜索;
- 去
-idirafter
指定的路径搜索;
注意下面的描述:
You can use -I to override a system header file, substituting your own version, since these directories are searched before the standard system header file directories. However, you should not use this option to add directories that contain vendor-supplied system header files; use -isystem for that.
The -isystem and -idirafter options also mark the directory as a system directory, so that it gets the same special treatment that is applied to the standard system directories.
所以,一般情况下,使用-I
指定路径即可。
我个人在使用过程中,使用
-isystem
只有在指定系统级SDK的头文件时才使用。比如/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include