(Free) Software Building and Packaging For Windows

Download and Installation From Linux

No Linux binaries are provided because of the differences between distributions. The usual approach is to build the cross-compiler on the host system and then re-use the pre-built windows packages (since they are independent of the system used to build).

The packages are split into three series: native, cross_toolchain and windows:

  • native adds native tools which must be of a specific version for other builds to succeed; for instance, it installs luajit because the luajit cross-compilation needs a native luajit of the exact same version and bitness;
  • cross_toolchain builds the cross-compilation toolchain(s);
  • windows is the last step and cross-compiles the binaries that will run on windows

Building takes up to 200MB for native_toochain, 4GB for cross_toolchain_* and 13GB for windows_* (but this series can be retrieved instead of being built). Around 90% of this space is made up of temporary files in tmp directories. At peak it can also use a lot of memory, having 2GB of memory available (swap excluded) is advised. If you only wish to build a specific package, only the required build dependencies will be built.


Builds are tested on Debian, Ubuntu, Mageia, Slackware. The lists for other distributions are user-contributed.

Arch Linux

intltool wget

Debian and Ubuntu

libudev-dev intltool libpng-dev gtk-doc-tools tcl8.5 libgdk-pixbuf2.0-dev yasm \
autopoint flex bison libdbus-1-dev \
xutils-dev git libgtk2.0-bin texi2html cmake texinfo \
librsvg2-bin imagemagick gperf libreadline6-dev help2man

Versions of Debian and Ubuntu before 2012 are not officially supported but can be made to work with some additional work; upgrading is encouraged nonetheless.


A default exherbo install should ship everything needed.

Mageia 64bits

git help2man lib64readline-devel lib64freetype6-devel lib64jpeg-devel lib64dbus-devel texinfo yasm lib64gdk_pixbuf2.0-devel intltool itstool texi2html valgrind-devel


A default slackware install ships everything needed.

Retrieve sources

Win-builds sources are stored in git. Retrieve them with:

git clone

Next cd into that directory; from now on, all commands shown will assume you have cd'ed there:

cd win-builds

In case you want to use another branch, for instance next, run:

git checkout -b next origin/next

Yypkg and build environment

Yypkg is the package manager used in win-builds. It can be built automatically, along with its dependencies:

make deps

When you do that, if you haven't cloned the slackware and build script repositories (you probably haven't), they will be cloned automatically and put on a branch consistent with the one used for the win-builds repository.

Get the Windows binaries

You can either download the pre-built packages for released versions or build everything yourself. In both cases the cross-compilation toolchain needs to be built but this operation is not very long anyway, even on less powerful machines.

Download packages (250MB per architecture)

make WINDOWS=download

A few commands will try to run at the very end of the installation and will fail. They can be safely ignored since they only matter when running on Windows.

Build the packages yourself (a few hours of CPU time)

make WINDOWS=all


Selective builds

Chosing which packages are built is done through environment variables. There are 7 of them:

  • WINDOWS_32, WINDOWS_64, WINDOWS: packages which executables will run on Windows for 32 or 64 bits; WINDOWS=foo is shorthand for WINDOWS_32=foo WINDOWS_64=foo;
  • CROSS_TOOLCHAIN_32, CROSS_TOOLCHAIN_64: the cross-compilation toolchain which runs on your current system and targets Windows for 32 or 64 bits; CROSS_TOOLCHAIN is a short-hand notation;
  • NATIVE_TOOLCHAIN: some build-time dependencies for packages above; they are either uncommon or common but required to be at a specific version

The value of these environment variables is the comma-separated list of packages to build. Dependencies across series are handled, meaning that most typically only the WINDOWS_* variables are set by the user.

A virtual package named all is available in order to select every stable package from the WINDOWS series.

When a package has variants (several configuration presets), the identifier is of the form ${package}:${variant}.

As an example, if you want to build a specific set of packages, you might call make as such:

make WINDOWS=libjpeg,libpng,lua,fontconfig:regular

Packages will only get rebuilt if at least one of their sources is more recent than the resulting package. However, the rebuild of a package doesn't trigger the rebuild of packages that depend on it in order to avoid excessive rebuilds. Since win-builds uses shared libraries rather than static ones, this is an issue only when a library changes major version but keeps the same package name.

Build script configuration

The configuration for most packages is stored directly inside the build scripts. The packages which have variants have their configuration in a separate file in the same directory as the build script and named config-${variant}.

Modify the package lists

The list of packages to build is stored inside three files: win-builds/, win-builds/, win-builds/ through #use directives which point to the actual build scripts:

#use "slackware/l/libjpeg-turbo/"

A package description is made of a name, a variant (which is mostly useful for bootstrapping a minimal version of a package before being able to build the full one), a directory where its sources are stored, its build dependencies, version, build number and source files.

Below is the description for the freetype package from the windows series, stored in slackware/l/freetype/

let freetype = add (name, variant)
  ~dependencies:[ zlib; libpng ]

This package is named “freetype”, doesn’t have a variant, is stored inside the slackware/l directory, depends on zlib and libpng, is at version, first build, and has three source files: its source tarball and two patches.

Build as you develop

A fairly common scenario while developing is to build what has just been developed.

This can be achieved through two means: pulling sources from git and using the :devshell feature.

Pull sources from git

For packages that support this (i.e. which have the corresponding information filed in), the way to build from git is to set the FROM_VCS environment variable. It will pull sources from VCS rather that from tarballs. For instance, one could run:

make WINDOWS_32=efl:regular FROM_VCS=efl

By default this will pull from the upstream git repository. If you want to build from a local repository, the simplest is to look at the metadata file, for the EFL package. It contains the following lines:

Git.(T {
  tarball = "${PACKAGE}-${VERSION}.tar";
  dir = "efl";
  prefix = "${PACKAGE}-${VERSION}";
  obj = None;
  uri = None;
  remote = None;

Note the dir = “efl” line. It means the git repository that will be used to get sources will be in an efl directory, relative to the other files for that package. As such, the simplest way to direct the build to your sources is to create a symbolic link to them:

ln -s /home/you/path/to/your/project/directory/efl

Use the :devshell feature

A package is built using a .SlackBuild file. However it is possible to spawn an interactive shell rather than run that script. This is available for all packages and is available by appending :devshell to the chosen package name. For instance:

make WINDOWS_32=efl:regular:devshell