Ray's Knowledge Base

Time two builds with one scratch program, using the build's own compile and link lines

RecipeVerified 27 Sep 2026Holds anywhere
Recipe. When to use it, the steps, and what showed that they work.

When to use#

You must A/B a code path between two versions of a CMake/Ninja project (for example a git worktree at the old commit and the working tree), no benchmark in the repo covers it, and you must not add one to either tree.

Steps#

  1. Write the timing program in a scratch folder. Use only the public headers. A helper type from the tests (such as a test sink) is not in the library, so define a small one in the program.

  2. In each tree, build a benchmark target that links the same library, so the libraries are current: cmake --build <tree>/build/build-release --target <bench>.

  3. Take that target's compile and link lines from Ninja and swap in your source, object and output:

    cd <tree>/build/build-release
    cc=$(ninja -t commands src/<bench> | grep -- "-c .*<bench>.cpp" | tail -1)
    ln=$(ninja -t commands src/<bench> | tail -1)
    eval "$(echo "$cc" | sed "s#-o [^ ]*<bench>.cpp.o#-o $OBJ#; s#-c [^ ]*<bench>.cpp#-c $SRC#; s#-MD -MT [^ ]* -MF [^ ]*##")"
    eval "$(echo "$ln" | sed "s#: && ##; s#&& :##; s#src/CMakeFiles/<bench>.dir/__/benchmarks/<bench>.cpp.o#$OBJ#; s#-o src/<bench>#-o $EXE#; s#@loader_path/../lib#$PWD/lib#")"
    

    The last sed term points the rpath at the tree's own lib/, so each binary loads its own libraries.

  4. Give each run fresh input (copy the data into a new folder per run), so a cache that one run writes does not serve the next.

  5. Alternate A and B runs and compare medians. Run nothing else heavy meanwhile.

Evidence#

  • dftracer-utils stage 10b (2026-09-27): qc_bench.cpp built against a54be906 and the working tree through index_bench's lines. The first try failed with error: unknown type name 'StringSink' (a type from tests/trace/views/test_view_common.h); a local NullSink : ExportSink fixed it. Three alternating runs gave medians within 1.3% between the builds.