完整构建后跳过文件夹以使用 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
函数。这应该会加快您的依赖性检查时间。
但要回答您的具体问题,是的,可以不在 B
和 C
中构建目标。如果您不为这些子目录中的目标调用构建器,您就不会构建它们。只需要一个 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
也是允许的。
我有大量约 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
函数。这应该会加快您的依赖性检查时间。
但要回答您的具体问题,是的,可以不在 B
和 C
中构建目标。如果您不为这些子目录中的目标调用构建器,您就不会构建它们。只需要一个 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
也是允许的。