【问题标题】:How to use -isystem instead of -I to include directories of third-party projects in scons?如何用-isystem代替-I在scons中包含第三方项目的目录?
【发布时间】:2022-12-17 02:51:12
【问题描述】:

最近发现在CFLAGS中加上-Wall和-Wextra可以提高编译警告级别。 这暴露了一些隐藏的错误。

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

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

我们知道,scons的底层是gcc, 所以我找到了a gcc's solution in stack-overflow。

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

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

【问题讨论】:

    标签: gcc warnings scons gcc-warning


    【解决方案1】:

    您可以将要传递给编译器的标志添加到CCFLAGS(通用)-或CFLAGS(C-specific)或CXXFLAGS(C++-specific)。这可以通过附加到 CCFLAGS 或调用 MergeFlags() 来完成,-isystem 应该发送到 CCFLAGS。

    这是一个简单的 sconscript 文件,显示了这一点:

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

    如果源文件包含 other/include 中存在的标头 inc.h,则构建如下所示:

    $ 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 在通过 CPPPATH 的内容告知它的标头目录中查找,但我们在这里没有这样做。这实际上使 -isystem 给出的标头的默认处理与 SCons 的其他系统标头一致 - 注意 stdio.h 也没有作为依赖项进行跟踪。如果你想在 3rd 方项目中对标头进行依赖跟踪,你可以还将目录添加到CPPPATH。该目录将在命令行中出现两次,但根据 gcc 文档,这没关系:“如果标准系统包含目录,或用-isystem指定的目录,也用-I指定,则忽略-I选项。“

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

    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
    

    【讨论】:

      【解决方案2】:

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

      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 所写,在编译时只需手动添加包含目录作为 -isystem 即可,但 SCons 无法正确解析它们,有时它不会重建依赖于包含更改后的文件。

      此工具将路径添加为 -I 和 -isystem,SCons 和编译器都可以正确解释它们。

      如果您打算使用 MSVC,您还需要为外部标头设置不同的警告级别,或者默认为与普通标头相同。 该工具不会这样做,但您可以使用例如下面的代码。 (它应该通过将级别设置为 0 来关闭所有警告。)

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

      【讨论】:

      • 有点可爱!你会考虑在这里添加什么? scons-cookbook.readthedocs.io/en/latest
      • 稍微考虑一下,你不需要更多的东西来获得外部 Heaers 行为的安静,比如 "/external:W0" 或类似的东西吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-15
      • 1970-01-01
      相关资源
      最近更新 更多