嗯...这是可能的,有点复杂,而且存在一些问题。通常最好在构建系统中添加包含路径,例如(假设使用纯make
):
CPPFLAGS += -I$(PROJECT_PATH)
在源文件中不带路径引用头文件,只需使用 #include
引用即可。这将使得 make
命令使用 -Iyour/project/path
选项调用编译器,从而让编译器在 your/project/path
目录下寻找头文件。也就是说,在 Makefile 文件中你可以写:
PROJECT_PATH = foo/bar
CPPFLAGS = -I$(PROJECT_PATH)
并且在这些来源中
具有 #include "foo/bar/foobar.h"
的效果。
...还有,我看到你尝试使用 #include
引用源文件而不是头文件了吗?不要走那条路;那条路只会导致疯狂。除非你有一个非常好的理由,否则将源文件分别编译并像往常一样链接它们在一起。
所以,我不明白为什么你想在代码中直接引用项目���径的原因;构建系统方面唯一的更改是你必须传递-DPROJECT_PATH = foo / bar /
而不是 -IPROJECT_PATH = foo / bar /
,而且这种机制比实际设计用于此类东西的机制更加脆弱。但如果你真的想这么做,那么以下是方法:
你遇到的第一个问题是
代码格式不正确,因此简单的方法行不通。我们需要尝试预处理器魔法,其工作原理如下:
// v-- important: no spaces allowed here!
也许从下往上开始:
将其参数转换为字符串。也就是说,HEADER_STRING(foo/bar/baz.h)
将扩展为"foo/bar/baz.h"
。值得注意的是,宏参数不会被扩展,因此即使定义了宏PROJECT_PATH
,HEADER_STRING(PROJECT_PATH)
也会扩展为"PROJECT_PATH"
。这是当您尝试使用预处理器进行复杂操作时经常遇到的问题之一,解决方法是添加另一个层次,以便可以扩展参数:
......对于HEADER_STRING
我们不需要这个,但是在HEADER
中会用到,所以记住这个技巧。我担心预处理器的替换规则有些晦涩难懂,详细解释已超出了SO答案的范畴。简而言之,宏是逐层展开的,当宏没有被展开时,通常的技巧是为它们提供一个展开的位置,也就是添加另一层。
接下来是HEADER_I
,
将其参数粘贴在一起并将它们传递给HEADER_STRING
。 HEADER_I(foo,bar)
扩展为HEADER_STRING(foobar)
。由于我上面提到的问题,HEADER_I(PROJECT_PATH,foobar.h)
扩展为HEADER_STRING(PROJECT_PATHfoobar.h)
,进而扩展为"PROJECT_PATHfoobar.h"
,因此我们需要另一个层次来扩展PROJECT_PATH
:
这只是添加了可以扩展path
和name
参数的位置。最后,将PROJECT_PATH
定义为foo/bar/
,HEADER(PROJECT_PATH,foobar.h)
扩展为"foo/bar/foobar.h"
,然后我们可以说
导入 #include "foo/bar/foobar.h"
。可以在makefile里设置PROJECT_PATH
并使用-DPROJECT_PATH=$(some_make_variable)
传递。
最后需要注意的是,千万不能让任何空格跑到标记之间。
最终扩展为"foo/bar/ foobar.h"
(注意空格),这是行不通的。
vpath
)。 - πάντα ῥεῖ