Table of Contents
- Building and Cross-Compilation
- Workspace layout
- Native builds
- Installation (Linux)
- build.rs
- .cargo/config.toml
- Cross-compiling for Windows (from Linux)
- Cross-compiling for macOS (using osxcross)
- 1 — Obtain an SDK
- 2 — Build osxcross
- 3 — Add Rust targets
- 4 — Configure Cargo
- 5 — Set environment variables
- 6 — Build
- 7 — Universal binary (optional)
- Makefile targets (not yet added)
- Generating icons
Building and Cross-Compilation
rustpg is a Cargo workspace. Everything compiles from source with no system crypto libraries required — the RustCrypto backend is pure Rust.
Workspace layout
rustpg/
Cargo.toml ← workspace root (edition 2024, resolver 2)
Makefile
.cargo/config.toml ← linker overrides for cross targets
crates/
rpg/ ← CLI binary
rpglib/ ← shared library (no binary)
rustpg/ ← GUI binary
rustpg/build.rs ← compile-date env var + Windows icon embedding
default-members in the workspace root is [rpg, rpglib] — cargo build without flags builds only the CLI and library. The GUI must be requested explicitly.
Native builds
cd rustpg
cargo build # CLI (rpg) + rpglib — debug
cargo build --workspace # CLI + GUI (rustpg) — debug
cargo build --release # CLI release
cargo build --release --workspace # CLI + GUI release
cargo build -p rustpg # GUI only
cargo run -p rpg -- --help
cargo run -p rustpg
cargo test -p rpglib
Or via Make:
make # cargo build --workspace (debug)
make small # cargo build (CLI + lib only)
make clean # cargo clean
Installation (Linux)
User install (~/.cargo/bin)
make install
Runs cargo install for rpg and rustpg, then copies the icon and desktop entry:
~/.local/share/rustpg/rustpg.png— app icon~/.local/share/applications/rustpg.desktop— XDG entry (patchesExec=andIcon=to user paths)
make uninstall # reverses the above
System install (/usr/local/bin)
sudo make sys-install
Builds release binaries and installs to /usr/local/bin/rpg and /usr/local/bin/rustpg. Icon goes to /usr/local/share/rustpg/, desktop entry to /usr/local/share/applications/.
sudo make sys-uninstall
build.rs
The GUI crate's build.rs does two things:
- Compile date: runs
date "+%-d %b %Y"and exposes it as theCOMPILE_DATEenv var, shown in Help → About. - Windows icon: when
CARGO_CFG_TARGET_OS == "windows", callswinresourceto embedassets/rustpg.icointorustpg.exe. The ICO contains 16/32/48/64/128/256 px images.
.cargo/config.toml
[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"
This tells Cargo to use the MinGW-w64 GCC cross-linker for the Windows target. Additional targets (macOS) are added here when osxcross is set up.
Cross-compiling for Windows (from Linux)
This is the primary release path. All crypto is pure Rust so there are no C library surprises.
One-time setup
make windows-setup
# equivalent to:
rustup target add x86_64-pc-windows-gnu
sudo apt install mingw-w64
Build
make windows
# equivalent to:
cargo build --release --workspace --target x86_64-pc-windows-gnu
Produces:
target/x86_64-pc-windows-gnu/release/rpg.exetarget/x86_64-pc-windows-gnu/release/rustpg.exetarget/x86_64-pc-windows-gnu/release/keylib-librarian.exe
Zip release
make windows-zip
Creates rustpg-windows-<VERSION>.zip containing all three .exe files. The version is read live from cargo metadata.
Test under Wine
make windows-run
# equivalent to:
WGPU_BACKEND=vulkan wine target/x86_64-pc-windows-gnu/release/rustpg.exe
WGPU_BACKEND=vulkan forces wgpu to use the Vulkan backend via Wine's translation layer instead of trying Direct3D.
Cross-compiling for macOS (using osxcross)
macOS cross-compilation requires osxcross, which provides a Clang-based cross-toolchain wrapping an Apple SDK.
1 — Obtain an SDK
Apple does not redistribute SDKs for redistribution. The standard approach is to extract one from a local Xcode installation on a Mac and scp the resulting tarball to the Linux build machine. osxcross provides tools/gen_sdk_package.sh for this.
# On a Mac with Xcode installed:
git clone https://github.com/tpoechtrager/osxcross
cd osxcross
./tools/gen_sdk_package.sh # produces MacOSX<ver>.sdk.tar.xz
scp MacOSX*.sdk.tar.xz user@buildhost:~/
2 — Build osxcross
# On the Linux build host:
git clone https://github.com/tpoechtrager/osxcross
cd osxcross
cp ~/MacOSX*.sdk.tar.xz tarballs/
UNATTENDED=1 ./build.sh
This installs the toolchain under osxcross/target/bin/. Add it to your PATH:
export PATH="$HOME/osxcross/target/bin:$PATH"
Verify:
x86_64-apple-darwin23-clang --version
aarch64-apple-darwin23-clang --version
3 — Add Rust targets
rustup target add x86_64-apple-darwin # Intel Mac
rustup target add aarch64-apple-darwin # Apple Silicon
4 — Configure Cargo
Add to .cargo/config.toml in the workspace root:
[target.x86_64-apple-darwin]
linker = "x86_64-apple-darwin23-clang"
ar = "x86_64-apple-darwin23-ar"
[target.aarch64-apple-darwin]
linker = "aarch64-apple-darwin23-clang"
ar = "aarch64-apple-darwin23-ar"
Replace darwin23 with the SDK version suffix your osxcross build produced (e.g. darwin20.4 for macOS 11 SDK, darwin23 for macOS 14 SDK). Check ls ~/osxcross/target/bin/ to confirm.
5 — Set environment variables
export MACOSX_DEPLOYMENT_TARGET=11.0
export CC_x86_64_apple_darwin=x86_64-apple-darwin23-clang
export CC_aarch64_apple_darwin=aarch64-apple-darwin23-clang
6 — Build
CLI only (no OS framework dependencies — straightforward):
cargo build --release -p rpg --target x86_64-apple-darwin
cargo build --release -p rpg --target aarch64-apple-darwin
GUI (egui/eframe links against AppKit and Metal on macOS):
cargo build --release -p rustpg --target aarch64-apple-darwin
The GUI requires the osxcross SDK to include AppKit and Metal headers. If the build fails with missing framework headers, ensure the SDK tarball was generated from a full Xcode install (not just Command Line Tools).
7 — Universal binary (optional)
Apple Silicon Macs can run x86_64 binaries via Rosetta 2, but a universal binary runs natively on both architectures:
lipo -create -output rpg-universal target/x86_64-apple-darwin/release/rpg target/aarch64-apple-darwin/release/rpg
Makefile targets (not yet added)
The Makefile does not yet have macos / macos-zip targets. The pattern follows the Windows targets:
MACOS_TARGET_X86 = x86_64-apple-darwin
MACOS_TARGET_ARM = aarch64-apple-darwin
macos-cli :
export MACOSX_DEPLOYMENT_TARGET=11.0 && \
cargo build --release -p rpg --target $(MACOS_TARGET_X86) && \
cargo build --release -p rpg --target $(MACOS_TARGET_ARM)
macos-setup :
rustup target add $(MACOS_TARGET_X86)
rustup target add $(MACOS_TARGET_ARM)
Generating icons
Each GUI binary has its own icon script (requires Pillow: pip install pillow). Run from the workspace root:
| Script | Output | Background |
|---|---|---|
assets/gen_icon_rustpg.py |
rustpg.png + rustpg.ico |
Blue gradient |
assets/gen_icon_librarian.py |
keylib-librarian.png + keylib-librarian.ico |
Teal gradient |
python3 assets/gen_icon_rustpg.py
python3 assets/gen_icon_librarian.py
Each ICO contains embedded sizes at 16/32/48/64/128/256 px. The .ico is embedded into the Windows EXE at compile time via build.rs + winresource.