Guide

Tools

Learn how the bootstrap compiles small repository tools on demand and when to write one.

Tool bootstrap

Compile only what changed

Bootstrap Build ToolsBootstrap when stale
Locate tool Resolve the selected C++ source
Compile Reuse unchanged support objects
Run Forward the action and arguments

Sane C++ tools are small C++ programs compiled on demand by the repository bootstrap. They automate repository work without introducing another scripting runtime, and they exercise the same libraries that application code uses.

Why tools are C++ programs

A tool can use Process, FileSystem, Hashing, Http, and the other libraries directly. It can be debugged with a normal C++ debugger, share result-handling conventions with the repository, and run on macOS, Linux, and Windows.

The tradeoff is explicit: a working host C++ compiler is required to bootstrap the first tool. After that, unchanged tool support code is reused from _Build, so ordinary invocations only rebuild what changed.

Invoke a built-in tool

The first argument to SC.sh or SC.bat selects a tool. The next argument selects an action owned by that tool:

./SC.sh <tool> <action> [tool arguments...]

For example:

./SC.sh build compile SCTest Debug
./SC.sh package status llvm
./SC.sh format check

The words after the tool name matter. build compile stops after producing the target; build run brings the target up to date and then launches it. Arguments after -- are forwarded to the launched program.

External projects use the dedicated SC-build.sh, SC-build.ps1, or SC-build.bat launchers described in SC::Build (External use).

Write a small custom tool

Pass the path of a tool source file instead of a built-in name:

./SC.sh MyTools/InspectFiles.cpp inspect Source

A tool implements Tools::Tool::runTool and receives the selected action, remaining arguments, repository paths, and a console:

#include "Libraries/Strings/Console.h"
#include "Tools/Tools.h"

namespace SC
{
namespace Tools
{
StringView Tool::getToolName() { return "InspectFiles"; }
StringView Tool::getDefaultAction() { return "inspect"; }

Result Tool::runTool(Tool::Arguments& arguments)
{
    arguments.console.print("Action: {0}\n", arguments.action);
    for (StringView argument : arguments.arguments)
        arguments.console.printLine(argument);
    return Result(true);
}
} // namespace Tools
} // namespace SC

Use this form for repository-local automation that benefits from Sane C++ APIs. A standalone application with its own targets belongs in SC::Build instead.

How does it work

The bootstrap keeps startup work incremental. It rebuilds ToolsBootstrap only when stale, locates the selected tool source, reuses unchanged Tools.cpp support objects, compiles the tool when needed, and then runs it with the original action and arguments.

ToolsBootstrap is deliberately small. The selected tool is linked with the Sane C++ unity build, so custom tools can use the libraries without maintaining another project definition. Build products remain below _Build/_Tools.

Know the boundary

Use a tool for a bounded development operation with a command-line lifecycle. Use SC::Build for a graph of application targets. Use a library when behavior belongs in reusable program code. Keeping those roles separate prevents the bootstrap from becoming an application framework.