Skip to content

About

A self-contained cross-compilation toolchain for classic Windows CE and Windows Mobile

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

ce-toolchain

A self-contained cross-compilation toolchain for classic Windows CE and Windows Mobile devices. It builds Max Kellermann's WinCE forks of GNU binutils and GCC (9.2) together with the mingw32ce runtime (mingwrt, w32api) entirely on your Linux machine, and wires them up so that compiling, deploying, and running test binaries is a one-command affair.

Import libraries for each target OS come from the official Microsoft SDKs. The SDK installers are downloaded, checksum-verified, and mined statically, so nothing proprietary is committed to this repository and no Windows machine is ever needed.

demo

What it is / has

  • A complete arm-wince-mingw32ce GCC toolchain: C and C++, with working exception handling and the full libstdc++ built for the target.
  • Per-flavor sysroots. Switching between Windows Mobile 5, Windows Mobile 6, and plain Windows CE 5.0 is one command; import libraries are overlaid to match.
  • A scriptable test bench: Microsoft Device Emulator 3.0 installed into a private Wine prefix, booting real OS images, with a shared folder acting as \Storage Card.
  • CMake integration that tracks the installed flavor automatically, including the correct _WIN32_WCE value.

Quick start

From zero to a hello world running in an emulated Windows Mobile device:

git clone https://github.com/Hedy88/ce-toolchain.git
cd ce-toolchain
python3 -m pip install --user -e '.[dev]'

Build the compiler once. This is the long step (tens of minutes; see below for details):

ce-toolchain build-toolchain

Pick a target OS and verify the compiler end to end:

ce-toolchain install-sysroot wm6-professional-arm
ce-toolchain smoke-test

