SCons: A Software Construction Tool
scons.org
scons.org
I've long been really excited about SCons but eventually decided to move away because it became unbearably sluggish for a large-ish codebase with >180K lines of C++ code split into many files. Another issue are cross-platform builds. SCons breaks every time there is a new version of Visual Studio, and it takes many months until an updated version restores compatibility.
Also SCons is Turing complete and this makes it a bit of a stretch to call the language declarative; Meson keeps simple loops but is not Turing complete and the maintainers are okay with plans/pull requests that make Meson even more declarative. In Meson generally "there is only one way to do it", in SCons much less so which is ironic given it uses Python as the language.
The only annoying part of Meson is that it only supports a few compilers (GCC, clang, ICC, MSVC), and requires porting to new compilers unlike Autoconf.
I realise that the post is not from recently but the benchmarks are on seriously outdated software and hardwaee, those specs are over a decade old at this stage. His conclusions are also misleading, all of his graphs show that make is 2-10x faster than scons, and that make scales better than scons.he seems hell bent on proving there's no quadratic complexity, despite there being an order of magnitude of a difference!
On the other hand, I don't think it's reasonable to assume every build system will immediately support every compiler/IDE. At the end of the day, scons is an open source project and if that's the only issue stopping you using it, I'm sure they'd be happy to accept patches providing support rather than wait months.
If your API is stable, why wouldn't it be reasonable to expect that it should work out of the box?
Scons has great ideas, but something either about the implementation or about reality fails to deliver.
There's definitely some mental gymnastics and careful massaging going on to hide the performance problem. Would be a great example for a "How to lie with charts and graphs" article.
In the last decade we have gone from everyone needs an antivirus to Windows 10 is good enough for most people. We've had Spectre and meltdown, SSDs have become viable and been replaced by nvmE SSDs we've had a decade of OS development, filesystem development and hardware improvements.weve also had huge improvements in build ststems, Ninja was only relewaeed in 2012!
And yet, even after all of that, the TLDR from the article is "scons is an order of magnitude slower than make, but my hardware was the bottleneck before i figured it out scaled quadratically, therefore scons is not slow".
WAF worked, and didn't seem especially slow, unlike Scons, but I frequently needed to code Python to make it do what seemed like pretty ordinary things.
It takes it 30s, on a decent size codebase, just to tell you that there is "Nothing to do." There is order of magnitude difference between it and make. It's a complete travesty!
A few times, the skipped link step revealed to me that the code change I had just made had no effect on the compiler output, usually because the compiler's optimizer was already doing the same thing.
Likewise, hash-based compilation made git operations much smoother, since things like rebasing or jumping back and forth between branches can update timestamps without affecting content.
I know it's possible to hack similar functionality into some other build systems by adding a layer of intermediate hash file targets everywhere. But I'm a bit surprised the idea hasn't seen broader adoption... Having build artifacts indexed by hash seems like it'd be a requirement for any system that eventually wants to support large, distributed builds.
As a Linux distribution maintainer, I second that. There are not that many packages that still use SCons, but ones that do often require boilerplate and/or patches to honor standard environment variables like CC, CFLAGS, LDFLAGS. Cross-compiling a SCons package is a nightmare.
If you like that SCons uses Python, I'd suggest to try Meson. It does everything right and exposes a subset of Python API: https://mesonbuild.com
The only other tools I've found to rival this flexibility are Gradle (see the Software Domain Modeling chapter of its documentation) and Shake (though having to write rules in Haskell makes it a hard pill to swallow).
Among the most used articles on MDB's internal wiki is "Scons: It's Not That Slow!"
In fact it is really quite, quite slow, but a universally popular add-on (not officially "supported" when I was there), is a Ninja build scheduler that is blindingly quick.
So, the slowness only manifests when you need to recalculate the dependencies, which doesn't appear in the typical edit-build-test cycle. With Ninja, combined with Ccache and a distributed build tool (whose name escapes me ATM), coding at Mongo was not bad.
It would just be a huge job migrating to something else, for little better possible result than "it still works". And it does already work.
We eventually switched to Blueprint.
Edit: Google, for me, doesn't return that on the first page, but the first result is https://opensource.google.com/projects/blueprint which links to it.
At least autotools and m4 have the excuse of all that historical baggage and very broad portability.
Having used both scons and waf, and also having used make, cmake and cargo, I would take any of the last three over scons or waf in a heartbeat. I think cargo is far and away the nicest to use because there is very little to actually do to build your program. Using waf or scons was always an exercise of 'I added a header file, so now I need to figure out the scons/waf API in order to tell it what to do with it'.
At the beginning might look good, with some "apparently" nice principles, but beyond a certain point it will start growing in volume and complexity, like a cancer grows, until its technical debt devoures whole teams of people and impacts everyone performance and people starts quitting. Adding more people to the build responsibilities doesn't help because it's impossible to maintain it after more than 2 people have been involved in a large scons projects.
Together with the few fancy ideas that it has, there are other design principles which do not scale from the human standpoint. It's nature of python code for everything and the way builders and scanners are created, makes impossible to follow the code flow and next to impossible to find certain bugs unless the people who built the mess was a god of communication and an ascet in coding discipline. Every single aspect from that build, as soon as more than one target is compiled, will start growing unendlessly, moving the focus from the project's business code to build environment's code. It's design principles and monolitic structures together with its terrible underlaying implementation of that horrible API make impossible to work in a team with scons and the larger it gets the more it leads to giant unmaintaible build environments which end up crashing randomly and no one can explain why or how to make anything by themselves. And at some point the amount of features pythin users end up embeddign there end up creating so much technical debt that it makes feel impossible to justify the migration to a different build system; whereas in reality other build environments might solve almost all the non problems easier by skipping features no one wanted.
You might think I am exagerating because someone showed to you a scons hello world, but then I will reply you that I've witnessed 3 different teams at a large corporation escalating their scons based build environments to upper management because it became an interminable source of conflicts and a black hole of company's resources. The best case was when a full dedicated person in a team of 10 people does all the build related work, and when I say all related work, I trilly mean to write even the most basic aspects of every single build, leaving the rest of the team in the ignorance and uncappable of extending the build by themselves, or at best copy-pasting a snippet and praying that it works.
Seriously, this tool is wrong for teams of all sizes bigger than 2 people. It favors an unmaintainable mess only comparable with the worst spaghetti-worm-hole codebases.
I think a declarative DSL with scripting hooks behind it is a better model. Having used many, many build systems over the years, I've never found one I thought truly got things right (though several came close).
I actually think the ideas behind bjam ought to be revisited. It had a declarative style, with scripting to support it. The implementation was awful sadly; the tiniest mistake or typo would send the parser into a tailspin and the documentation was truly confusing. Any errors were presented to the user at the scripting level, which was even more confusing. But the idea of having toolchains defined separately, and having traits and features was brilliant. There's a lot to learn from there.
Maybe it's just me, but I prefer even the ugliest make files to scons and Gradle and what not. Because I have been burned too many times by "improvements" in the build system making my code so compiling.
Am I the only one?
Everybody must write python code to build their C++ files in a project. What could go wrong?
A couple data points on performance. A current snapshot of MongoDB's repo will do a null incremental build in 53 seconds on my i7-2600 with non-ssd drive. (Null incremental build = fully built tree. no need to rebuild anything).
In the last few releases we knocked that down from about 63 seconds.
Currently we're working on a number of performance related items and hope to make some strides here.
Note the article sited is fairly old: https://github.com/scons/scons/wiki/WhySconsIsNotSlow (from before 2.4).
That said there are (currently) faster build systems. SCons tends to be most valuable when the build is complicated.
So as you can see.. the current maintainers don't argue that there are no performance issues with SCons. But we're working on them.
Try Meson instead:
ihmo CASE (really automated policy configuration) is what people are now calling "AI". It's really just a computer augmenting and assisting a human's decision making.
Is it some sort O(n^2) rule handler deep inside the builder? Or is it just "python-slow" ? :/
Can someone give an example of a big open source project which is too slow to build?
Of course if you only ever build from scratch, on one core, compile time will dominate, and you will wonder what the fuss is about.
Using Ninja as a benchmark, most of these higher level build systems take a lot of time to determine they have little to do, while ninja instantly determines this. The build performance rarely matters, the incremental build performance is where you waste a lot of time. Especially if you do TDD cycles.
Imagine if CMake were separated into a front-end and back-end. You could use a super nice Scons-esque pythonic front-end instead of CMake's crappy proprietary language and still have all the benefits of CMake!
Ninja is indeed a build system backend but it's too low level. I want a intermediate to high level backend that abstracts common things I want to do.
If you think about it though, it's not hard to cons up a tool that files objects on disk by normalizing all the inputs to a compile step, and retrieving that object if it exists. Here's one but there's others.
http://beza1e1.tuxen.de/version_control_and_build_systems.ht...
Now that's a VCS I have not heard mentioned in a long time. I shudder to think some entrenched legacy project is still stuck on ClearCase.
Scons is 19 years old...