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

Reply via email to