I'd like to eliminate the "busybox --install" step, and I hoped I could do it via batch scripts command "aliases". However, each aliased command has cmd.exe as its parent interfering with its operation, particularly the infamous "Terminate batch job (Y/N)?" message which cannot be disabled. The usual suggestion when people complain about this misfeature is to use PowerShell. However, unlike batch scripts, PowerShell scripts are not first class citizens on Windows. PowerShell is not always available (often disabled by the adminstrator), and its scripts generally can't be installed on and executed via the PATH, at least not without system-wide configuration (i.e. PATHEXT).
Portable C and C++ Development Kit for x64 Windows
w64devkit is a Dockerfile that builds from source a small, portable development suite for creating C and C++ applications on and for x64 Windows. It is the highest quality native toolchain for C, C++, and Fortran currently available on Windows.
Included tools:
- Mingw-w64 GCC : compilers, linker, assembler
- GDB : debugger
- GNU Make : standard build tool
- busybox-w32 : standard unix utilities, including sh
- Vim : powerful text editor
- Universal Ctags : source navigation
- NASM : x86 assembler
The compilers support pthreads, C++11 threads, and OpenMP. All included libraries are static. Docker is not required to use the development kit. It's merely a reliable, clean environment for building the kit itself.
Build
First build the image, then run it to produce a distribution .zip file:
docker build -t w64devkit .
docker run --rm w64devkit >w64devkit.zip
This takes about half an hour on modern systems. You will need an internet connection during the first couple minutes of the build.
Usage
The final .zip file contains tools in a typical unix-like configuration.
Unzip the contents anywhere. Inside is an activate.bat
that launches a
console window with the environment configured and ready to go. It is the
easiest way to enter the development environment, and requires no system
changes.
Alternatively, add the bin/
directory to your path. For example, while
inside a console or batch script:
set PATH=c:\path\to\w64devkit\bin;%PATH%
Then to access a small unix environment:
busybox sh -l
This will expose the rest of busybox's commands without further action.
However, the unix environment will not be available to other tools such
as make
without "installing" BusyBox into the bin/
directory:
busybox --install
This step is recommended.
Best of class
What makes w64devkit the best? It is the only production-grade, native toolchain for Windows which:
-
Does not require installation. Run it anywhere as any user.
-
Does not require internet access during installation. The installers for other toolchains are actually downloaders, and so must be online for at least part of their installation process.
-
Supports C99 by default. The others have incomplete support or require esoteric configurations in order to enable it.
It's the only MinGW / Mingw-w64 distribution that produces binaries that do not depend on extra runtime DLLs. You will never need to distribute a DLL with your binary unless you explicitly choose to do so.
Optimized for size
The language runtimes in w64devkit are optimized for size, so it produces
particularly small binaries when programs are also optimized for size
(-Os
) during compilation. If your program only uses the printf
family
of functions with MSVC-compatable directivies (i.e. limited to C89), and
you want even smaller binaries, you can avoid embdedding the Mingw-w64's
improved implementation by setting __USE_MINGW_ANSI_STDIO
to 0 before
including any headers.
$ cc -Os -D__USE_MINGW_ANSI_STDIO=0 ...
Fortran support
Only C and C++ are included by default, but w64devkit also has full
support for Fortran. To build a Fortran compiler, add fortran
to the
--enable-languages
lines in the Dockerfile.
Notes
Due to an old GCC bug, we must build a cross-compiler to cross-compile GCC itself because, due to host contamination, GCC can only be correctly and safely cross-compiled by a matching version.
Since the development kit is intended to be flexible, light, and portable — i.e. run from anywhere, in place, and no installation is necessary — the binaries are all optimized for size, not speed.
I'd love to include Git, but unfortunately Git's build system doesn't quite support cross-compilation, and it's hostile to installation-free .zip distribution (lots of symlinks).
It would be nice to have a better shell like Bash. BusyBox's ash is limited, and the Windows port is quirky even more limited. Unfortunately, neither Bash nor Zsh have native Windows support.
What about sanitizer support? That would be fantastic, but unfortunately libsanitizer has not yet been ported from MSVC to Mingw-w64 (also).
Since the build environment is so stable and predicable, it would be great for the .zip to be reproducible, i.e. builds by different people are bit-for-bit identical. There are multiple reasons why this is not currently the case, the least of which are timestamps in the .zip file.
Licenses
When distributing binaries built using w64devkit, your .exe will include
parts of this distribution. For the GCC runtime, including OpenMP, you're
covered by the GCC Runtime Library Exception so you do not need to
do anything. However the Mingw-w64 runtime has the usual software license
headaches and you may need to comply with various BSD-style licenses
depending on the functionality used by your program: MinGW-w64 runtime
licensing and winpthreads license. To make this easy,
w64devkit includes the concatenated set of all licenses in the file
COPYING.MinGW-w64-runtime.txt
, which should be distributed with your
binaries.