代码之家  ›  专栏  ›  技术社区  ›  FrozenKiwi

SCons:如何将cpp文件添加到源列表

  •  1
  • FrozenKiwi  · 技术社区  · 9 年前

    在SCons中,我有一个生成未知数量文件的预构建步骤。生成这些文件后,我需要能够将cpp文件添加到源列表中。我是SCons的绝对初学者,我不知道该走什么样的正确道路。这样做的最佳方法是什么?

    原件: 基本/原始构建步骤如下:

    fpmFile = Dir('#').Dir('src').entry_abspath("FabricKINECT.fpm.json")
    # The next step generates a bunch of source files
    cppHeader = env.Command(
      [env.File(target + '.h')],
      klSources,
      [[kl2edkBin, fpmFile, "-o", hdir, "-c", cppdir]]
      )
    env.Depends(cppSources, cppHeader)
    
    # We pass in the supplied filelist to the build command
    # however, this list does not include the cpp files generated above
    # Currently I am hard-coding the generated files into
    # the cppSources list, but I want to add them in dynamically
    return env.SharedLibrary(
      '-'.join([target, buildOS, buildArch]),
      cppSources
      )
    

    我尝试过的 我尝试了几个不同的角度:

    http://www.scons.org/wiki/DynamicSourceGenerator ,但据我所知,这会为每个文件创建单独的构建目标,而我希望它们都包含在我的库构建中

    使用发射器: SCons to generate variable number of targets ,但我似乎无法解决依赖关系-无论我如何分配依赖关系,我的扫描仪都会先于其他任何东西运行

    我尝试制作另一个命令来收集文件列表-

    def gatherGenCpp(target, source, env):
      allFiles = Glob('generated/cpp/*.cpp')
      # clear dummy target
      del target[:]
      for f in allFiles:
        target.append(f)
    
    genSources = env.Command(['#dummy-file'], cppdir, gatherGenCpp)
    env.Depends(genSources, cppSources)
    
    allSources = genSources + cppSources
    return env.SharedLibrary(
      '-'.join([target, buildOS, buildArch]),
      allSources
      )
    

    然而,这失败了

    致命错误LNK1181:无法打开输入文件“dummy file.obj”

    我猜这是因为即使我从命令的目标中清除了伪文件条目,但这是在它注册到构建系统之后发生的(并且生成了预期的目标)。

    所有这些都可以说-您将如何实施以下内容:

    • 一个命令生成一堆CPP文件
    • 这些文件将添加到传入的文件列表中
    • 我们从这个cpp文件列表中构建一个dll。

    有什么建议吗?

    3 回复  |  直到 7 年前
        1
  •  1
  •   myaut    9 年前

    如果您想告诉SCons某些文件是使用他不知道的工具生成的,请使用 Builders .

    即。:

    env = DefaultEnvironment()
    
    # Create a builder that uses sed to replace all of occurrences
    # of `lion` word to `tiger`
    BigCatBuilder = Builder(action = Action('sed "s/lion/tiger/g" $SOURCE > $TARGET'))
    env.Append(BUILDERS = {'BigCatBuilder': BigCatBuilder})
    
    # Create tiger.c from pre/lion.c
    tiger_c = env.BigCatBuilder('tiger.c', 'pre/lion.c')
    
    # tiger.c is globbed by Glob('*.c')
    Program('tiger', Glob('*.c'))
    
        2
  •  1
  •   dirkbaechle    9 年前

    正如myout正确指出的,在您的情况下使用的方法是定义自定义生成器。它应该将当前命令字符串设置为Action,然后您可能还需要定义自定义发射器。看见 http://www.scons.org/wiki/ToolsForFools 更详细地描述如何将所有“点放在i上”。 Emitter很重要,因为它在解析构建脚本时运行,所以在调用env.BigCatBuilder时也会运行。它的返回值是实际构建步骤(将来)将生成的目标列表。SCons将这些目标存储为内部结构中的节点,并在其中跟踪信息,如:此节点是否具有隐式依赖关系?,它的一个孩子不是最新的,所以目标需要重建吗?。。。 Glob()调用将在本地文件系统中搜索,但也会遍历所提到的“虚拟文件树”。。。并且,像这样,能够跟踪对物理上还不存在的文件的依赖关系。 您不必管理生成的文件列表并将其传递给不同的Builder。Glob()通常为您完成大部分工作。。。

        3
  •  0
  •   FrozenKiwi    9 年前

    最后,我只需在scons中运行exec语句来生成文件。有时,最短的路径是最好的:)