Safeguard
Developer Tools•

Does the build directory path change your binary?

Yes. Compilers often record source paths in debug info and macros. Use prefix map flags or build in a fixed path so two directories give the same output.

Safeguard Security Team
4 min read

Yes. Many compilers write the path of the source files into debug information, and macros like the file name macro can embed paths too. Build in two different directories and the binaries can differ. Fix it by mapping the path prefix at compile time, or by always building in the same directory.

Why paths leak in

The reproducible-builds documentation says most compilers write the path of the source into debug information so a debugger can find the source files. Some other tools also record paths in their output. A developer builds in a home directory and CI builds in a workspace directory, so the same source yields two different binaries, even though nothing in the code changed.

Two ways to deal with it

Option 1: make the path part of the build environment. If every build happens in the same directory, say a fixed path inside a container, the path never varies. The deterministic build documentation says there is no need to make output independent of build path if the path is defined as part of the build environment, and rebuilds are required to use the same directory. This is the simplest option for a small team: build inside a container with a fixed working directory.

Option 2: remap the path. The documentation lists compiler flags that rewrite a path prefix.

FlagEffectAvailability noted in the docs
debug prefix mapRewrites paths in debug informationAll GCC versions, Clang 3.8 and later
macro prefix mapRewrites paths from file name macros such as in assertionsGCC 8 and later, Clang 10 and later
file prefix mapAlias that does bothGCC 8 and later, Clang 10 and later
# map the real source directory to a fixed name
CFLAGS="-ffile-prefix-map=$PWD=/src"

The same page notes that Debian tooling can enable the file prefix map for packages through a build flag, and that some tools save the compile options into the output, which is itself a problem, since those options may contain the path.

A caution on debug symbols

The documentation says there is currently no good post-processing tool to change paths in debug symbols to a predetermined value, and that rewriting at compile time is the workaround. That means if you notice late, you may have to rebuild, not patch the binary.

How to test

  1. Build the same commit in a directory with one name, then in a directory with a different, longer name.
  2. Compare the output hashes.
  3. If they differ, search the binaries for the directory string. A simple string search is enough to find leaks.
  4. Add the prefix map flag or move to a fixed build directory, then repeat.
strings dist/app | grep "/home/"

Which should you pick

If you already build in a container, choose option 1 and write the working directory into the Dockerfile. If you want developers to be able to reproduce your release hash on their own laptops without containers, choose option 2. Either way, record the decision in the build record.

Where Safeguard fits

Safeguard does not change how compilers record paths. It supports dependency visibility with SBOMs and scanning. Free scan: gold.safeguard.sh/scan.

Quick check

Does this affect interpreted languages?

It can. Bytecode and packaged archives sometimes record paths too, so test by building in two directories.

Is a fixed build directory a hack?

No. The reproducibility documentation treats it as a valid choice, as long as it is written down as part of the build environment.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.