Selaa lähdekoodia

app: add `make win64-msvc` target, see README.md, test with `wine darkfi-app.exe`

darkfi 3 viikkoa sitten
vanhempi
sitoutus
c95d1e24e1
6 muutettua tiedostoa jossa 99 lisäystä ja 213 poistoa
  1. 5 18
      bin/app/Makefile
  2. 35 1
      bin/app/README.md
  3. 39 5
      bin/app/build.rs
  4. 0 188
      bin/app/release/win/README.md
  5. 3 1
      bin/app/release/win/package.sh
  6. 17 0
      bin/app/release/win/rc.exe

+ 5 - 18
bin/app/Makefile

@@ -47,12 +47,9 @@ linux-release: build-release
 	-mv darkfi-app darkfi-app.linux
 linux-debug: build-debug
 	-mv darkfi-app darkfi-app_debug.linux
-win-release: $(SRC) $(PROOFS_BIN) fonts
-	$(CARGO) build --no-default-features --release $(RELEASE_FEATURES)
-	-mv target/release/darkfi-app.exe .
-win-debug: $(SRC) $(PROOFS_BIN) fonts
-	$(CARGO) build --no-default-features $(DEBUG_FEATURES)
-	-mv target/debug/darkfi-app.exe .
+win64-msvc: $(SRC) $(PROOFS_BIN) fonts
+	PATH="$(shell pwd)/release/win:$$PATH" $(CARGO) xwin build --no-default-features --release --target x86_64-pc-windows-msvc $(RELEASE_FEATURES)
+	-mv target/x86_64-pc-windows-msvc/release/darkfi-app.exe .
 android-release: $(SRC) $(PROOFS_BIN) fonts assets/forest_720x1280.mp4
 	podman run -v $(shell pwd)/../../:/root/darkfi -w /root/darkfi/bin/app/ -t apk cargo quad-apk build --no-default-features --release $(RELEASE_FEATURES)
 	-mv $(RELEASE_APK) darkfi-app.apk
@@ -60,16 +57,6 @@ android-debug: $(SRC) $(PROOFS_BIN) fonts assets/forest_720x1280.mp4
 	podman run -v $(shell pwd)/../../:/root/darkfi -w /root/darkfi/bin/app/ -t apk cargo quad-apk build --no-default-features $(DEBUG_FEATURES)
 	-mv $(DEBUG_APK) darkfi-app_debug.apk
 
-# Windows cross-compilation using Docker/Podman
-win-docker-release: $(SRC)
-	podman run -v $(shell pwd):/root/build -w /root/build/ -t windows \
-		cargo build --no-default-features --release --target x86_64-pc-windows-gnu $(RELEASE_FEATURES)
-	./release/win/package.sh release
-win-docker-debug: $(SRC)
-	podman run -v $(shell pwd):/root/build -w /root/build/ -t windows \
-		cargo build --no-default-features --target x86_64-pc-windows-gnu $(DEBUG_FEATURES)
-	./release/win/package.sh debug
-
 build-release: $(SRC) $(PROOFS_BIN) fonts assets/forest_1920x1080.ivf
 	$(CARGO) build --no-default-features --release $(RELEASE_FEATURES)
 	-mv target/release/darkfi-app .
@@ -118,8 +105,8 @@ $(PROOFS_BIN): zkas $(PROOFS_SRC)
 # Developer targets
 
 compile-dev: $(SRC) $(PROOFS_BIN) fonts assets/forest_1920x1080.ivf
-	$(CARGO) lbuild --no-default-features $(DEV_FEATURES)
-	-mv target/debug/darkfi-app .
+	$(CARGO) lbuild --release --no-default-features $(DEV_FEATURES)
+	-mv target/release/darkfi-app .
 
 dev:
 	$(MAKE) compile-dev

+ 35 - 1
bin/app/README.md

@@ -8,11 +8,45 @@ make
 
 # Windows
 
