Skip to content

Build Go, Rust and .NET projects ​

Go, Rust and .NET can all produce Windows programs from Linux with their own tools. This page shows what each one needs and what winbridge build runs for you.

The command is the same for every language ​

bash
winbridge build path/to/project

Leave the path out to build the current folder. WinBridge looks at that folder only: it does not search subfolders or parent folders. In a repository with several packages, build one package folder at a time.

When more than one marker file is present, the first match in this order wins: Flutter, Go, Rust, .NET, C/C++.

Options that apply to every toolchain:

OptionWhat it does
--debugBuilds unoptimized, with debug information.
-o, --outputWrites the result to a folder you choose.
-- argumentsPasses everything after -- to the underlying compiler unchanged.
--verbosePrints every command and resolved tool path, as in winbridge --verbose build.

The result lands in build/winbridge/windows-x64/ inside the project, named after the project.

Go ​

Go has cross-compiling built in, so it needs nothing but the Go toolchain.

  1. Make sure Go is available.

    If go is already installed, WinBridge uses it. If not, let WinBridge install it into your home folder (67 MB):

    bash
    winbridge doctor --install go
  2. Build the module.

    bash
    winbridge build path/to/module

WinBridge detects a Go project by its go.mod file and names the output after the last part of the module path. It runs go build with GOOS=windows, GOARCH=amd64 and CGO_ENABLED=0. A release build adds -ldflags "-s -w", which strips debug symbols to make the file smaller; --debug leaves them in.

Good to know

cgo is switched off for these builds. A Go package that needs C code through cgo does not compile this way.

Extra arguments reach go build. For example, to add build tags:

bash
winbridge build . -- -tags netgo

Rust ​

Rust needs three things: Cargo, the Windows target for the Rust standard library, and a MinGW linker that can write Windows executables.

  1. Install Rust with rustup if you have not already. WinBridge does not download Rust.

  2. Add the Windows target.

    bash
    rustup target add x86_64-pc-windows-gnu
  3. Install the MinGW-w64 linker. On Debian and Ubuntu:

    bash
    sudo apt install gcc-mingw-w64-x86-64

    This provides x86_64-w64-mingw32-gcc, the program WinBridge looks for.

  4. Build the crate.

    bash
    winbridge build path/to/crate

WinBridge detects a Rust project by Cargo.toml and runs cargo build --release --target x86_64-pc-windows-gnu. With --debug it leaves out --release. Cargo's target folder is kept in WinBridge's cache, so your project folder gains only the finished .exe.

If the Windows target is missing and rustup is installed, the build stops early and prints the rustup target add command to run.

Extra arguments reach cargo build:

bash
winbridge build . -- --features cli

.NET ​

The .NET SDK can publish for Windows from Linux. WinBridge does not download the SDK; install dotnet from Microsoft or your distribution.

bash
winbridge build path/to/project

WinBridge detects a .NET project by a .csproj or .fsproj file in the folder and runs:

bash
dotnet publish -r win-x64 -c Release --self-contained false -o <output folder>

Things to know about the result:

  • The build is framework-dependent: the Windows PC that runs it needs the matching .NET runtime installed.
  • The output folder holds the launcher .exe together with the project's .dll files. Ship the whole folder, not only the .exe.
  • The project must produce a launcher .exe. If UseAppHost is disabled in the project file, the build fails with a message saying so.
  • --debug does not change a .NET build. It always publishes the Release configuration.

Extra arguments reach dotnet publish:

bash
winbridge build . -- -p:Version=1.2.3

Check a project before building ​

winbridge detect shows what WinBridge would do, and builds nothing:

bash
winbridge detect path/to/project

It prints the project name, its type, the file that decided the type, and the toolchain that would build it.

Choose the Windows architecture ​

--target accepts windows-x64 (the default) and windows-arm64. In version 0.4.0 the check that follows every build accepts only 64-bit x86 executables, so use the default windows-x64.

Next steps ​