Preparing rust

First install Rust normally with rustup. The next step will install the Windows toolchain.

rustup target add x86_64-pc-windows-gnu

Then set up the target in ~/.cargo/config.

linker = "x86_64-w64-mingw32-gcc"
ar = "x86_64-w64-mingw32-gcc-ar"

Mingw and GTK installation

Arch Linux

The mingw packages are in the AUR, you can either install manually or use a helper. These instructions use the pacaur helper. The packages take a while to compile.

pacaur -S mingw-w64-gcc mingw-w64-freetype2-bootstrap mingw-w64-cairo-bootstrap
pacaur -S mingw-w64-harfbuzz
pacaur -S mingw-w64-pango
pacaur -S mingw-w64-poppler
pacaur -S mingw-w64-gtk3


Fedora provides pre-compiled Mingw and GTK packages through its repositories. Both 64 and 32 bits are available (mingw64-* vs mingw32-*), of which you probably want the 64 bits packages.

dnf install mingw64-gcc mingw64-pango mingw64-poppler mingw64-gtk3 mingw64-winpthreads-static


Be advised that the windows:mingw:win64 project only provides mingw64-gtk3 at version 3.22-15, you will only be able to compile programs requiring GTK features v3_22-15 and lower.

openSUSE is similar to fedora with differences on the packages to install


zypper addrepo

Leap 15.2

zypper addrepo

Leap 15.1

zypper addrepo

zypper refresh
zypper in mingw64-gtk3-devel mingw64-cross-gcc

Other distributions

GTK doesn’t offer Windows binaries for download anymore, so for distributions that don’t package their own Mingw-GTK packages, cross-compiling is much harder. In general the steps are:

  1. Download 64 bit Mingw GTK libraries.
  2. Unzip it in a folder. For example, to install it in /opt/gtkwin: mkdir -p /opt/gtkwin && unzip <> -d /opt/gtkwin.
  3. You have to set-up the library to match the installation folder:

     cd /opt/gtkwin
     find -name '*.pc' | while read pc; do sed -e "s@^prefix=.*@prefix=$PWD@" -i "$pc"; done

Finding some place to download the libraries is the challenge however, and there is no ideal solution. Three options are: (1) Getting the most versions from the Fedora RPMs, which can be downloaded here; (2) Using the ancient GTK 3.6 available here; (3) Delving into GTK’s own recommendations for Windows. Be sure to check your own distribution’s repository first however.


Now create your project using gtk-rs (and relm, it’s great). if you don’t want a terminal window to pop up when running add the following to the top of your

#![windows_subsystem = "windows"]

Once you get it working on Linux you can compile for Windows following these steps. PKG_CONFIG_PATH should point to your Mingw’s pkgconfig directory, while MINGW_PREFIX should point to Mingw’s root installation. For Arch for example:

export MINGW_PREFIX=/usr/x86_64-w64-mingw32
export PKG_CONFIG_PATH=$MINGW_PREFIX/lib/pkgconfig
cargo build --target=x86_64-pc-windows-gnu --release

For Fedora Mingw’s prefix is /usr/x86_64-w64-mingw32/sys-root/mingw/. For other distributions it is /opt/gtkwin or wherever you installed the precompiled binaries.

If you have some problems while compiling, you might want to consider rebooting since this has solved some problem on my side. Also, you should be careful when using Glade with gtk-rs. Make sure that the version requested by Glade is at most equal to the version installed on your system. Otherwise it will fail to execute.


We will reuse the MINGW_PREFIX path here to copy over relevant files to package it up:

mkdir /wherever/release
cp target/x86_64-pc-windows-gnu/release/*.exe /wherever/release
cp $MINGW_PREFIX/bin/*.dll /wherever/release
mkdir -p /wherever/release/share/glib-2.0/schemas
cp $MINGW_PREFIX/share/glib-2.0/schemas/gschemas.compiled /wherever/release/share/glib-2.0/schemas/gschemas.compiled
cp -r $MINGW_PREFIX/share/icons /wherever/release/share/icons

After that you can zip up the contents of the /wherever/release folder and distribute it.

Optional Extras

Icon and version info

These steps are for adding an icon to your program. First make a rc file showing where the icon is and the version info. Change “path/to/my.ico” to your icon”. The BLOCK “040904E4” and VALUE “Translation”, 0x409, 1252 are for US english, if you would like something different refer to


id ICON "path/to/my.ico"
FILEVERSION     1,0,0,0
BLOCK "StringFileInfo"
    BLOCK "040904E4"
        VALUE "CompanyName", "My Company Name"
        VALUE "FileDescription", "My excellent application"
        VALUE "FileVersion", "1.0"
        VALUE "InternalName", "my_app"
        VALUE "LegalCopyright", "My Name"
        VALUE "OriginalFilename", "my_app.exe"
        VALUE "ProductName", "My App"
        VALUE "ProductVersion", "1.0"
BLOCK "VarFileInfo"
    VALUE "Translation", 0x409, 1252

now to have the linker include it you’ll need to make a build script, first add the following to your Cargo.toml:

build = ""

then in your

use std::process::Command;
use std::env;
use std::path::Path;

fn main() {
    let out_dir = env::var("OUT_DIR").unwrap();
        .arg(&format!("{}/program.o", out_dir))
        .args(&["crus", "libprogram.a", "program.o"])

    println!("cargo:rustc-link-search=native={}", out_dir);

You’ll need to comment out both prints when building for linux.

Windows 10 theme

If you’d like the program to have a more native look you can set the theme to windows 10.

mkdir /wherever/release/share/themes
mkdir /wherever/release/share/gtk-3.0

edit /wherever/release/share/gtk-3.0/settings.ini

gtk-theme-name = Windows10
gtk-font-name = Segoe UI 10
gtk-xft-rgba = rgb

then download the windows 10 them from

mv Windows-10-master /wherever/release/share/themes/Windows10