我如何使用 GCC 选项 -iprefix 和 -iwithprefix?

How do I use GCC options -iprefix and -iwithprefix?

我有一个分成模块的 C++ 应用程序。每个模块的目录结构如下所示:

module_a/
  export/  <-- module_a public interface
  src/     <-- module_a private source
  test/
    src/   <-- unittests for module_a

我正在使用 CMake 设置模块依赖项并构建应用程序。如果 module_a 依赖于 module_b,则 module_bexport 目录在构建 module_a.

时添加为包含路径

因此,如果 module_a 需要一个文件 module_b/export/foo.h,那么在源文件中您将使用 #include "foo.h"

我正在寻找一种方法,使模块名称成为 include 指令的一部分。所以对于上面的例子我想(必须)写 #include "module_b/foo.h".

这可以通过 GCC 选项 -iprefix 和 -iwithprefix 来完成吗?我已经搜索了使用示例,但我只能找到 GCC 手册的副本和参考资料,我认为它解释得不是很好。

我试过这样使用它:

$ find -type f
./src
./src/main.cc
./export
./export/bar.h

$ g++ -iprefix foo/ -iwithprefix export/ src/main.cc
src/main.cc:1:10: fatal error: foo/bar.h: No such file or directory
    1 | #include "foo/bar.h"
      |          ^~~~~~~~~~~
compilation terminated.

$ gcc --version
gcc (Debian 9.2.1-17) 9.2.1 20191102

但是如您所见,它不起作用。我应该如何使用 -iprefix 和 -iwithprefix?

另外,有没有人有其他解决我的问题的方法?我有点担心 IDE 和其他编译器可能不理解 -iprefix 和 -iwithprefix,所以也欢迎任何其他解决方案。

编辑:发布这个问题后我立即意识到也许 -iprefix foo/ -iwithprefix bar 只是一种奇特的写法 -I foo/bar。但是,我对此进行了测试,但仍然无法正常工作。所以如果有人能解释这些选项是如何工作的,那还是很好的,即使他们不会帮助我解决我的问题。

How should I use -iprefix and -iwithprefix?

这只是一个捷径,可以避免每次都写出一个共同的前缀。所以代替:

cpp -Idirafter /sys/root/a -Idirafter /sys/root/b

你改为:

cpp -iprefix /sys/root/ -iwithprefix a -withprefix b

(如果您希望它等同于 -I,请用 -Iwithprefix 代替 -Iwithprefixbefore。)

这可以派上用场很长的包含目录路径,就像您在交叉编译时可能 运行 进入的那样(甚至可能需要,参见 getconf ARG_MAX

Also, does anyone have another solution to my problem?

我偶然发现了 -iprefix,因为我也遇到了同样的问题,希望有一个开箱即用的选项。没有,但是 Linux 设备树构建有同样的问题:

ARCH=armARCH=arm64 的设备树分别在 arch/arm/boot/dtsarch/arm64/boot/dts 中。有时,arm64 设备树需要 arm 目录中的一些通用文件,但是在路径中包含所有体系结构的 dts 目录并不是一个很好的解决方案。

Linux 所做的是 having a dedicated directory in the source tree with suitably-named symlinks into each architecture and this directory's path as well as the directory of the currently active ARCH go into the search path。这样,ARCH=arm 可以写成 #include "something.dtsi",但 ARCH=arm64 必须写成 #include <arm/something.dtsi>