-Install [rustup](rustup.rs) and follow the instructions.
+Built by cross-compiling on Linux using [cargo-xwin] (MSVC ABI, clang-cl/lld-link).
+Also install [rustup](rustup.rs).
+
+Distro packages needed (example uses Void Linux):
+
+```
+# xbps-install -S clang lld ninja nasm wget \
+    cross-x86_64-w64-mingw32 cross-x86_64-w64-mingw32-crt
+```
+
+The mingw packages provide `windres`, which is used to embed the app icon
+and the Windows version resource turso needs (`rc.exe` does not exist on
+Linux). On Arch the equivalents are `clang lld ninja nasm mingw-w64-gcc`,
+on Debian `clang lld ninja-build nasm gcc-mingw-w64-x86-64`, and on Fedora
+`clang lld ninja-build nasm mingw64-gcc`.
+
+Then set up the Rust side:
+
+```
+$ rustup target add x86_64-pc-windows-msvc
+$ rustup component add llvm-tools
+$ cargo install --locked cargo-xwin
+```
+
+And build:
+
+```
+$ make win64-msvc
+```
+
+The first run downloads the Windows SDK and MSVC CRT (a couple of GB) and
+caches them. Using cargo-xwin implies accepting Microsoft's SDK license.
+The resulting `darkfi-app.exe` is placed in `bin/app/`, and can be tested
+on Linux using `wine darkfi-app.exe`.
 
 If you get the error "VCRUNTIME140.dll was not found", then
 install [Microsoft Visual C++ Redistributable][msvc++].
 
+[cargo-xwin]: https://github.com/rust-cross/cargo-xwin
 [msvc++]: https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#visual-studio-2015-2017-2019-and-2022
 
 # Android

+ 39 - 5
bin/app/build.rs

@@ -16,7 +16,12 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-use std::{fs::File, io::Write};
+use std::{
+    env, fs,
+    io::Write,
+    path::{Path, PathBuf},
+    process::Command,
+};
 
 /// Adds a temporary workaround for [an issue] with the Rust compiler and Android when
 /// compiling sqlite3 bundled C code.
@@ -41,16 +46,21 @@ use std::{fs::File, io::Write};
 /// [zcash issue]: https://github.com/zcash/librustzcash/issues/800
 /// [their workaround]: https://github.com/Electric-Coin-Company/zcash-android-wallet-sdk/blob/88058c63461f2808efc953af70db726b9f36f9b9/backend-lib/build.rs
 fn main() {
-    let target_os = std::env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS not set");
-    let target_arch =
-        std::env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH not set");
+    let target_os = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS not set");
+    let target_arch = env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH not set");
     //println!("cargo:warning={target_arch}");
 
+    let out_dir = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR not set"));
+
     // Add some useful debug info directly into the app itself
-    let mut f = File::create("src/build_info.rs").unwrap();
+    let mut f = fs::File::create("src/build_info.rs").unwrap();
     writeln!(f, "pub const TARGET_OS: &'static str = \"{target_os}\";").unwrap();
     writeln!(f, "pub const TARGET_ARCH: &'static str = \"{target_arch}\";").unwrap();
 
+    if target_os == "windows" {
+        embed_windows_icon(&out_dir);
+    }
+
     if target_os == "android" {
         // Since we run this inside a container, we can just hardcore the paths directly
         println!("cargo:rustc-link-search=/opt/android-ndk-r29/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/21/lib/linux/");
@@ -66,3 +76,27 @@ fn main() {
         }
     }
 }
