# How to compile and run C++ code in a sandbox Write the source to a Linux microVM, build it there with g++ or CMake, and run the binary with a time limit and without network access. **g++ is already in every Runtime sandbox, and you pay only for the CPU your build uses.** Each sandbox is a Firecracker microVM that runs Ubuntu 24.04.5 with build-essential. Runtime bills measured CPU at $0.025 per vCPU-hour. A sandbox that waits between builds costs at least a twentieth of a vCPU. A 2 vCPU, 4 GiB sandbox costs $0.03125 an hour while it waits and $0.08 an hour with both cores compiling. These are the rates checked on 25 October 2026 ([pricing](/docs/pricing)). ## What the image has for C++ | Tool | In the default image | Ubuntu 24.04 package, checked 26 October 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.1 | | Valgrind | No: `apt` package `valgrind` | valgrind 3.22.0 | Pass `-std=c++20` to select the standard. GCC uses C++20 as its default mode only from GCC 16 ([C++ status in GCC](https://gcc.gnu.org/projects/cxx-status.html)). Ubuntu 24.04 ships GCC 13. To install other packages, run `sudo apt-get install -y`. The command runs without a password ([the sandbox environment](/docs/sandbox-environment#what-is-installed)). ## Compile one file and run it Run the compile and the run as two separate commands. The stderr of the build holds the compiler's diagnostics. The stderr of the run holds the program's own messages. ```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 timeout for a command. Give the build its own `timeoutMs`. When a command times out, it returns `timedOut: true` and the output so far. It does not throw an exception ([run commands](/docs/javascript#run-commands)). ## Build a CMake project and run its tests Upload the source tree, install CMake, then configure, build and run `ctest`. Output streams back during the build. ```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 immediately, including to connections that are already open. Root inside the sandbox cannot turn the network back on ([security](/docs/security)). ## Give a big build more cores Set `-j` to the number of cores you request. A sandbox can burst up to `vcpu` cores and bills only the cores the build uses. A larger `vcpu` shortens a parallel build, and idle cores are not billed. This example's size is above the limit without credit. It runs only on an account that holds prepaid credit. ```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); ``` Without credit, a sandbox has up to 2 vCPU and 4 GiB ([free usage](/docs/included-usage)). A paid account can request more. ## Keep the toolchain in an image A recipe installs CMake, clang and the debuggers once. Every sandbox made from the image starts with them. Building an image is free. The stored image is billed by 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`. The build machine needs internet access during that step. A new account gets 100 free hours of a 1 GB machine in its first 30 days. No payment card is needed: ```bash no-run npx withruntime sandboxes run -- 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 26 October 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 26 October 2026.