# How to compile and run C++ code in a sandbox Write the source into a Linux microVM, build it with g++ or CMake there, and run the binary with a time limit and no network. **On Runtime g++ is already in every sandbox, and you pay only for the CPU the build uses.** Each sandbox is a Firecracker microVM running Ubuntu 24.04.5 with build-essential, and Runtime bills measured CPU at $0.025 per vCPU-hour, so a sandbox that waits between builds costs the floor of a twentieth of a vCPU. A 2 vCPU, 4 GiB sandbox costs $0.03125 an hour waiting and $0.08 an hour with both cores compiling, at the rates checked on 25 September 2026 ([pricing](/docs/pricing)). ## What the image has for C++ | Tool | In the default image | Ubuntu 24.04 package, checked 25 September 2026 | | --------- | ---------------------------- | ----------------------------------------------- | | g++, make | Yes (build-essential) | g++-13 from gcc-13 13.3.0 | | clang++ | No: `apt` package `clang` | clang-18 18.1.3 | | CMake | No: `apt` package `cmake` | cmake 3.28.3 | | gdb | No: `apt` package `gdb` | gdb 15.0.50 | | Valgrind | No: `apt` package `valgrind` | valgrind 3.22.0 | Pass `-std=c++20` for C++20: GCC makes it the default mode only from GCC 16 ([C++ status in GCC](https://gcc.gnu.org/projects/cxx-status.html)), and Ubuntu 24.04 ships GCC 13. Install anything else with `sudo apt-get install -y`, which works without a password ([the sandbox environment](/docs/sandbox-environment#what-is-installed)). ## Compile one file and run it Keep the compile and the run as two commands. The build's stderr is the compiler's diagnostics; the run's stderr is the program's own. ```ts import { Sandbox } from "withruntime"; const source = `#include #include #include int main() { std::vector v{5, 3, 9, 1}; std::ranges::sort(v); for (int x : v) std::cout << x << ' '; std::cout << '\\n'; } `; await using sbx = await Sandbox.create({ network: { internet: false }, timeoutSeconds: 300, onLeaseEnd: "stop", }); await sbx.files.write("/workspace/main.cpp", source); const build = await sbx.exec(["g++", "-std=c++20", "-O2", "-Wall", "-o", "main", "main.cpp"], { timeoutMs: 120_000, }); if (build.exitCode !== 0) throw new Error(build.stderr); const run = await sbx.exec(["./main"], { timeoutMs: 10_000 }); console.log(run.stdout); // 1 3 5 9 ``` ```python from withruntime import Sandbox source = """#include #include #include int main() { std::vector v{5, 3, 9, 1}; std::ranges::sort(v); for (int x : v) std::cout << x << ' '; std::cout << '\\n'; } """ with Sandbox.create(network={"internet": False}, timeout_seconds=300, on_lease_end="stop") as sbx: sbx.files.write("/workspace/main.cpp", source) build = sbx.exec(["g++", "-std=c++20", "-O2", "-Wall", "-o", "main", "main.cpp"], timeout_ms=120_000) if build.exit_code != 0: raise SystemExit(build.stderr) run = sbx.exec(["./main"], timeout_ms=10_000) print(run.stdout) ``` Template-heavy C++ can take longer to compile than the 60-second default for a command, so give the build its own `timeoutMs`. A timeout comes back as `timedOut: true` with the output so far, not as an exception ([run commands](/docs/javascript#run-commands)). ## Build a CMake project and run its tests Upload the source tree, install CMake, configure, build and run `ctest`. Output streams back while the build runs. ```ts check import { Sandbox } from "withruntime"; await using sbx = await Sandbox.create({ timeoutSeconds: 1800, onLeaseEnd: "stop" }); await sbx.exec("sudo apt-get update -q && sudo apt-get install -y -q cmake", { check: true, timeoutMs: 300_000, }); await sbx.network.set({ internet: false }); // nothing the tests run can call out await sbx.files.upload("./engine", "/workspace/engine"); const stream = { cwd: "/workspace/engine", timeoutMs: 900_000, onStdout: (t: string) => process.stdout.write(t), }; await sbx.exec(["cmake", "-S", ".", "-B", "build", "-DCMAKE_BUILD_TYPE=Release"], { ...stream, check: true, }); await sbx.exec(["cmake", "--build", "build", "-j", "2"], { ...stream, check: true }); const tests = await sbx.exec(["ctest", "--test-dir", "build", "--output-on-failure"], stream); process.exitCode = tests.exitCode ?? 1; ``` ```python check import sys from withruntime import Sandbox with Sandbox.create(timeout_seconds=1800, on_lease_end="stop") as sbx: sbx.exec("sudo apt-get update -q && sudo apt-get install -y -q cmake", check=True, timeout_ms=300_000) sbx.network.set(internet=False) sbx.files.upload("./engine", "/workspace/engine") opts = {"cwd": "/workspace/engine", "timeout_ms": 900_000, "on_stdout": sys.stdout.write} sbx.exec(["cmake", "-S", ".", "-B", "build", "-DCMAKE_BUILD_TYPE=Release"], check=True, **opts) sbx.exec(["cmake", "--build", "build", "-j", "2"], check=True, **opts) tests = sbx.exec(["ctest", "--test-dir", "build", "--output-on-failure"], **opts) sys.exit(tests.exit_code or 0) ``` The network rule applies at once, to connections already open too. Root inside the sandbox cannot turn it back on ([security](/docs/security)). ## Give a big build more cores `-j` should match the cores you ask for. A sandbox bursts up to `vcpu` cores and bills only what the build uses, so a larger `vcpu` shortens a parallel build without charging for cores while they sit idle. ```ts import { Sandbox } from "withruntime"; await using sbx = await Sandbox.create({ vcpu: 4, memoryMiB: 8192, diskMiB: 8192 }); const cores = await sbx.exec(["nproc"]); console.log(cores.stdout); ``` The free trial allows up to 2 vCPU and 4 GiB per sandbox ([free trial](/docs/trial)); a paid account can ask for more. ## Keep the toolchain in an image A recipe installs CMake, clang and the debuggers once, and every sandbox from the image starts with them. Building is free; the stored image is charged on its size ([custom images](/docs/images)). ```python check from withruntime import Runtime runtime = Runtime() runtime.images.build(name="cpp", recipe={"apt": ["cmake", "clang", "gdb", "valgrind"]}) with runtime.sandboxes.create(image="cpp", network={"internet": False}) as sbx: print(sbx.exec(["cmake", "--version"]).stdout) ``` For libraries from vcpkg or Conan, run their install in the recipe's `commands` while the build machine has the web. New accounts get 50 free sandbox hours, no card: ```bash no-run npx withruntime sandbox run --trial -- g++ --version ``` See also [how to run C code in a sandbox](/languages/c), [grading student code](/use-cases/grade-student-code) and [agent evals and SWE-bench](/use-cases/agent-evals-and-swe-bench). ## Sources Checked 25 September 2026. - Ubuntu 24.04 (noble) packages: [gcc-13](https://packages.ubuntu.com/noble/gcc-13), [g++](https://packages.ubuntu.com/noble/g++), [clang-18](https://packages.ubuntu.com/noble/clang-18), [cmake](https://packages.ubuntu.com/noble/cmake), [gdb](https://packages.ubuntu.com/noble/gdb), [valgrind](https://packages.ubuntu.com/noble/valgrind) - [C++ standards support in GCC](https://gcc.gnu.org/projects/cxx-status.html) Facts on this page were checked on 25 September 2026.