SC::Tools are self contained single C++ source files that are (automatically) compiled on the fly and linked to Sane C++ to be immediately executed.
They leverage the growing shell, system and network programming capabilities of Sane C++ Libraries, by just including the SC.cpp unity build file, that has no third party dependencies (see Building (Contributor)).
Another way to look at them is just as small C++ scripts for which you don't need to setup or maintain a build system, as long as you only use Sane C++ Libraries.
SC::Tools and not SC::Scripts because they're still just small programs. Some relevant blog posts are:
SC::Tools has been created for the following reasons:
Tools/SC-package.cpp uses SC::Process library to download some third party binaryTools/SC-package.cpp uses SC::Hashing library to check downloaded package hashesTools/SC-format.cpp uses SC::FileSystemIterator library to find all files to format in the repoAll built-in tools are invoked with the SC.sh or SC.bat bootstrap script that is located in the root of the repo.
Such script must be called with the name of the tool and some parameters.
For Example, invoking the Tools\SC-build.cpp tool with configure action:
or (on Windows)
SC::Tools are just regular programs being compiled on the fly when needed, so they require a working host compiler to be available in system path. This limitation could be removed if needed, as described in the Roadmap section. External projects should use SC-build.sh, SC-build.bat, or SC-build.ps1 instead of the repository-only SC.sh build ... entrypoint.
Those launchers:
SC-build.cpp--project-dir <path> and --libraries-root <path> overridesSee External SC::Build Bootstrap for the full workflow and examples.
Tools can be automatically compiled and run by just passing its full path to the SC bootstrap.
Given the following custom tool at myToolDirectory/TestScript.cpp
This is how to invoke the tool with action and some parameters
or (on Windows):
Possible output (Posix):
This is the list of tools that currently exist in the Sane C++ repository.
SC-build configures generated projects and can also build Sane C++ repository targets directly through the standalone native backend in SC::Build.
configure: Generates repository projects into _Build/_Projects/<Generator>/<Workspace>compile: Builds one project or an entire workspace through the selected backendrun: Builds a single executable target if needed and then runs itcoverage: Builds clang coverage output into _Build/_Coveragedocumentation: Builds the documentation into _Build/_DocumentationSC-build command shape:
Generator keywords are default, native, make, xcode, vs2022, and vs2019.
Named options are:
-c, --config <NAME>-g, --generator <NAME>-a, --arch <NAME>--target <PROFILE> (compile / run)--toolchain <NAME>--triple <VALUE>--sysroot <PATH>--runner <MODE> (run)--runner-path <PATH> (run)-o, --output <MODE> (compile / run)-q, --quiet (compile / run)--normal (compile / run)-v, --verbose (compile / run)Target profiles currently exposed by the CLI are host, native, linux-glibc-x86_64, linux-glibc-arm64, linux-musl-x86_64, linux-musl-arm64, windows-gnu-x86_64, windows-msvc-x86_64, windows-msvc-arm64, and windows-gnu-arm64.
Toolchain keywords currently exposed by the CLI are default, host-default, clang, filc, gcc, msvc, clang-cl, and llvm-mingw.
Runner keywords currently exposed by the CLI are auto, none, wine, qemu, and custom.
--triple and --sysroot are the current raw escape hatches for advanced toolchain overrides. When combined with --target, the raw overrides win.
Contradictory explicit combinations such as mismatched --generator, --arch, --runner, or --triple values now fail early with concrete CLI errors instead of drifting into backend-time failures.
Current defaults:
default resolves to vs2022default resolves to makeconfigure stepglibc and musl target profiles now shape canonical target triples and sysroot flags; macOS and Windows hosts auto-select a packaged LLVM toolchain for those profiles when the caller does not provide explicit compiler paths, and macOS now also auto-selects packaged Linux glibc/musl sysroots for themSCTest compile validation for linux-glibc-x86_64, linux-glibc-arm64, linux-musl-x86_64, and linux-musl-arm64x86_64 and arm64 targets through packaged llvm-mingwSC-package install filc plus build ... --toolchain filc; this is compiler-first Linux support for native x86_64 output only and is not yet a public target-profile row./SC.sh package install msvc and compile windows-msvc-x86_64 and windows-msvc-arm64windows-msvc-x86_64 and windows-msvc-arm64; ./SC.sh package install msvc auto-prefers a generated box64 + wine64 wrapper when those tools are available, can fall back to an auto-installed packaged Linux Wine runner that resolves a maintained generic-arm box64 build when system box64 is absent, and native build run can now auto-install a separate ARM64 Wine runtime for windows-*-arm64 execution while still accepting plain wine64 / wine or an explicit --wine / SC_MSVC_WINE overrideSC-package install msvc now also accepts --import-directory <path> and --wine <path> so imported layouts and custom Wine wrappers can be selected directly from the command linewindows-msvc-* builds can reuse the recorded wrapper path from sc-msvc-package.json instead of depending on SC_MSVC_WINE or host Wine discovery againsc-msvc-package.json metadata and wrapper scripts in place, and SDK version detection now falls back from Windows Kits/10/bin to Include or Lib when SDK tools are absentmacOS vs Linux) so shared workspaces do not reuse the wrong recorded Wine runner path across hostsSCTest compiles for both windows-msvc-x86_64 and windows-msvc-arm64, plus targeted BaseTest/new-delete runs for both targets through the maintained packaged Box64 runner (x86_64) and the packaged native ARM64 Wine runner (arm64)--runner qemu or --runner auto to wrap build run through a managed SC-package install qemu registration or a host qemu-user executable from PATH; the runner passes -L <sysroot> so the Linux loader and runtime libraries resolve from the selected sysrootbuild run can auto-route windows-gnu-x86_64 through Wine on macOS and Linux, and Linux arm64 now also smoke-runs windows-gnu-arm64 through the packaged native ARM64 Wine runnerbox64 + wine64 wrappers when those host tools are available; Linux x64 console targets still switch to a sibling wineconsole --backend=curses wrapper when it is present, while Linux arm64 now stays on plain packaged wine because that is more reliable than wineconsole on the current Box64 stackwindows-msvc-x86_64 validation scope is a real compile, link, and tiny-start smoke through Wine; Linux arm64 now also has targeted SCTest smokes for both windows-msvc-x86_64 and windows-msvc-arm64build run now launches Wine through cmd /c with a Windows-style target path, which fixes real macOS startup for windows-gnu-x86_64windows-gnu-arm64 and windows-msvc-arm64 are no longer rejected by a hardcoded CLI rule; Linux arm64 now has a real ARM64-capable Wine runtime for targeted smokes, while the packaged macOS Wine runner still lacks an ARM64 Windows loadertarget as [config] [generator] [arch] [output]Configure project, generating them:
Possible Output:
Build all projects
Build through the native backend
Prepare the packaged host LLVM toolchain for Linux targets
Register an imported QEMU user-runner layout for foreign Linux build run
Register an imported Fil-C installation and compile a native Linux target through the experimental compiler-first path
Cross-compile a Linux glibc executable through the native backend with the packaged macOS sysroot path
Cross-compile a Linux musl executable through the native backend with the packaged macOS sysroot path
Cross-compile a Windows GNU executable through the native backend
Acquire the portable MSVC package and cross-compile a Windows MSVC executable on macOS
Cross-compile a Windows MSVC arm64 executable on macOS
Cross-compile a Windows GNU arm64 executable
Cross-compile through a friendly profile and then override the raw toolchain details
Smoke-run a Windows GNU x86_64 executable through the shared runner model
Run a generated-backend executable and pass extra test arguments after --
Open generated projects:
_Build/_Projects/XCode/SCWorkspace/SCWorkspace.xcworkspace_Build/_Projects/VisualStudio2022/SCWorkspace/SCWorkspace.sln_Build/_Projects/VisualStudio2019/SCWorkspace/SCWorkspace.sln_Build/_Projects/Make/SCWorkspace/apple_Build/_Projects/Make/SCWorkspace/linuxPossible Output:
SC-package downloads third party tools needed for Sane C++ development (example: clang-format).
Proper OS / Architecture combination is selected (Windows/Linux/Mac and Intel/ARM) and all downloaded files (packages) are hash checked for correctness.
Packages are placed and extracted in _Build/_Packages while downloaded archives are reused from _Build/_PackagesCache.
install: Downloads required tools (LLVM archives / documentation tools)These are the packages that are currently downloaded and extracted / symlinked by SC-package.cpp:
LLVM 20.1.8: Downloads clang-format from the official LLVM github repository using SHA256 pinned archivesLLVM toolchain 20.1.8: Downloads the full host LLVM toolchain (clang, clang++, llvm-ar, lld) for Linux-target native-backend flows on supported hostsFil-C 0.678 (experimental): Linux-only compiler package with a pinned upstream pizfix download path plus --import-directory <path> registration for compiler-first native-backend work through --toolchain filcdoxygen: Doxygen documentation generatordoxygen-awesome-css: Doxygen awesome css (Doxygen theme)clang-format install is available on macOS ARM64, Linux ARM64/x64 and Windows ARM64/x64. llvm@20 manually (for example through Homebrew) because recent official LLVM releases no longer provide Intel macOS archives.SC-format tool formats or checks formatting for all files in Sane C++ repository
execute: Formats all source files in the repository in-placecheck: Does a dry-run format of all source files. Returns error on unformatted files (used by the CI)Format all source files in the repository
Check if all source files in the repository are properly formatted
The bootstrap batch (SC.bat) / bash (SC.sh) shell scripts are doing the following:
.cpp files are compiled (only if they're out of date) by a MakefileTools/Tools.cpp fileSC.cpp unity build file, defining main(argc, argv)$TOOL.cpp file$TOOL name is the main $ACTION by convention$ACTION and all $PARAM_X arguments passed to the bootstrap shell scripts are forwarded to the toolExample:
SC.sh $TOOL $ACTION $PARAM_1 $PARAM_2 ... $PARAM_N
Tools.cpp is shared between all compiled tools by the Makefile inside the _Build/_Tools/_Intermediates directory. Tools.cpp.SC::Tools define an handy way of invoking an on the fly compiled program that has Sane C++ Libraries. The bootstrap process bringing from the command line to final execution is the following:
./SC.sh build compile SCTest DebugSC.sh is the ${TOOL_NAME} (in this case build)SC.sh checks if Tools/ToolsBootstrap executable exists and is up to date with Tools/ToolsBootstrap.cTools/ToolsBootstrap.c to create the bootstrap executableSC.sh invokes Tools/ToolsBootstrap with the library directory, tool source directory, build directory, tool name, and any additional argumentsSC.bat setting up the MSVC environment and compiling Tools/ToolsBootstrap.exe if neededToolsBootstrap receives 3 predefined arguments: a. The directory of SC Libraries ${LIBRARY_DIR} b. The directory containing Tools ${TOOL_SOURCE_DIR} c. The build products directory ${BUILD_DIR} containing intermediates and final productsToolsBootstrap checks if the selected tool executable exists and is up to dateToolsBootstrap compiles Tools/Tools.cpp and the selected tool source (for example Tools/SC-build.cpp)ToolsBootstrap invokes the compiled tool with the original action and parametersSC-build tool then configures projects, compiles, runs, or performs the selected actionTools\Build\$(PLATFORM) makefiles.[*] Running the Sane C++ Tools scripts on a machine without a pre-installed compiler could be implemented by shipping a pre-compiled SC-package.cpp (that is already capable of downloading clang on all platforms) or by adding to the bootstrap script ability to download a suitable compiler (and sysroot).