文章目录
最近用google test/mock 框架写Unit Test的时候, 碰到的关于覆盖头文件的问题.
- include的搜索顺序, 包括编译器选项来强制指定
- include的写法包含了相对路径
- include当前路径查找如何覆盖
问题远不止者3项. 下面的文章可以解决这些问题, 需要稍微思考以下即可.
The #include Directive
The following coming from the gcc documenation:
Both user and system header files are included using the preprocessing directive #include. It has three variants:
#include <file>
This variant is used for system header files. It searches for a file named file in a list of directories specified by you, then in a standard list of system directories. You specify directories to search for header files with the command option -I (see section 1.9 Invoking the C Preprocessor)
. The option -nostdinc
inhibits searching the standard system directories; in this case only the directories you specify are searched.
The parsing of this form of #include
is slightly special because comments are not recognized within the <...>
. Thus, in #include <x/*y>
the /*
does not start a comment and the directive specifies inclusion of a system header file named x/*y
. Of course, a header file with such a name is unlikely to exist on Unix, where shell wildcard features would make it hard to manipulate.
The argument file may not contain a >
character. It may, however, contain a <
character.
#include “file”
This variant is used for header files of your own program. It searches for a file named file first in the current directory, then in the same directories used for system header files. The current directory is the directory of the current input file. It is tried first because it is presumed to be the location of the files that the current input file refers to. (If the -I-
option is used, the special treatment of the current directory is inhibited.)
The argument file may not contain "
characters. If backslashes occur within file, they are considered ordinary text characters, not escape characters. None of the character escape sequences appropriate to string constants in C are processed. Thus, #include "x\n\\y"
specifies a filename containing three backslashes. It is not clear why this behavior is ever useful, but the ANSI standard specifies it.
#include anything else
This variant is called a computed #include. Any #include
directive whose argument does not fit the above two forms is a computed include. The text anything else is checked for macro calls, which are expanded (see section 1.4 Macros). When this is done, the result must fit one of the above two variants–in particular, the expanded text must in the end be surrounded by either quotes or angle braces.
This feature allows you to define a macro which controls the file name to be used at a later point in the program. One application of this is to allow a site-specific configuration file for your program to specify the names of the system include files to be used. This can help in porting the program to various operating systems in which the necessary system header files are found in different places.
difference between #include <filename>
and #include “filename”
In practice, the difference is in the location where the preprocessor searches for the included file.
#include <filename>
For #include <filename> the preprocessor searches in an implementation dependent manner, normally in search directories pre-designated by the compiler/IDE. This method is normally used to include standard library header files.
#include “filename”
For #include “filename” the preprocessor searches first in the same directory as the file containing the directive, and then follows the search path used for the #include <filename> form. This method is normally used to include programmer-defined header files.
A more complete description is available in the GCC documentation on search paths.
What if you want to reuse some files that you want to use different headers
For short and the following applys for gcc:
- use
-I-
option to inhibit the current directory treatment - use
-iquote dir
option to force the cpp to search the dir you specified
Reference
what-is-the-difference-between-include-filename-and-include-filename
Where Does GCC Look to Find its Header Files?