【问题标题】:Skip folders to build using scons after full build完全构建后跳过文件夹以使用 scons 构建
【发布时间】:2015-11-10 22:42:41
【问题描述】:

我有大约 10,000 个源文件,它们分散在多个文件夹中。

我想知道是否有办法跳过某些文件夹,我知道没有改变。

例如,考虑以下文件夹结构

A (Sconstruct is here)
|
->B (unchanged 1000 files)
->C (unchanged 1000 files)
->D (changed 1 file)

一旦我第一次进行完整构建,我希望它编译所有内容(B、C、D)但是当我修改 D 中的文件时(我知道),我想构建文件夹 仅 D,跳过 B 和 C,最后将它们链接在一起形成最终的二进制文件(B、C 和新 D)。

我一直在寻找很长一段时间,但无法弄清楚。甚至可能吗?我可以指定只查看特定文件夹以进行更改吗?

【问题讨论】:

  • 您刚刚描述了 scons 的确切功能。如果您运行“scons”,随后更改了一个文件,然后再次运行“scons”,scons 只会重新编译该文件而不会重新编译其他文件。这是你看到的吗?
  • 正确,但它也会遍历目录 B 和 C 并查找修改过的文件。作为用户,我知道他们没有改变,所以我如何让 scons 完全跳过这些文件夹。
  • 所以你的抱怨不是 scons 在 B 和 C 中构建,而是 scons 测试 B 和 C 中的依赖关系。我理解正确吗?
  • 除了跳过依赖项(我使用 --implicit-deps-unchanged 禁用),我还想完全禁用遍历 B 和 C (这需要大量时间才能发现什么改变)。最后,我想将 B、C 和 new D 一起链接到可执行文件。
  • 我有一个问题:如果您在第一次运行时从头开始构建所有内容,然后随后全部由您自己构建,则始终知道您必须根据最新的源代码更改准确地重建哪些库/目标...您需要构建系统做什么?为什么不使用简单的脚本?

标签: c scons


【解决方案1】:

首先,我将使用Decider('timestamp-match') 进行调查,甚至构建自定义Decider 函数。这应该会加快您的依赖性检查时间。

但要回答您的具体问题,是的,可以不在BC 中构建目标。如果您不为这些子目录中的目标调用构建器,您就不会构建它们。只需有一个 if 选择性地选择要调用的 env.Object()(或类似)函数。

当我充实您的示例时,我选择让每个子目录创建一个链接到主可执行文件的库,并且只为用户选择的目录调用 env.SConscript()。这是一种实现方式:

A/S构造:

subdirs = ['B','C','D']
AddOption('--exclude', default=[], action='append', choices=subdirs)
env = Environment(EXCLUDES = GetOption('exclude'))

env.SConscript(
    dirs=[subdir for subdir in subdirs
          if subdir not in env['EXCLUDES']],
    exports='env')

env2 = env.Clone()
env2.PrependUnique(LIBPATH=subdirs,
                   LIBS=subdirs)
env2.Program('main.c')

B/SConscript:

Import('env')
env.Library('B', env.Glob('*.c'))

C/SConscript:

Import('env')
env.Library('C', env.Glob('*.c'))

D/SConscript:

Import('env')
env.Library('D', env.Glob('*.c'))

要进行全局构建:scons

修改D中的单个文件后进行构建:scons --exclude=B --exclude=C

编辑

同样,您可以向 SConstruct 添加白名单选项。想法是一样的:只为某些对象调用构建器。

这是一个与上面类似的 SConstruct,但带有白名单选项:

subdirs = ['B','C','D']
AddOption('--only', default=[], action='append', choices=subdirs)
env = Environment(ONLY = GetOption('only') or subdirs)

env.SConscript(
    dirs=env['ONLY'],
    exports='env')

env2 = env.Clone()
env2.PrependUnique(LIBPATH=subdirs,
                   LIBS=subdirs)
env2.Program('main.c')

构建一切:scons

重建D并重新链接主程序:scons --only=D

【讨论】:

  • 只是B和C太多了,我需要一种白名单而不是黑名单的方法。有什么建议吗?
【解决方案2】:

如果 D 独立于 B 和 C,只需在 D(程序/库)或整个目录中指定您的目标,如 scons D/myprog.exe 那样在命令行上明确指定为目标。 SCons 会自动展开所需的依赖,不会遍历不相关的文件夹 B 和 C。

注意如何指定任意数量的目标,所以

scons D/myprog.exe B

也是允许的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    相关资源
    最近更新 更多