Step 06 · Driving the toolchain

driver.cpp owns the boring-but-critical job of turning an IR string into an executable on disk.

The pipeline as commands

$ /opt/homebrew/opt/llvm/bin/llc -O0 -filetype=obj -o /tmp/minilangc-obj-XXX.o /tmp/minilangc-ir-YYY.ll
$ /opt/homebrew/opt/llvm/bin/clang -O0 -o a.out /tmp/minilangc-obj-XXX.o

That's the whole compiler. llc lowers IR → object file (handles instruction selection, register allocation, scheduling, emission). clang acts as the linker driver — it knows how to invoke the system linker (ld64 on macOS) with the right libc paths so printf resolves.

-O<N> is forwarded to both; -v echoes the commands so users can re-run them. Both tools are looked up via ${LLVM_BIN_DIR} (settable via CMake -DLLVM_BIN_DIR=...) so the lab works on other people's machines.

Process management

We use popen (read end) for capturing combined stdout+stderr. This is good enough for our purposes:

  • Tools rarely produce large output on success.
  • On failure, we want all the diagnostic chatter.
  • No need to handle stdin (we pass IR via a file).

For production:

  • Use posix_spawn + pipes to capture stderr separately.
  • Stream to user terminal in -v mode rather than buffer.
  • Handle signals properly (Ctrl-C should kill the child).

Temp file hygiene

mkstemp("/tmp/minilangc-{tag}-XXXXXX") then rename to add the right extension. We don't clean up because:

  • On success the user doesn't care.
  • On failure the user wants to inspect the IR.

A real driver would offer --save-temps (gcc) or --keep-tmp-files. The current behaviour matches --save-temps, which is fine for an educational tool.

Why clang instead of ld directly

Calling ld directly requires knowing the platform-specific runtime glue: crt1.o, libSystem.B.dylib, the right SDK path. clang -o figures all that out by querying the macOS SDK. It's slower (one extra exec) but vastly more portable.

Testing the e2e pipeline

Tests in test_suite.cpp call toolchainAvailable() and skip e2e tests gracefully if llc isn't present. This keeps CI green even on machines without LLVM installed.