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

SCons: how to add cpp files to source list

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

原文: basic/original 构建步骤如下:

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
  )

但是失败了

fatal error LNK1181: cannot open input file 'dummy-file.obj'

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

综上所述 - 您将如何实施以下内容:

有什么建议吗?

如果你想告诉 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'))

正如 myaut 正确指出的那样,在您的情况下使用的方法是定义自定义生成器。它应该将您当前的 Command 字符串作为 Action,然后您可能还必须定义一个自定义 Emitter。有关如何放置所有 "dots on the i" 的更详细说明,请参阅 http://www.scons.org/wiki/ToolsForFools。 发射器很重要,因为它在解析构建脚本时获得 运行,因此在调用 env.BigCatBuilder 时。它的 return 值是实际构建步骤将产生的目标列表(将来)。 SCons 将这些目标作为节点存储在内部结构中,它会跟踪以下信息:此节点是否具有隐式依赖关系?它的子节点之一是否不是最新的,因此目标需要重建?... Glob() 调用将在本地文件系统中搜索,但也会遍历提到的 "virtual file tree"...并且,像这样,能够跟踪对物理上尚不存在的文件的依赖性。 您不必管理生成的文件列表并将它们传递给不同的构建器。 Glob() 通常会为您完成大部分工作...

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