【问题标题】:How do I set scons system include path如何设置 scons 系统包含路径
【发布时间】:2011-01-27 07:35:48
【问题描述】:

使用 scons 我可以轻松设置我的包含路径:

env.Append( CPPPATH=['foo'] )

这通过了标志

-Ifoo

到海合会

但是,我尝试在启用了很多警告的情况下进行编译。 特别是

env.Append( CPPFLAGS=['-Werror', '-Wall', '-Wextra'] )

在某些 boost 包含中会死得很惨……我可以通过将 boost 包含添加到系统包含路径而不是包含路径来解决这个问题,因为 gcc 对待系统包含的方式不同。

所以我需要传递给 gcc 而不是 -Ifoo 是

-isystem foo

我想我可以使用 CPPFLAGS 变量来做到这一点,但我想知道 scons 中是否有更好的解决方案。

【问题讨论】:

    标签: c++ scons


    【解决方案1】:

    在 SCons 中没有内置的方法来传递 -isystem 包含路径,主要是因为它是非常特定于编译器/平台的。

    将它放在 CXXFLAGS 中会起作用,但请注意,这将隐藏 SCons 的依赖项扫描器的标头,它只查看 CPPPATH。

    如果您不希望这些标头发生更改,这可能没问题,但如果您使用构建结果缓存和/或隐式依赖项缓存,则可能会导致奇怪的问题。

    【讨论】:

    • 感谢您确认我的预期(但希望是错误的)
    • 很好的答案,但实际上,我认为将这些包含从依赖链中排除是一件好事,因为它们会减慢整个构建过程而没有真正的收益。有很多 Boost 标头,它们不太可能改变(当它们改变时,您知道并可以决定清理所有内容)。
    • 确实,排除“只读”标头是加快构建速度的好方法。一个好的做法是确保库版本是其目录路径的一部分(即 /foo/bar/boost/1.38/include)。这样,boost 版本号就会显示在编译命令行上。由于 SCons 在其签名中包含命令行,因此任何 boost 升级都将位于不同的目录中,从而使任何现有的构建产品无效。这使得构建缓存更加健壮,尤其是对于大型团队。
    • 是的,对于这种很少更改的库,依赖库版本号会更有效。假设库更新是有规律的,并且版本从不混合 :) 顺便说一句,有人知道 Microsoft 编译器的相应选项吗?
    【解决方案2】:

    如果你这样做

      print env.Dump()
    

    您会看到_CPPINCFLAGS,并且您会看到CCCOM(或_CCCOMCOM)中使用的变量。 _CPPINCFLAGS 通常如下所示:

      '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
    

    从这里您可能会看到如何添加“isystem”集合,例如 _CPPSYSTEMINCFLAGS 或类似的。只需定义您自己的前缀、路径变量名称(例如 CPPSYSTEMPATH)和后缀,并使用上述习惯用法连接前缀。然后只需将您的 _CPPSYSTEMINCFLAGS 附加到 CCCOM 或 _CCCOMCOM 即可。

    当然,这是特定于系统的,但您可以在需要时有条件地将新变量包含在编译器命令行中。

    【讨论】:

      【解决方案3】:

      根据the SCons release notes,环境的CCFLAGS 从2.3.4 版开始支持“-isystem”。

      因此,例如,您可以执行以下操作:

      env.AppendUnique(CCFLAGS=('-isystem', '/your/path/to/boost'))
      

      不过,您需要确保您的编译器支持该选项。

      【讨论】:

      • 发行说明说 ParseFlags 现在可以解析 -isystem,但这并不意味着以下工作。你试过了吗?
      • 我试过了,它对我有用,至少在 scons 2.5.0 上是这样。
      • 是否有任何文件显示在依赖树中(来自 --tree=prune 的输出)?或者如果你在上面做,它们会被省略吗?
      • 你的意思是 boost-includefiles?它们实际上被省略了。
      【解决方案4】:

      扩展@LangerJan 和@BenG 提出的想法...这是一个完整的跨平台示例(将env['IS_WINDOWS'] 替换为您的Windows 平台检查)

      from SCons.Util import is_List
      def enable_extlib_headers(env, include_paths):
          """Enables C++ builders with current 'env' to include external headers
          specified in the include_paths (list or string value).
          Special treatment to avoid scanning these for changes and/or warnings.
          This speeds up the C++-related build configuration.
          """
          if not is_List(include_paths):
              include_paths = [include_paths]
      
          include_options = []
          if env['IS_WINDOWS']:
              # Simply go around SCons scanners and add compiler options directly
              include_options = ['-I' + p for p in include_paths]
          else:
              # Tag these includes as system, to avoid scanning them for dependencies,
              # and make compiler ignore any warnings
              for p in include_paths:
                  include_options.append('-isystem')
                  include_options.append(p)
         env.Append(CXXFLAGS = include_options)
      

      现在,在配置使用外部库时,而不是

      env.AppendUnique(CPPPATH=include_paths)
      

      打电话

      enable_extlib_headers(env, include_paths)
      

      在我的例子中,这在 Linux 上减少了 1000 倍,在 Windows 上减少了 3000 倍的修剪依赖树(使用 --tree=prune 生成)!它将无操作构建时间(即所有目标都是最新的)加快了 5-7 倍 在此更改之前修剪的依赖树有 400 万个来自 Boost 的包含。这太疯狂了。

      【讨论】:

        猜你喜欢
        • 2022-10-23
        • 2014-03-03
        • 2011-02-19
        • 1970-01-01
        • 2011-07-14
        • 1970-01-01
        • 1970-01-01
        • 2014-12-13
        • 1970-01-01
        相关资源
        最近更新 更多