+
+/// Embeds `release/win/darkfi.ico` as the exe icon on Windows targets,
+/// using mingw's windres directly.
+fn embed_windows_icon(out_dir: &Path) {
+    let manifest_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
+    let ico_path = PathBuf::from(manifest_dir).join("release/win/darkfi.ico");
+    println!("cargo:rerun-if-changed={}", ico_path.display());
+
+    let rc_path = out_dir.join("app.rc");
+    let icon_rc = format!("1 ICON \"{}\"", ico_path.display());
+    fs::write(&rc_path, icon_rc).expect("write icon rc script");
+
+    let res_path = out_dir.join("app.res");
+    let status = Command::new("x86_64-w64-mingw32-windres")
+        .arg(&rc_path)
+        .arg("-O")
+        .arg("coff")
+        .arg("-o")
+        .arg(&res_path)
+        .status()
+        .expect("run windres");
+    assert!(status.success(), "windres failed");
+    println!("cargo:rustc-link-arg-bins={}", res_path.display());
+}

+ 0 - 188
bin/app/release/win/README.md

@@ -1,188 +0,0 @@
-# Windows Build Guide
-
-## Automated Cross-Compilation (Recommended)
-
-The easiest way to build for Windows from Linux is using Docker/Podman with cross-compilation. This eliminates the need for a Windows VM.
-
-### Prerequisites
-
-- Podman (or Docker)
-- Make
-
-### Build Instructions
-
-```bash
-# Build the Windows cross-compilation container
-podman build -t windows -f Dockerfile.windows .
-
-# Build Windows release
-make win-docker-release
-
-# Output files:
-#   - darkfi-win64-release.zip (portable archive)
-#   - darkfi-win64-release-installer.exe (installer with shortcuts)
-```
-
-### Distribution
-
-- **ZIP archive**: Extract and run `darkfi-app.exe` - no installation required
-- **Installer**: Run `darkfi-win64-release-installer.exe` for proper installation with Start Menu/Desktop shortcuts
-
-### Debug Builds
-
-```bash
-make win-docker-debug
-```
-
----
-
-## Manual VM Build (Legacy)
-
-Skip the first step if you're already using Windows.
-
-## Prepare the VM
-
-You will need qemu and the remote-viewer tool.
-
-Provision a disk:
-
-```
-qemu-img create -f raw winblows-raw.disk 100G
-```
-
-Download the Windows ISO from their website. Use this script to launch QEMU.
-
-```
-#!/bin/bash
-
-ISO=Win10_22H2_EnglishInternational_x64v1.iso
-
-args=(
-    --cdrom $ISO --boot order=d
-
-    -drive file=winblows-disk.raw,format=raw
-
-    -m 30G -accel kvm -cpu qemu64
-
-    # We forward 22 to 10022 for SSH
-    #-net nic -net user,hostname=windowsvm
-    -net nic -net user,hostname=windowsvm,hostfwd=tcp:127.0.0.1:10146-:22
-
-    # This fixes the fucked up mouse
-    #-device qemu-xhci -device usb-mouse -device usb-tablet
-    -machine vmport=off
-
-    # Auto-resize display
-    # -vga qxl
-    # We use virtio since it allows us the full res size at least
-    -vga virtio -spice port=30001,disable-ticketing=on
-    -device virtio-serial -chardev spicevmc,id=vdagent,debug=0,name=vdagent
-    -device virtserialport,chardev=vdagent,name=com.redhat.spice.0
-)
-
-qemu-system-x86_64 "${args[@]}"
-```
-
-There will be no output. Use remote-viewer to attach the display:
-
-```
-remote-viewer spice://localhost:30001
-```
-
-Now install Windows. Then power off Windows. Download the [virtio-win ISO].
-Modify the `ISO=...` line of the script above and relaunch the VM.
-
-Navigate to the CD drive in the file explorer and install the virtio x64 driver.
-
-In your browser go to "spice windows guest" and scroll down the webpage.
-Download and install "Windows SPICE Guest Tools".
-
-Relaunch the Windows VM. Adjust your display resolution and fullscreen the VM.
-
-### (Optional) Enable SSH
-
-This will enable you to work on Windows from within your host.
-
-Open Settings -> Apps -> Optional features -> + Add a feature. Search
-for "OpenSSH Server" and install it.
-
-Open Services -> OpenSSH SSH Server. Make "Startup type" Automatic.
-
-You can now ssh into your windows and use cmd.exe. In the script above,
-we forward port 22 to 10146. You can put this in `~/.ssh/config`.
-
-```
-Host winblows
-    Hostname localhost
-    User a
-    Port 10146
-```
-
-You can also make an `/etc/fstab` entry with:
-
-```
-sshfs#winblows: 		/mnt/winblows  		fuse  	noauto,defaults  	0  	0
-```
-
-Then `mount /mnt/winblows && cd /mnt/winblows/.ssh/` and copy your SSH pubkey
-to `authorized_keys`.
-Open "This PC", View -> Hidden files, open `C:\ProgramData\ssh\sshd_config`
-to disable password login and just use pubkey auth.
-Also disable the administrator auth keys setting in there too (bottom 2 lines).
-Then restart SSH.
-
-## Setting Up the Dev Environment
-
-Install rustup, which will also install Visual Studio. Next, next, finish.
-After visual studio, it will then proceed with the rustup install.
-Select 2 and enter nightly.
-
-```
-1) Proceed with standard installation (default - just press enter)
-2) Customize installation
-3) Cancel installation
->2
-
-Default host triple? [x86_64-pc-windows-msvc]
-(leave this unchanged)
-
-Default toolchain? (stable/beta/nightly/none)
-nightly
-
-Profile (which tools and data to install)? (minimal/default/complete) [default]
-(leave this unchanged)
-```
-
-Then proceed with the installation (option 1).
-
-## Building the DarkFi App
-
-Go to the [git repo] and select "⋯", then Download ZIP. Unzip the folder
-in an accessible place.
-
-Open cmd and navigate to the folder. Now run `cargo build`.
-
-```
-C:\Users\a> cd ../../darkfi/bin/app/
-C:\darkfi\bin\app> cargo build --release --features=enable-plugins
-```
-
-## Create Installer
-
-* Use Advanced Installer to create an MSI installer.
-    * Application Folder should have `DarkFi App.exe` and `assets/`.
-* Add shortcuts. Use the provided darkfi.ico icon.
-    * Application Shortcut Folder
-    * Desktop
-
-## (Optional) Mesa GL for Tesing
-
-This is buggy af software renderer. App will often randomly crash.
-For testing it's better to use a cheap laptop.
-
-* Setup OpenGL using [this guide](https://thomas.inf3.ch/2019-06-12-opengl-kvm-mesa3d/index.html).
-    * Download [mesa3d-xxx-release-msvc.7z](https://github.com/pal1000/mesa-dist-win/releases)
-      and install the default options.
-
-[virtio-win ISO]: https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/virtio-win.iso
-

+ 3 - 1
bin/app/release/win/package.sh

@@ -2,12 +2,14 @@
 set -e
 
 VERSION=${1:-"dev"}
+PROFILE=${2:-"release"}
+TARGET=${3:-"x86_64-pc-windows-gnu"}
 DIST_DIR="darkfi-win64-${VERSION}"
 rm -rf "${DIST_DIR}"
 mkdir -p "${DIST_DIR}"
 
 # Copy binary
-cp target/x86_64-pc-windows-gnu/release/darkfi-app.exe "${DIST_DIR}/"
+cp "target/${TARGET}/${PROFILE}/darkfi-app.exe" "${DIST_DIR}/"
 
 # Copy assets
 cp -r assets "${DIST_DIR}/"

+ 17 - 0
bin/app/release/win/rc.exe

@@ -0,0 +1,17 @@
+#!/bin/sh
+# rc.exe replacement for cross builds, forwards to mingw windres
+out=
+in=
+for arg in "$@"; do
+    case "$arg" in
+        /fo*)
+            out=${arg#/fo}
+            ;;
+        /nologo|/r|/v)
+            ;;
+        *)
+            in=$arg
+            ;;
+    esac
+done
+exec x86_64-w64-mingw32-windres "$in" -O coff -o "$out"