|
1 | 1 | # SCons - Software Construction Tool |
2 | 2 |
|
3 | | -## Project Overview |
4 | | -SCons is an open-source software construction tool (build tool) implemented in Python. It is designed to be easier to use and more reliable than the traditional `make` utility. SCons configuration files are Python scripts, allowing users to use the full power of Python to solve build problems. |
| 3 | +## Build & Run |
5 | 4 |
|
6 | | -**Key Features:** |
7 | | -* Configuration files are Python scripts. |
8 | | -* Built-in support for C, C++, D, Java, Fortran, Yacc, Lex, Qt, SWIG, and TeX/LaTeX. |
9 | | -* Reliable dependency analysis (implicit and explicit). |
10 | | -* Support for parallel builds. |
11 | | -* Cross-platform (Linux, POSIX, Windows, macOS). |
12 | | - |
13 | | -## Building and Running |
14 | | - |
15 | | -### Prerequisites |
16 | | -* Python 3.7 or higher. |
17 | | -* Development dependencies: `python -m pip install -r requirements-dev.txt` |
18 | | - |
19 | | -### Running SCons (Development) |
20 | | -You do not need to install SCons to run it from the source tree. |
21 | | - |
22 | | -**Linux/macOS:** |
23 | 5 | ```bash |
24 | | -python scripts/scons.py [arguments] |
| 6 | +python scripts/scons.py # build packages (wheels, tarballs, zips → build/) |
| 7 | +python scripts/scons.py doc # docs only |
| 8 | +python scripts/scons.py [args] # run SCons from source (no install needed) |
25 | 9 | ``` |
| 10 | +SCons builds itself. The repo root `SConstruct` is the build script for packaging. |
26 | 11 |
|
27 | | -**Windows:** |
28 | | -```cmd |
29 | | -py -3 scripts\scons.py [arguments] |
30 | | -``` |
31 | | - |
32 | | -### Building SCons |
33 | | -SCons uses itself to build its own packages. |
| 12 | +## Testing |
34 | 13 |
|
35 | | -**Full Build (Packages & Docs):** |
36 | 14 | ```bash |
37 | | -python scripts/scons.py |
| 15 | +python runtest.py -a # all tests |
| 16 | +python runtest.py SCons/SConfTests.py # unit test |
| 17 | +python runtest.py test/Configure/ConfigureDryRunError.py # e2e test |
| 18 | +python runtest.py --retry # re-run last failures (reads failed_tests.log) |
| 19 | +python runtest.py -j 0 # parallel (cpu_count) |
| 20 | +python runtest.py -t # print timing |
38 | 21 | ``` |
39 | | -This produces artifacts (wheels, tarballs, zips) in the `build/` directory. |
40 | 22 |
|
41 | | -**Build Documentation Only:** |
| 23 | +For more complete testing, the dependency set `[dev]` from `pyproject.toml` |
| 24 | +is useful. |
| 25 | + |
42 | 26 | ```bash |
43 | | -python scripts/scons.py doc |
| 27 | +python bin/docs-validate.py |
| 28 | +python scripts/scons.py doc SKIP_DOC=pdf,api |
44 | 29 | ``` |
45 | 30 |
|
46 | | -## Testing |
47 | | -The project uses a custom test runner script, `runtest.py`. |
| 31 | +| Type | Location | Pattern | |
| 32 | +|------|----------|---------| |
| 33 | +| E2E | `test/**/*.py` | Custom `TestSCons` (subclass of `TestCmd`) with `test.run()` / `test.pass_test()` | |
| 34 | +| Unit | `SCons/*Tests.py` | Standard `unittest.TestCase`, also use `TestCmd`/`TestSCons` for setup | |
| 35 | + |
| 36 | +The test runner (`runtest.py`) adds `SCons/` and `testing/` to `PYTHONPATH` automatically. E2E tests create a temp workdir per run. Use `SCons.Debug.Trace()` for print debugging (won't interfere with test output capture). |
| 37 | + |
| 38 | +## Codebase Architecture |
| 39 | + |
| 40 | +**Core engine (`SCons/`):** |
| 41 | +- `Script/Main.py` - entry point (`main()`). |
| 42 | +- `Environment.py` - `Environment` class; construction variable management. |
| 43 | +- `Builder.py` + `Action.py` - define how targets are built and what commands execute. |
| 44 | +- `Node/` — dependency graph: `FS.py` (File, Dir, Entry), `Alias.py`, `Python.py`. |
| 45 | +- `Taskmaster/` - parallel job scheduling and task execution. |
| 46 | +- `SConsign.py` - `.sconsign.dblite` persistence (single file at build top, keyed by dir path). |
| 47 | +- `Subst.py` - variable substitution (`$CC`, `$CFLAGS`, etc.). |
| 48 | +- `Scanner/` - dependency scanners (C/C++ `#include`, etc.). |
| 49 | +- `CacheDir.py` - shared build-artifact cache. |
| 50 | +- `SConf.py` - `Configure()` logic. |
| 51 | +- `Warnings.py` - warning hierarchy (stderr via `warn()`). |
| 52 | +- `Tool/` - compiler/linker integrations (CC, CXX, MSVC, Ninja, Docbook, etc.). |
| 53 | +- `Script/` - CLI entry points, option parsing (`SConsOptions.py`). |
| 54 | +- `Platform/` - OS-specific adaptations. |
| 55 | +- `Variables/` - `PathVariable`, `BoolVariable`, etc., for build configuration. |
| 56 | + |
| 57 | +**Tests:** |
| 58 | +- `testing/framework/` — `TestSCons.py`, `TestCmd.py` (e2e test base classes). |
| 59 | +- `test/` — ~200+ e2e tests organized by feature. |
| 60 | +- `SCons/*Tests.py` — unit tests alongside source, standard `unittest.TestCase`. |
| 61 | + |
| 62 | +**Documentation:** |
| 63 | +- `doc` documentation sources, tools, extended DocBook schema |
| 64 | +- `SCons/*.xml` - module-specific documentation sources |
| 65 | + |
| 66 | +## Documentation |
| 67 | + |
| 68 | +The doc build requires the dependency set `[doc]` from `pyproject.toml`. |
| 69 | +For validating just that the Docbook xml documents build, use |
48 | 70 |
|
49 | | -**Run All Tests:** |
50 | 71 | ```bash |
51 | | -python runtest.py -a |
| 72 | +python bin/docs-validate.py |
| 73 | +python scripts/scons.py doc SKIP_DOC=pdf,api |
52 | 74 | ``` |
53 | 75 |
|
54 | | -**Run Specific Tests:** |
55 | | -```bash |
56 | | -python runtest.py SCons/BuilderTests.py # Unit test |
57 | | -python runtest.py test/option/option-j.py # End-to-end test |
58 | | -``` |
| 76 | +Individual xml files are not syntactically complete DocBook, |
| 77 | +they require the context of xincluded files (`.mod` and `.gen` |
| 78 | +from `doc` and `doc/generated`), the SCons schema extension |
| 79 | +(`doc/xsd`), and the framework from `bin/SConsDoc.py`, |
| 80 | +which also contains information on some of the extensions. |
| 81 | + |
| 82 | +## Lint & Type |
59 | 83 |
|
60 | | -**Run Failed Tests (Retry):** |
61 | 84 | ```bash |
62 | | -python runtest.py --retry |
| 85 | +python -m ruff check . # lint (target-version py37, skips test/ bench/ doc/ etc.) |
| 86 | +python -m ruff format --check . # formatting check |
| 87 | +python -m mypy SCons/ # type check |
63 | 88 | ``` |
64 | 89 |
|
65 | | -**Test Types:** |
66 | | -* **Unit Tests:** Located in `SCons/` alongside the source files (e.g., `SCons/Builder.py` -> `SCons/BuilderTests.py`). |
67 | | -* **End-to-End Tests:** Located in the `test/` directory. These run SCons against sample projects. |
68 | | - |
69 | | -## Development Conventions |
70 | | - |
71 | | -* **Code Style:** Follows Python PEP 8 (mostly). The project includes a `.editorconfig` file. |
72 | | -* **Version Control:** Git is used. Commits should be signed off (`git commit -s`). |
73 | | -* **Debugging:** |
74 | | - * Use `--debug=pdb` when running SCons to drop into the Python debugger. |
75 | | - * Use `SCons.Debug.Trace()` for print debugging in a way that doesn't interfere with test output capturing. |
76 | | -* **Directory Structure:** |
77 | | - * `SCons/`: Core engine source code and unit tests. |
78 | | - * `test/`: End-to-end system tests. |
79 | | - * `scripts/`: Wrapper scripts (e.g., `scons.py`). |
80 | | - * `bin/`: Development utilities. |
81 | | - * `doc/`: Documentation source (DocBook/XML). |
82 | | - * `template/`: Templates for file generation. |
83 | | - * `testing/framework`: Test framework used by the end-to-end tests. |
84 | | - |
85 | | -## AI Contribution Policy |
86 | | -If contributing AI-generated code: |
87 | | -1. You take full responsibility for the code quality and license. |
88 | | -2. Disclose AI use in the commit message (e.g., `Assisted-by: ModelName`). |
| 90 | +`.editorconfig` enforces: indent 4 spaces, 88-char line limit (Python/SConstruct/SConscript), LF line endings, trailing comma, parentheses for multiline. |
| 91 | + |
| 92 | +## Conventions |
| 93 | + |
| 94 | +- Git commits signed off (`git commit -s`). Add `Assisted-by:` to message for AI-generated changes. |
| 95 | +- Version in `SCons/__init__.py` (`__version__`) - automatically generated, do not edit. |
| 96 | +- CI: GitHub Actions (`runtest.yml` - test suite; `scons-package.yml` — packaging), AppVeyor (Windows, legacy). |
| 97 | +- Python >= 3.7 required. |
| 98 | +- Config log for `Configure()` lives at `config.log` in the build dir. |
| 99 | +- `.sconsign.dblite` persists across builds; deleting build dirs from disk doesn't clear sconsign entries. |
0 commit comments