我知道可以指定相对于文件所在目录的#include
文件路径,作为绝对文件路径,或相对于$PATH
系统变量中的任何目录。有没有办法在程序编译时相对于用户的当前目录指定它?我们假设我有以下文件结构:
|--dir_a/
| |--a.c
| |--a.h
|--dir_b/
| |--b.c
| |--b.h
|--makefile
现在让我们说#include
来自dir_a/a.h
的文件dir_b/b.h
。使用dir_b/b.h
的位置,可以这样写:
#include ../dir_a/a.h
然而,这种方法在我看来有一个重大缺陷,因为它硬编码文件相对于彼此的位置,这意味着重定位文件需要更新文件所在的文件路径。
使用绝对文件路径可以避免这个问题,但是会在文件系统中硬编码项目的位置,这似乎是不好的做法。
最后,使用<>
标记来指定文件路径是不可行的,因为我无法假设项目将列在$PATH
变量中。
所以我想要做的是能够指定相对于用户编译位置的路径(甚至更好,从makefile的位置)。在上面的示例中,这将允许我从#include
dir_a/a.h
使用以下语句dir_b/b.h
#include dir_a/a.h
:
#include
我认为这将是理想的解决方案。这将使gcc
语句更加一致和易于遵循,并避免上面列出的缺点。是否有可能以任何方式这样做,例如。用编译器标志或什么?我使用{{1}}作为我的编译器。
答案 0 :(得分:4)
如果您始终使用<>
包含,则makefile中的-I
选项应该足够了。目录布局在父目录中仅显示一个makefile
。那可以用
-Idir_a -Idir_b
在编译器选项中,而.c文件只能执行
#include <a.h>
#include <b.h>
引用包含的问题之一是它们与其他编译器的行为可能不同,如What is the difference between #include <filename>
and #include “filename”
?中所述(标准不够明确)。使用gcc扩展可能不会改善这种情况。
答案 1 :(得分:1)
我设法解决了我的问题。
解决方案的第一部分涉及在编译时在-iquote
中指定gcc
标志。来自man gcc
:
-iquotedir
Add the directory dir to the head of the list of directories to be searched for header files only for the case of #include "file"; they are not searched for #include <file>, otherwise just like -I.
难题的第二部分是如何在makefile
本身内获取makefile
的路径。 This answer为我工作。为方便起见,我在这里粘贴解决方案:
ROOT_DIR = $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
编辑:虽然这种方法有效,this answer对交叉编译器更友好,所以我个人会使用它。
答案 2 :(得分:0)
是。任何包含文件(不直接位于项目链接器设置中指定的include
路径中)应该包含指定的所有子文件夹,例如:
#include "first/second/third/folder/library.h"