threadpanic/rustpg
1
0
Fork
You've already forked rustpg
0
2 Building and Cross Compilation
Bert van der Weerd edited this page 2026年05月12日 12:02:22 +02:00

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 (patches Exec= and Icon= 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:

  1. Compile date: runs date "+%-d %b %Y" and exposes it as the COMPILE_DATE env var, shown in Help → About.
  2. Windows icon: when CARGO_CFG_TARGET_OS == "windows", calls winresource to embed assets/rustpg.ico into rustpg.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.exe
  • target/x86_64-pc-windows-gnu/release/rustpg.exe
  • target/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.