Nix is a package manager for Unix-like systems, which supports the installation of multiple versions of an application and which can run in parallel to whatever package manager a system uses natively (apt, pacman, yum, …). As other package managers, it needs a compiler toolchain to generate packages. Mingw-w64 and Cygwin provide free open source toolchains on Windows, both having their trade-offs and benefits: Cygwin offers a POSIX emulation needed by many applications, but binaries generated with Cygwin require the Cygwin runtime library; Mingw-w64 generates native Windows binaries without providing a POSIX emulation. In this report we describe how the Nix package manager realizes the installation of multiple versions of an application, what challenges Cygwin poses to these mechanisms, how we addressed, what should be done next, and how Mingw-w64 could be integrated to support management of native windows applications.

Cross-platform deployment means to exactly reproduce an application with its dependencies across different target platforms, like GNU/Linux, Mac OS X or Windows. An application — or more specifically a release of an application — is built and tested with specific versions of dependencies, like dynamic libraries, interpreter language modules, databases and command line tools.

For the deployment of multiple applications or releases of one application, it is essential that multiple versions of dependencies can be installed in parallel without interference. To minimize disk and RAM usage it is desirable that identical dependencies are shared between applications.

The Nix Package Manager solves these problems and the remainder of this section gives a brief introduction of its features and mechanisms.

1.1 Nix — The Purely Functional Package Manager Nix is a package manager for Unix-like systems, which can run in parallel to whatever package manager the system uses natively (apt, pacman, yum, …). As of version 1.7 it was available for GNU/Linux and Mac OS X (Darwin). NixOS is a Linux distribution that uses it natively as its sole package manager. Nix is a purely functional package manager in that it treats the files of packages like values of functions in purely functional programming languages such as Haskell: The functions describe how packages are built, they don’t have side-effects, and they never change after they have been built. A collection of such build functions is provided as the Nix Packages Collection (Nixpkgs). At its core Nixpkgs has a set of functions that provide a compiler toolchain and a minimal set of system tools across platforms, described in its own section: The Standard Environment. Nix supports installation of multiple versions of one application and even multiple, differently compiled builds of one version; sticking to the Filesystem Hierachy Standard (FHS) would lead to collisions. Instead nix installs the files generated by its build functions into a database, described in its own section: The Nix Store.

1.2 The Nix Store Nix uses functions in a purely functional sense to describe its packages. The values of these functions are called outputs and are stored as subdirectories of the Nix Store ( /nix/store ). An output in the store holds the content of a package that would usually be installed to /usr . In that regard, the store resembles /opt with the possibility to have multiple versions and even multiple builds of the same version installed in parallel. This is achieved by using a cryptographic hash as a prefix for the store output. % ls -l /nix/store/w08118q0kp26qdcz5cdl2rx6chghawam-hello-2.9 dr-xr-xr-x 2 root root 4096 Jan 1 1970 bin/ dr-xr-xr-x 5 root root 4096 Jan 1 1970 share/ % ls -l /nix/store/w08118q0kp26qdcz5cdl2rx6chghawam-hello-2.9/bin -r-xr-xr-x 2 root root 30845 Jan 1 1970 hello* The cryptographic hash used as a prefix is calculated over the function describing the build of a package as well as all its build-time dependencies, represented by similar functions. Variations in any of these will lead to a different hash and therefore a different store location. To make sure that a binary in the store will load the correct dynamic libraries, Nix hardcodes absolute store paths of dependencies into build binaries. % ldd =hello linux-vdso.so.1 (0x00007fffbc1fe000) libc.so.6 => /nix/store/i11d0d4015p0vbdnjq7lb509v9pwp049-glibc-2.19/lib/libc.so.6 (0x00007f55d1263000) /nix/store/i11d0d4015p0vbdnjq7lb509v9pwp049-glibc-2.19/lib/ld-linux-x86-64.so.2 (0x00007f55d1610000) Based on such and other references of store locations, Nix performs automatic runtime dependency detection and supports copying a package and its dependencies from one machine to another: If a store path of package A occurs in any file of package B, package A is a runtime dependency of B.