完整构建后跳过文件夹以使用 scons 构建

Skip folders to build using scons after full build

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

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

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

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

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

我已经找了好久了,还是没找到。有可能吗?我可以指定只查看特定文件夹的更改吗?

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

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

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

A/SConstruct:

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

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

请注意如何指定任意数量的目标,因此

scons D/myprog.exe B

也是允许的。