Examples¶
Every example below is a self-contained project with its own pcons-build.py,
built and verified on Linux, macOS and Windows on every commit. If it's listed
here, it works.
Browse them at github.com/DarkStarSystems/pcons/tree/main/examples, or copy one and build it:
| Example | What it shows |
|---|---|
01_hello_c |
The simplest pcons build: one C file, one program |
02_multi_file |
Demonstrates building a multi-file C project with include directories |
03_variants |
Demonstrates debug/release build variants using env.clone() |
04_transitive_deps |
Demonstrates transitive include directory propagation |
05_multi_library |
Demonstrates multi-library builds with transitive dependencies |
06_archive_install |
C program with Tarfile archive installers |
07_conan_example |
Example showing how to use Conan packages with pcons |
08_custom_tool |
Demonstrates creating a custom tool that concatenates files |
09_makefile |
Demonstrates Makefile generation with pcons |
10_paths_with_spaces |
Paths with spaces throughout: a source file, its directory, an include directory, and a define whose value contains spaces |
11_windows_resource |
Demonstrates compiling Windows resource files (.rc) with MSVC |
12_env_override |
Demonstrates env.override() for per-file compiler settings |
13_subdirs |
Nested subdirectories with add_subdirectory() |
14_install_dir |
InstallDir for recursive directory copying |
15_custom_builder |
Demonstrates creating a custom builder with the @builder decorator |
16_xcode |
Demonstrates Xcode project generation (macOS only) |
17_object_sources |
Per-file flags: add_sources(env=...) inside a target, and standalone env.cc.Object() |
18_static_into_shared |
Tests linking a static library into a shared library |
19_installers |
Demonstrates platform-specific installer creation (.pkg/.dmg on macOS, .msix on Windows) |
20_windows_manifest |
Windows SxS: an embedded app manifest and a private assembly that actually loads |
21_msvcup_hello |
Demonstrates building with msvcup-managed MSVC (no Visual Studio required) |
22_wasm_wasi |
Demonstrates compiling a C program to WebAssembly via wasi-sdk |
23_wasm_emscripten |
Demonstrates compiling a C program to WebAssembly via Emscripten |
24_configure_file |
Demonstrates compiler feature checks feeding configure_file() |
25_fortran_hello |
Demonstrates compiling a simple Fortran program with gfortran |
26_fortran_modules |
Demonstrates Fortran modules with correct dyndep dependency ordering |
27_fortran_calls_cxx |
Fortran primary calling C++ via BIND(C) interface, with automatic C++ runtime injection |
28_cxx_calls_fortran |
C++ primary calling Fortran via BIND(C), with automatic Fortran runtime injection |
29_cxx_modules |
Demonstrates C++20 named modules with Ninja dyndep ordering |
30_cxx_partitions |
C++20 module partitions: interface partition + internal partition + module impl unit, all in .cpp files |
30_restat |
Demonstrates restat to avoid unnecessary rebuilds from code generators |
31_cxx_modules_optin |
Module units in .cpp files (env.cxx.modules opt-in) |
31_pkg_config |
Build a library and generate a pkg-config .pc file |
32_cxx_import_std |
C++23 import std; — multi-toolchain support (clang, gcc, msvc) |
32_latex |
LaTeX PDF compilation via latexmk |
33_path_in_flags |
Demonstrates using PathToken to embed paths in linker flags |
34_multi_build_dir |
Demonstrates separate build directories using --variant (CMake-style) |
35_cxx_modules_deps |
Demonstrates C++20 named modules with Ninja dyndep ordering |
36_cxx_modules_multi_level_subdirs |
Demonstrates multi-level subdirectories with C++20 named modules |
37_cxx_import_std_header_deps |
Header touch should rebuild regular .cpp object even when modules mode is enabled |
39_bmi_compat |
C++20 module interface (BMI) reuse across targets, keyed by BMI-sensitive flags |
40_unit_tests |
Demonstrates project.Test() builder, the JSON manifest, and ninja test |
41_fuzzing |
libFuzzer fuzz target with a regression test and a short campaign |
42_nested_metadata |
Nested Project() instances each get their own metadata entry with no duplicated targets |
43_rust_cxx_hybrid |
Build a Rust staticlib via cargo and link it into a C++ program |
44_rust_cxx_cbindgen |
Generate a C header from a Rust crate via cbindgen, then link the staticlib into C++ |
45_rez_integration |
pcons reads a rez resolve and builds against rez-resolved packages |
46_swift_hello |
Demonstrates building a Swift program (whole-module compilation) |
47_swift_library |
Demonstrates a Swift library with cross-module import and a Test() target |
48_swift_cxx_interop |
Demonstrates bidirectional Swift/C/C++ interop (modulemap import + generated -Swift.h) |
49_swift_ios |
Demonstrates cross-compiling Swift for iOS via the ios() cross preset |
50_pyproject |
Build a Python extension using the pyproject.toml backend and run its tests |
51_ios_objcxx |
Cross-compiles C++ and Objective-C++ for iOS via the ios() cross preset |
52_qt_widgets |
Qt Widgets app via QtProgram: automoc, .ui and .qrc in sources |
53_qt_explicit |
Qt low-level builders: explicit moc (header and source mode) and rcc |
54_qt_qml |
QML module via QtQmlModule: QML_ELEMENT types, qmldir, embedded QML |
55_qt_translations |
Qt translations: lrelease-compiled .qm catalogs embedded as resources |
56_qt_deploy |
Qt deployment: macdeployqt makes a relocatable .app (ninja deploy) |
57_staged_generation |
Targets discovered from a manifest the build itself produces, via the build.ninja regen edge |
58_system_includes |
Third-party headers via system_includes and system=True packages: found like -I, exempt from -Werror |
59_codegen_sources |
A built generator plus a variable-length input list: declared source order, ${SOURCES[n:]} slices, and a globbed directory as a configure dependency |
60_command_cwd |
A generator that must run from the source root: env.Command(cwd=...) moves the command and its paths, and write_if_different keeps identical output from rebuilding the world |
61_command_substitution |
Markers embedded in an argument: ./${SOURCES[0]}, --out=$TARGET, a prefix repeated over a slice, and $$ for a literal dollar |
62_metal_library |
project.MetalLibrary compiles .metal shaders and links them into a loadable .metallib |
63_command_launcher |
Commands run behind a launcher: two stacked wrappers (a compiler-cache stand-in and a timer) in front of every C compile, a third belonging to a single command, and compile_commands.json still reporting the real compiler |
64_persistent_worker |
An action run in a persistent worker: the worker holds the expensive setup, each action gets a fresh forked child, and the build works the same when no worker can be reached |
65_user_commands |
Commands declared by the build script, reachable as pcons run <name>: an option, a group with its own subcommands, and a command reading the resolved project |
66_multi_project |
Two independent top-level projects built in one pcons run |
67_embedded_build |
pcons as a library: an embedded build step and a custom CLI driver |
68_command_dependencies |
A declared command names the targets it needs, and pcons run builds them before dispatching |
69_custom_tools_pipeline |
Custom tools chained into a document pipeline (git version -> pandoc -> footer) |
70_scene_packs |
Content-discovered build order via a Scanner, over two generations of generated sources |
71_cxx_modules_codegen |
A generated C++ source alongside a C++20 module interface: per-target scanning keeps the generator out of the consumer's scan (issue #105) |
72_cxx_modules_codegen_interface |
A C++20 module interface unit written by a program the build compiles: the suffix is static, the scan waits for the generator, and the BMI is discovered |
73_command_env |
Per-command environment variables: env_vars= reaches its own command and no other, via env(1) on POSIX and the pcons env helper on Windows |
74_bare_metal |
A Cortex-M3 firmware and its host tools in one project: a cross toolchain via CrossPreset, a host-built generator, and one checksum library built for both worlds, each environment owning its build directory |
75_multi_env |
One project, two named environments: each owns its build directory, so one library and one program name serve both, and one subdirectory is included once per environment |