Hi folks
I'm involved with trying to achieve reproducible builds for Threema Desktop 2.0
(https://three.ma/md).
Threema Desktop is an Electron application containing both native node modules
(written in C, using node-gyp as build system) as well as a Rust binary.
To achieve reproducible builds, things I've discovered and fixed so far:
- I added the undocumented `/Brepro` MSVC linker flag to ensure that no
timestamps are added to the PE binaries
- I added the `/PDBALTPATH:%_PDB%` MSVC linker flag to avoid having absolute
build directory paths embedded in the PE binaries
- I added a `rust-toolchain.toml` file to the Rust subproject to ensure that
the identical toolchain version is being used for all builds
For node modules, the linker flags can be added in `binding.gyp`. For example:
...
"msvs_settings": {
...
"VCLinkerTool": {
"AdditionalOptions": [
# Reproducible builds: Do not include timestamps in binary
"/Brepro",
# Reproducible builds: Do not include absolute paths to debug symbols
in binary
"/PDBALTPATH:%_PDB%"
]}
},
...
For the Rust project, the config can be added in `.cargo/config.toml`:
[target.'cfg(target_env = "msvc")']
rustflags = ["-C", "link-args=/Brepro"] # Reproducible builds on Windows
For debugging, diffoscope (especially the try.diffoscope.org website) was a big
help, thanks!
One aspect that I cannot get rid of is the embedded toolchain information, as
well as differing behavior between toolchain versions. As an example, the COFF
header of the PE files contains the following header fields when buliding with
the Visual Studio 2022 toolchain:
MajorLinkerVersionĀ» 14
MinorLinkerVersionĀ» 42
>From what I could gather, there is no way to really solve this issue. The
>approach that we currently plan to implement is to simply declare the
>toolchain version we used, and let the user deal with the effort to get it
>installed.
Are there any alternatives? How are other Windows projects dealing with this?
Is there maybe a way to build using a MSVC toolchain in a container using
Docker for Windows, or something similar? Or can a MSVC redistributable
toolchain be installed to a directory, and selected using some environment
variables?
Cheers,
Danilo