如何使用 -isystem 而不是 -I 在 scons 中包含第三方项目的目录?

How to use -isystem instead of -I to include directories of third-party projects in scons?

提问人:childerxxx 提问时间:11/30/2022 最后编辑:Piotr Siupachilderxxx 更新时间:12/17/2022 访问量:156

问:

最近,我发现通过添加 and to 可以提高编译警告级别。 这暴露了一些隐藏的错误。-Wall-WextraCFLAGS

但我不想编辑第三方代码中的警告。

我使用的项目是一个开源的 RTOS:RT-Thread

众所周知,scons 的底层是 gcc, 所以我在stack-overflow中找到了一个gcc的解决方案

顶级解决方案建议保持警告,但使用而不是包含第三方项目的目录。 然后我使用了 并发现默认使用的 scons。-isystem-Iscons --verbose-I

如何使用 -isystem 而不是 -I 在 scons 中包含第三方项目的目录?

GCC 警告 SCONS GCC-warning

评论


答:

0赞 Mats Wichmann 11/30/2022 #1

您可以将要传递给编译器的标志添加到(泛型)或(特定于 C )或(特定于 C++)。这可以通过附加到 来完成,或者通过调用 来完成,它理解应该发送到 。CCFLAGSCFLAGSCXXFLAGSCCFLAGSMergeFlags()-isystemCCFLAGS

下面是一个显示这一点的简单 sconscript 文件:

env = Environment()
env.MergeFlags("-isystem other/include")
env.Program("hello", "hello.c")

如果源文件包含存在于 中的标头,则生成如下所示:inc.hother/include

$ scons -Q --tree=prune
gcc -o hello.o -c -isystem other/include hello.c
gcc -o hello hello.o
+-.
  +-SConstruct
  +-hello
  | +-hello.o
  | | +-hello.c
  | | +-/bin/gcc
  | +-/bin/gcc
  +-hello.c
  +-[hello.o]

该标志被传递给 gcc,因此那里的处理应该是正确的。请注意,SCons 在其依赖项树中没有记录对标头的依赖关系 - SCons 通过 的内容查找它被告知的标头目录,但我们在这里没有这样做。这实际上使 SCons 给出的标头的默认处理与其他系统标头一致 - 通知也不会作为依赖项进行跟踪。如果要对第三方项目中的标头进行依赖关系跟踪,还可以将目录添加到 。该目录将在命令行上出现两次,但根据 gcc 文档,这没关系:“如果标准系统包含目录或用 -isystem 指定的目录也用 -I 指定,则忽略 -I 选项。CPPPATH-isystemstdio.hCPPPATH"

因此,如果需要跟踪,修改后的脚本可以是:

env = Environment()
env.MergeFlags("-isystem other/include")
env.Append(CPPPATH=["other/include"])
env.Program("hello", "hello.c")

现在:

$ scons -Q --tree=prune
gcc -o hello.o -c -isystem other/include -Iother/include hello.c
gcc -o hello hello.o
+-.
  +-SConstruct
  +-hello
  | +-hello.o
  | | +-hello.c
  | | +-other/include/inc.h
  | | +-/bin/gcc
  | +-/bin/gcc
  +-hello.c
  +-[hello.o]
  +-other
    +-other/include
      +-other/include/inc.h
0赞 Piotr Siupa 12/1/2022 #2

我遇到了类似的问题,并创建了一个添加新构造变量的工具(对 MSVC 的额外支持)。CPPSYSPATH

site_scons/site_tools/CppSystemPath.py:

def exists():
    return true

def generate(env):
    env.Append(CPPPATH=['$CPPSYSPATH'])
    
    env.Replace(
        SYSINCPREFIX='-isystem' if 'msvc' not in env['TOOLS'] else '/external:I',
        SYSINCSUFFIX='',
    )
    env.Replace(_CPPSYSINCFLAGS='${_concat(SYSINCPREFIX, CPPSYSPATH, SYSINCSUFFIX, __env__, RDirs)}')
    env.Append(CPPFLAGS=['$_CPPSYSINCFLAGS'])

SConstruct:

env = Environment()
env.Tool('CppSystemPath')
env.Append(CPPSYSPATH=['other/include'])

正如@MatsWichmann所写的,在编译时,只需手动添加包含目录即可,但 SCons 无法正确解析它们,并且有时不会在更改后重建依赖于包含的文件。-isystem

此工具将路径添加为 SCons 和编译器正确解释的路径。-I-isystem

如果计划使用 MSVC,还需要为外部标头设置不同的警告级别,否则将默认为与普通标头相同。 此工具不会执行此操作,但您可以使用下面的代码。(它应该通过将级别设置为 0 来关闭所有警告。您可以在此处找到所有其他选项的说明。)

if 'msvc' in env['TOOLS']:
    env.Append(CCFLAGS=['/external:W0'])

评论

0赞 Mats Wichmann 12/16/2022
这有点可爱!你会怎么考虑在这里添加?scons-cookbook.readthedocs.io/en/latest
0赞 Mats Wichmann 12/16/2022
想一想,难道你不需要更多的东西来获得外部Heaers行为的安静,比如之类的吗?"/external:W0"
0赞 Piotr Siupa 12/17/2022
@MatsWichmann 当然,添加它。或者只要我有时间,我就可以这样做。
0赞 Piotr Siupa 12/17/2022
@MatsWichmann我添加了一些有关 ./external:W0