scons: a bundled DocBook stylesheet whose licence the manifest cannot express, and Python 3.8 pinned to a build from sixteen days ago
SCons - a software construction tool
At a glance
- What is it?
- SCons is a build tool whose configuration files are Python scripts rather than a build specific language, and it has been stable for two decades. Two things on its front page are worth reading closely. Its package manifest declares MIT and ships a copy of the DocBook stylesheet, whose own terms the author tried to express as a compound licence expression and could not. And its Python compatibility table leaves anyone on 3.7 or 3.8 pinned to a release that is already superseded.
- Who is it for?
- SCons suits a project with heterogeneous sources that wants dependency analysis and parallel builds without maintaining generated dependency files, and it remains the most pleasant way to describe a build in a language you already write. Two things to check before you rely on it.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 7, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A bundled stylesheet whose licence the manifest could not express
The package metadata is careful almost everywhere, and in one place the care ran into a tooling wall and the author left a note about it.
license = "MIT" # PEP 639 form (new - setuptools >= 77.0)
# Should include docbook license, but this fails:
# license = "MIT AND DocBook-stylesheet"
license-files = [
"LICENSE",
"SCons/Tool/docbook/docbook-xsl-1.76.1/COPYING",
]The project bundles a copy of the DocBook stylesheet inside its own tool directory, at a pinned version, and that stylesheet carries its own terms. The author wanted to express that as a compound licence expression and found that it did not build. So the field says MIT, the stylesheet's own licence file is listed as one of the files being shipped, and the failed attempt is left in place as a comment.
That is a transparent way to leave a known gap. It is also still a gap. Anything that reads the licence field programmatically, which is what a dependency scanner, an internal policy engine, or a corporate licence audit does, sees a package that is unambiguously MIT. The stylesheet it actually ships is under different terms, and the only evidence of that lives in a comment and in a filename.
Compare it with how the Purpur Minecraft server project handles the same class of problem, which is worth doing because the contrast is instructive. That project states that all patches are MIT except where a patch header says otherwise, and it links both the upstream project and its build tooling for the terms of material used from them. Three layers, each attributed, with the exception mechanism located in the file rather than in a global statement.
Neither approach is wrong, but one of them survives being read by a machine.
Python 3.8 users are pinned to a build from sixteen days ago
Running SCons requires Python 3.9 or higher, and there should be no other dependencies or requirements. That is the execution requirement, and it is the simplest statement on the page.
Below it is a compatibility table that reads like a project with a long memory, which SCons is:
The last release to support Python 3.7 or Python 3.8 is 4.11.0. The last release to support Python 3.6 was 4.8.1. The last release to support Python 3.5 was 4.2.0.
The package metadata agrees: a floor of 3.9, and classifiers listing 3.9 through 3.14 with a 3 only marker.
What the compatibility table does not say is how recently the boundary moved. Version 4.11.0 was published on 2026-08-11. Version 4.11.1 was published on 2026-08-27, sixteen days later. So the last release any Python 3.7 or 3.8 user can install is already superseded, and the page does not draw attention to it.
The consequence is narrow but total. There is no 3.8 branch to follow and no security backport path mentioned, because the project does not appear to maintain one. A user on 3.8 is not choosing between supported options; they have a single build, sixteen days old, and the trend is one way.
The page is honest that some experimental features need more than the standard requirements. At the moment the Ninja feature requires the separate ninja package. That is the correct arrangement for an optional acceleration path, and it is the only dependency the front page acknowledges.
Four readme files and three requirements files, one of which disclaims itself
The root listing is long, and most of its length comes from a project that has been building itself for two decades. Two groups of near-duplicate files stand out.
The first is documentation. There are four readme files at the root. One is the reStructuredText file the site is built from. One is the version the source distribution and package index show. One is a local variant for running from a checkout. And one is named for the SourceForge hosting the project grew up on.
That is not accidental duplication, it is a convention. The site build renders one, a published package has to embed a different one because reStructuredText directives and badges do not survive a PyPI description unchanged, and the SourceForge file exists for the download page that predates the current site. A reader arriving at the repository can work out the mapping in a minute, and the page uses the site form.
The second group is dependency files, and here one of them says it should not exist:
# No dependencies for running SCons
#
# This file isn't really needed as any required deps covered by pyproject.tomlThat is `requirements.txt`, and it is right: the project genuinely has no runtime dependencies. Alongside it sit a development requirements file and a package requirements file, so three files where one would do, with the redundant one honest about being redundant. A file that documents its own superfluity is a small good, and it is also one fewer thing a reader has to puzzle over.
The rest of the listing explains itself: a build directory, because SCons bootstraps itself, a template directory for site scaffolding, a documentation directory, a testing framework directory, a benchmarks directory, a timing corpus, and a news directory holding per release notes.
setup.py exists to strip the word Tests out of a package list
The project has both a pyproject file and a setup script, which is a common transitional arrangement and usually harmless. Here the setup script has exactly one job and it is a small one.
It subclasses the standard build command and overrides the method that finds package modules, so that any module whose name matches the pattern `*Tests` is dropped before the build collects it. The comment above the pattern says the modules matching it are stripped out.
So the reason a legacy setup script is still in the tree is not that the package needs one. It is that the unit test modules live inside the package directory, and something has to keep them out of the distributed wheel. That is a real problem with a real but inelegant solution, and moving the tests outside the package would remove the need for the file entirely.
The build backend itself is unremarkable: setuptools through the standard build meta interface, with setuptools as the only build requirement and no version floor. Given that the manifest contains a comment noting the licence field requires setuptools 77 or later, that is a slight inconsistency in an otherwise careful file, though the build requirement and the metadata field are often permitted to differ in practice.
Elsewhere in the same file the project is thorough: a dynamic version, an author with a contact address, a classifier block that runs from development status through operating systems, and a full set of URLs including the homepage, documentation, a code host, an issue tracker, a chat invite and mailing lists. It also declares three console scripts, for the main tool, the signature database utility, and a cache configuration helper, which matches the three executables the Windows install notes say pip will warn about.
Four AppVeyor references and two Travis directories for a project that moved
The build history in this repository is visible in its file names, which is unusual and mildly confusing to read for the first time.
For continuous integration there is an AppVeyor configuration file at the root and a second file inside a directory named for the same service, plus a Devin configuration directory and a Travis configuration file at the root with a second directory named for Travis. There is also a lgtm configuration file, which is a static analysis service that has since been acquired by another vendor and folded into a different product.
So the root of a project whose own front page advertises a GitHub Actions badge carries configuration for four or five separate external services, several of which no longer exist under their own names. That is not sloppiness on the project's part. It is what two decades of accumulated history looks like when a build system has never been thrown away, only appended to.
The current one is there too, in a GitHub directory alongside a workflows badge on the front page, so a reader can find the live configuration without much difficulty. The difficulty is in establishing which of the others still do anything.
Two other files in the listing are worth knowing about, and both are good practice rather than artefacts. There is a file listing revisions to ignore when attributing blame, which is what you commit after rewriting history so that a reformat does not appear in every contributor's share of the blame. And there is a test ignore list, a plain text file listing tests that exist but do not run, sitting beside the test configuration and the editor configuration file.
That test ignore list is the same kind of artefact as the static analysis baseline elsewhere in this batch of work, and the same advice applies. It is a suppressed test, which is quiet where a failing test is loud, so it is worth knowing the size of before you trust a green run.
The homepage is recorded over http while the manifest uses https
A small inconsistency, and one that recurs across projects: the address of the project appears in more than one form.
The homepage recorded in repository settings is `http://scons.org`. The package manifest records its homepage as `https://www.scons.org/`. The front page links its documentation at `https://scons.org/documentation.html` without the subdomain, and its download link at `https://www.scons.org/pages/download.html` with it.
Four appearances, two schemes and two host forms, in no consistent order. The front page itself does not flag it, and the two forms are both reachable.
This matters in a build tool more than in most projects, and the reason is specific. A build system's job is to fetch things, and the tools it fetches are frequently discovered by following links in a build file or a configuration document. A non-TLS project address that gets copied into a project's own metadata, its documentation, or a vendoring manifest, propagates quietly and is then inherited by everything downstream.
The fix is a field in repository settings and one string in the manifest. Worth asking a maintainer for, and worth checking in your own projects while you are looking.
Editorial conclusion
SCons suits a project with heterogeneous sources that wants dependency analysis and parallel builds without maintaining generated dependency files, and it remains the most pleasant way to describe a build in a language you already write. Two things to check before you rely on it. The DocBook stylesheet question matters if you distribute SCons inside anything, because the manifest declares MIT, ships a copy of that stylesheet's licence file, and carries a commented out attempt at expressing the compound licence that failed. Establish the terms yourself rather than reading the licence field. And note the Python floor: 3.9 or higher, with 3.7 and 3.8 frozen out as of a release from mid August. Anyone on an older interpreter is not choosing between options, they have one build. The project's own engineering tells are encouraging if you need to read the source: it has a test ignore list, a static analysis configuration, commit history rewritten to drop specific revisions from blame, an editor ignore file, per file lint overrides, and a named tests directory separate from the unit test suite. The four readme files are explained once you know the convention, the build directory is self hosting by design, and the root is untidy in the ordinary way of a project with a very long history. The open issue count is the one number to interpret with care, since a tool this old accumulates a permanent backlog and the count alone says more about reporting volume than about health.
Frequently asked questions
What is a SCons?
An open source software construction tool that decides which components need building or rebuilding and invokes the commands to build them. Its configuration files are Python scripts rather than a build specific language, and dependency analysis is built in for C, C++ and FORTRAN, so no separate pass to generate dependencies is needed.
How do I install SCons?
Through pip or an equivalent package installer, and the page suggests a virtual environment to isolate the Python to one project. It says SCons has no installation dependencies beyond a compatible Python, and running it requires Python 3.9 or higher with no other requirements.
how to add scons to path
This is the Windows case the page covers in detail. A pip install places an scons executable in the scripts directory of the Python installation, or in a shadow scripts directory for a user install, and pip warns when that directory is not on PATH, printing the exact path and offering either to add it or to suppress the warning.
how to install scons on windows
The page gives a Windows variant assuming the Python Launcher alongside the general pip command, and notes that a pip install on Windows puts the executable in the Python installation's scripts directory rather than adding it to PATH. The default compiler assumption on Windows is the Microsoft Visual C++ suite, and a Cygwin platform selector is available.
Is it "SCons" or "scones"?
SCons, in full capitals, with no trailing e. The distribution name in the package metadata is SCons, the console scripts are named scons and sconsign, and the project's own site is scons.org.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/scons-scons)