我有一个SCons脚本需要大约10秒才发现没有什么需要重建,这对于本质上相当小的项目感觉非常长。阅读SConscript本身只花了一两秒钟,大部分时间花在:
scons: Building targets ...
步骤。
如何确定scons
目前究竟做了什么?还有什么其他一般建议可以写快速SCons脚本?
答案 0 :(得分:26)
(直接从 http://www.scons.org/wiki/GoFastButton被盗)
命令'scons --max-drift = 1 --implicit-deps-unchanged'将尽快执行你的构建。
OR:
使事情变得更快的另一个技巧是避免在修改共享库但不重建共享库时重新链接程序。见SharedLibrarySignatureOverride
答案 1 :(得分:9)
scons md5 - 汇总文件以确定它们已经发生了变化,所以它几乎都是md5sums所有文件。
你可以告诉它只使用时间戳来决定重建什么,而不是每次都要MD5sum所有文件,就像'make'那样,这应该可以加快速度。它可能更脆弱。例如如果文件在最后一次构建的1秒内发生了变化,那么scons就不会注意到这一点。使用
env.Decider('timestamp-newer')
还有MD5时间戳,它将首先检查时间戳,然后使用Md5比较内容,如果时间戳更新则实际更改。
env.Decider('MD5-timestamp')
另一个加快速度的简单方法是使用-j参数运行并行构建。
scons -j 2
在我的2核盒子上,-j 3通常可以提供最快的速度。
scons正在做的一些输出可以通过调用scons的--debug参数完成,请参阅各种选项的联机帮助页。
答案 2 :(得分:8)
为了弄清楚为什么SCons很慢而做了一些试验和错误,到目前为止的一些发现(确切的结果当然会因SCons脚本的结构和复杂性而异):
CacheDir()
没有明显的负面影响。Decider()
只有非常小的影响,不值得打扰。variant_dir
/ VariantDir()
可将构建时间增加约10%。SConstruct
文件本身需要大约10%的完整scons调用。可能的解决方案:
scons -u
而不是scons -D
)。SConscript
可选的部分,因此只能在手动调用时重建。对于库包含而不是-isystem
使用编译器标志-I
,这个更改单独将构建时间从10.5秒降低到6秒,对于我来说,它可以很容易地实现sed电话:
env.ParseConfig('pkg-config --cflags --libs gtkmm-2.4 | sed "s/-I/-isystem/g"')
不确定为什么会这样,我认为它会减少gcc
输出的依赖关系,从而减少scons
跟踪的依赖关系。
当然也强烈建议使用CacheDir()
和scons -j N
,但这只会加快实际构建速度,而不是评估SCons脚本本身。
答案 3 :(得分:7)
移动第三方包括CPPPATH和进入CCFLAGS产生了巨大的差异。对于我们的项目有12个外部包含目录(包括boost和python),无所事事的编译从30s减少到3s - 加速10倍。
答案 4 :(得分:5)
当SCons首先创建Environment
时,它会进行一系列查找以查看可用的工具。在创建第一个DefaultEnvironment
之前,您可以通过在env
中明确选择工具来避免不必要的检查和加速SCons。
DefaultEnvironment(tools=[])
答案 5 :(得分:2)
将SConscript添加到
中if 'explain' in GetOption("debug"):
Progress('Evaluating $TARGET\n')
并使用--debug=explain
运行。您将看到SCons花费时间评估
答案 6 :(得分:1)
scons --profile
+ snakeviz
这种组合向我展示了到底是什么。
--profile
以cProfile
格式输出二进制文件,即present in the stdlib。
snakeviz
是一个很棒的可视化工具,可以在GUI中快速查看该文件:
scons --profile f.prof
pip install -u snakeviz
snakeviz f.prof
输出看起来像这样:
,您可以将鼠标悬停在每个框上,以查看包含该功能的文件的完整路径。
在更一般的Python上下文中的问题:Is there any simple way to benchmark python script?
--debug
+ ts -s
这不能解决我的特定问题,但通常可以给您一些想法:
--debug
标志,或所有似乎有趣的标志ts -s
,显示每行何时出现在标准输出上:How to monitor for how much time each line of stdout was the last output line in Bash for benchmarking? time scons --debug=count,duplicate,explain,findlibs,includes,memoizer,memory,objects,prepare,presub,stacktrace,time |
ts -s | tee f
样本输出摘录显示了我在2到10秒之间有一个巨大的时间间隔,这是我试图关注的地方:
00:00:02 SConscript:/data/gem5/master3/build/ARM/sim/power/SConscript took 1.556 ms
00:00:02 dup: relinking variant 'build/ARM/sim/probe/SConscript' from 'src/sim/probe/SConscript'
00:00:02 Building build/ARM/sim/probe/SConscript with action:
00:00:02 UnlinkFunc(target, source, env)
00:00:02 Building build/ARM/sim/probe/SConscript with action:
00:00:02 LinkFunc(target, source, env)
00:00:02 SConscript:/data/gem5/master3/build/ARM/sim/probe/SConscript took 0.401 ms
00:00:10 SConscript:/data/gem5/master3/build/ARM/tests/opt/SConscript took 98.225 ms
00:00:10 SConscript:/data/gem5/master3/build/ARM/SConscript took 8885.387 ms
00:00:10 SConscript:/data/gem5/master3/SConstruct took 9409.641 ms
00:00:10 scons: done reading SConscript files.
00:00:10 scons: Building targets ...
在scons 3.0.1,Ubuntu 18.04中进行了测试。
另请参见