Set up the emulator (one-time download of Microsoft's Device Emulator 3.0), then compile, deploy, and run:

ce-toolchain emulator-setup
ce-toolchain deploy
ce-toolchain emulator-run

An emulated device boots. In its File Explorer, open \Storage Card and tap the deployed exe.

Supported target flavors

Pass any of these to install-sysroot:

Flavor Target OS CE version Emulator images
wm5-pocketpc-arm Windows Mobile 5.0 Pocket PC 5.1 yes
wm6-professional-arm Windows Mobile 6 / 6.1 Professional 5.2 yes
ce5-standard-arm plain Windows CE 5.0 (Standard SDK) 5.0 none (see note)

Notes:

  • There was never a dedicated WM6.1 SDK. The wm6-professional flavor covers both 6.0 and 6.1 Professional devices.
  • The Standard SDK targets generic Windows CE without the Windows Mobile stack (no phone, PIM, or ActiveSync APIs). It ships no ARM emulator images because the CE5-era emulator was x86-based. To test such builds, either use real hardware or boot a WM image instead; Windows Mobile is a superset of the same CE 5.x kernel. A generic community-built CE 5.0 image also works well in the emulator (see the emulator section).
  • Flavor names ending in -arm are sysroot directories under sysroot/. The bare forms (wm5-pocketpc, ...) are SDK keys used by fetch-sdk.

Requirements (Linux)

Debian/Ubuntu:

sudo apt install git make gcc g++ flex bison texinfo \
                 msitools p7zip-full wine cmake python3-pip

Fedora/RHEL:

sudo dnf install git make gcc gcc-c++ flex bison texinfo \
                 msitools p7zip wine cmake python3-pip
  • texinfo provides makeinfo, needed by the GCC docs step.
  • msitools provides msiextract; together with p7zip it lets us unpack MSI installers without executing them.
  • wine runs the Device Emulator. A 64-bit Wine installation is expected; the tooling creates its own win32 prefix at ~/.wine-ce.
  • CMake 3.25+ is only needed for the CMake example and your own projects.
  • Python 3.10+ hosts the orchestration CLI.

Check everything at once with:

ce-toolchain doctor

Building the toolchain

One command does the whole bootstrap in dependency order:

ce-toolchain build-toolchain

Internally this runs four stages, each stamped so an interrupted build resumes where it left off by simply re-running the command:

  1. binutils fork (assembler, linker, objdump and friends for PE/CE)
  2. GCC first stage, enough to build runtime code
  3. mingwrt and w32api (the C runtime and Win32 headers/libs). These two must be cloned side-by-side before either is built, since each compiles against the other's source headers.
  4. targetlibs: the full libgcc plus libstdc++ against the finished runtime

Expect tens of minutes on a modern CPU, dominated by the GCC stages, and roughly 3 GB of disk across src/, build/, and the installed tree under toolchain/. The result is a self-contained prefix: no system paths are baked in, so the tree can be tarballed and moved.

Building on Windows

Use WSL2. The tooling assumes Linux userland (msiextract, wine, bash staging); a native MSYS2 build is not supported.

  1. From an admin PowerShell: wsl --install -d Ubuntu. Reboot, create your Linux user.

  2. Follow the Linux sections above verbatim inside Ubuntu.

  3. Keep the repository on the Linux filesystem (for example ~/projects/ce-toolchain). Working under /mnt/c slows builds down by an order of magnitude.

  4. For emulator GUI output, Windows 11 shows Wine windows automatically via WSLg. On Windows 10, install VcXsrv or X410, start it with native OpenGL disabled, and point the display at it before emulator-run:

    export DISPLAY=$(grep nameserver /etc/resolv.conf | awk '{print $2}'):0

Running in the Device Emulator (Wine)

One-time setup downloads Microsoft Device Emulator 3.0 (SHA-verified, hosted on the Internet Archive), extracts it statically, and installs it into the private ~/.wine-ce prefix along with every OS image staged by your sysroots:

ce-toolchain emulator-setup

Compile something, put it where the device can see it, and boot:

ce-toolchain smoke-test
ce-toolchain deploy              # copies exes to build/device-storage
ce-toolchain emulator-run        # boots the default image of the active flavor

Inside the emulator, \Storage Card maps directly to build/device-storage, so anything deployed shows up there. Open it in File Explorer and tap an exe.

Useful variations:

# pick another staged image explicitly
ce-toolchain emulator-run --image wm6-professional/PPC_USA_GSM_VR.BIN

# pass raw DeviceEmulator.exe flags after
ce-toolchain emulator-run -- /memsize 256 /video 800x600x16

Screen resolution belongs to the emulator and can be set per launch with /video WxHxBPP. To persist a resolution for a specific image, place a sidecar file named <image>.args next to the staged image containing the flags; they are applied automatically on every launch.

Shell locale, by contrast, is baked into the OS image itself and cannot be changed at launch time.

Deploying to real hardware

Everything the toolchain produces is a normal ARM executable. Copy it to the device over USB MassStorage or ActiveSync as usual and run it from there. The emulator's ActiveSync/cradle features do not work under Wine, which is why deployment goes through the shared folder instead.

Building your own projects with CMake

Two zero-flag options; pick whichever suits your workflow.

Option A: source the environment once. After this, plain cmake invocations use the cross compiler without further flags:

. ./setup-env.sh
cmake -S examples/cmake-app -B build/plain
cmake --build build/plain

Option B: CMake presets, picked up by VSCode, CLion, and Rider too. Copy examples/cmake-app/CMakePresets.json into your project:

cd examples/cmake-app
cmake --preset wince
cmake --build --preset wince

Both routes point CMake at the checked-in cmake/arm-wince-mingw32ce.cmake, which sets CMAKE_SYSTEM_NAME to WindowsCE, selects the cross compilers, restricts find_* searches to the target sysroot, and derives _WIN32_WCE from whichever flavor is currently installed (so flavor-gated SDK headers behave correctly).

Then deploy and run:

ce-toolchain deploy build/presets/hello-cmake/hello-cmake.exe
ce-toolchain emulator-run

Limitations and design notes

What works:

  • Targets: ARMV4I Windows CE 5.x, in the three flavors listed above.
  • Languages: C and C++ with working exception handling. GCC is a 9.2 fork defaulting to GNU C++17; <optional>, <variant>, <string_view>, <atomic>, CTAD, and structured bindings all work.
  • Linking: static by default. libgcc and libstdc++ are linked in, giving roughly 10 MB unstripped binaries; strip with -s.
  • Testing: full compile/deploy/run loop in the Device Emulator under Wine.

Known limitations:

  • ARM only. The binutils and GCC forks only wire up the arm-wince-pe / mingw32ce targets. x86, MIPS, and SH would need genuine porting.
  • Soft-float only. Configured with --disable-multilib because the fork's t-wince-pe fragment declares an -mfloat-abi=hard multilib that its own backend cannot compile.
  • libgcc provides no __cxa_atexit/__dso_handle (configured with --disable-__cxa_atexit). Irrelevant for single statically-linked binaries.
  • No threads: std::thread and friends are unavailable (libstdc++ configured with --disable-threads; WinCE has no pthread layer). Single-threaded atomics are fine. <filesystem> is likewise unavailable.
  • C++20 is partial at best (-std=c++2a gives concepts; most C++20 library pieces arrived in GCC 10+).
  • The emulator on Wine is CLI-driven: no skins, no Device Emulator Manager, no cradle, hence no ActiveSync/RAPI connection. Deployment uses the shared folder.

Repository layout

Path Contents
src/ shallow clones of the upstream forks (WinCE patches live as branches)
build/ per-component build trees and stamp files
toolchain/cegcc/ the installed toolchain (arm-wince-mingw32ce-*)
sysroot/<flavor>/ staged SDK headers, import libs, and emulator images per flavor
downloads/ SDK installers kept on disk; extraction is quick
ce_toolchain/ the Python CLI orchestrating all of the above

License

BSD 2-Clause for everything in this repository. Downloaded Microsoft SDKs and the Device Emulator remain governed by their own terms and are fetched at build time rather than redistributed here.

About

A self-contained cross-compilation toolchain for classic Windows CE and Windows Mobile

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages