diff --git a/Makefile b/Makefile index 3aa9a292566..b3a45e90352 100644 --- a/Makefile +++ b/Makefile @@ -44,6 +44,9 @@ GIT_ROOT ?= $(shell git rev-parse --show-toplevel 2>/dev/null || echo .) run-statusq-sanity-checker \ statusq-tests \ run-statusq-tests \ + statusq-import-lib \ + nim-sds \ + copy-windows-dlls \ storybook-build \ run-storybook \ run-storybook-tests \ @@ -249,6 +252,56 @@ NIMSDS_LIBFILE := $(NIMSDS_LIBDIR)/libsds.$(LIB_EXT) NIM_EXTRA_PARAMS += --passL:"-L$(NIMSDS_LIBDIR)" --passL:"-lsds" STATUSGO_MAKE_PARAMS += NIM_SDS_SOURCE_DIR="$(NIM_SDS_SOURCE_DIR)" +# Common nim-sds build recipe (used by both Windows and non-Windows) +define BUILD_NIMSDS + @echo -e "\033[92mBuilding:\033[39m nim-sds" + @if [ ! -d "$(NIM_SDS_SOURCE_DIR)" ]; then \ + echo "Error: nim-sds directory not found at $(NIM_SDS_SOURCE_DIR)"; \ + echo "Please clone it or set NIM_SDS_SOURCE_DIR environment variable"; \ + exit 1; \ + fi + @$(MAKE) -C $(NIM_SDS_SOURCE_DIR) libsds USE_SYSTEM_NIM=1 SHELL=/bin/bash $(HANDLE_OUTPUT) +endef + +ifeq ($(mkspecs),win32) +# On Windows with MinGW, create import library for nim-sds +NIMSDS_DLL := $(NIMSDS_LIBDIR)/libsds.dll +NIMSDS_DEF := $(NIMSDS_LIBDIR)/libsds.def +NIMSDS_IMPORT_LIB := $(NIMSDS_LIBDIR)/libsds.dll.a + +$(NIMSDS_DEF): $(NIMSDS_DLL) + @echo -e "\033[92mCreating:\033[39m libsds.def" + @mkdir -p $(NIMSDS_LIBDIR) + @(echo "EXPORTS"; \ + echo "SdsCleanupReliabilityManager"; \ + echo "SdsMarkDependenciesMet"; \ + echo "SdsNewReliabilityManager"; \ + echo "SdsResetReliabilityManager"; \ + echo "SdsSetEventCallback"; \ + echo "SdsStartPeriodicTasks"; \ + echo "SdsUnwrapReceivedMessage"; \ + echo "SdsWrapOutgoingMessage"; \ + echo "libsdsNimDestroyGlobals"; \ + echo "libsdsNimMain") > $(NIMSDS_DEF) + +$(NIMSDS_IMPORT_LIB): $(NIMSDS_DLL) $(NIMSDS_DEF) + @echo -e "\033[92mCreating:\033[39m libsds.dll.a" + @rm -f $(NIMSDS_IMPORT_LIB) + @cd $(NIMSDS_LIBDIR) && dlltool --dllname libsds.dll --def libsds.def --output-lib libsds.dll.a || \ + (echo "Warning: Failed to create import library. Ensure dlltool is in PATH." && exit 0) + +$(NIMSDS_LIBFILE): | deps + $(BUILD_NIMSDS) + @$(MAKE) $(NIMSDS_IMPORT_LIB) || true + +nim-sds: $(NIMSDS_LIBFILE) $(NIMSDS_IMPORT_LIB) +else +$(NIMSDS_LIBFILE): | deps + $(BUILD_NIMSDS) + +nim-sds: $(NIMSDS_LIBFILE) +endif + INCLUDE_DEBUG_SYMBOLS ?= false ifeq ($(INCLUDE_DEBUG_SYMBOLS),true) # We need `-d:debug` to get Nim's default stack traces @@ -326,10 +379,35 @@ statusq-build: | statusq-configure statusq-install: | statusq-build echo -e "\033[92mInstalling:\033[39m StatusQ" + @mkdir -p $(STATUSQ_INSTALL_PATH)/StatusQ || true cmake --install $(STATUSQ_BUILD_PATH) \ $(HANDLE_OUTPUT) +ifeq ($(mkspecs),win32) +# On Windows with MinGW, create import libraries (.dll.a) from DLLs +STATUSQ_DLL := $(STATUSQ_INSTALL_PATH)/StatusQ/StatusQ.dll +STATUSQ_DEF := $(STATUSQ_INSTALL_PATH)/StatusQ/StatusQ.def +STATUSQ_IMPORT_LIB := $(STATUSQ_INSTALL_PATH)/StatusQ/libStatusQ.dll.a + +$(STATUSQ_DEF): $(STATUSQ_DLL) + @echo -e "\033[92mCreating:\033[39m StatusQ.def" + @mkdir -p $(STATUSQ_INSTALL_PATH)/StatusQ || true + @(echo "EXPORTS"; \ + echo "statusq_getMobileUIScaleFactor"; \ + echo "statusq_registerQmlTypes") > $(STATUSQ_DEF) + +$(STATUSQ_IMPORT_LIB): $(STATUSQ_DLL) $(STATUSQ_DEF) + @echo -e "\033[92mCreating:\033[39m libStatusQ.dll.a" + @mkdir -p $(STATUSQ_INSTALL_PATH)/StatusQ + @cd $(STATUSQ_INSTALL_PATH)/StatusQ && dlltool --dllname StatusQ.dll --def StatusQ.def --output-lib libStatusQ.dll.a || \ + (echo "Warning: Failed to create import library. Ensure dlltool is in PATH." && exit 0) + +statusq-import-lib: $(STATUSQ_IMPORT_LIB) + +statusq: | statusq-install statusq-import-lib +else statusq: | statusq-install +endif statusq-clean: echo -e "\033[92mCleaning:\033[39m StatusQ" @@ -474,6 +552,7 @@ STATUSGO := vendor/status-go/build/bin/libstatus.$(LIB_EXT) STATUSGO_LIBDIR := $(shell pwd)/$(shell dirname "$(STATUSGO)") export STATUSGO_LIBDIR +ifeq ($(mkspecs),win32) $(STATUSGO): | deps status-go-deps echo -e $(BUILD_MSG) "status-go" # FIXME: Nix shell usage breaks builds due to Glibc mismatch. @@ -481,6 +560,17 @@ $(STATUSGO): | deps status-go-deps SENTRY_CONTEXT_NAME="status-desktop" \ SENTRY_CONTEXT_VERSION="$(DESKTOP_VERSION)" \ $(HANDLE_OUTPUT) + # On Windows, ensure import library exists after status-go build + @if [ -f "$(NIMSDS_LIBFILE)" ]; then $(MAKE) $(NIMSDS_IMPORT_LIB) || true; fi +else +$(STATUSGO): | deps status-go-deps + echo -e $(BUILD_MSG) "status-go" + # FIXME: Nix shell usage breaks builds due to Glibc mismatch. + $(STATUSGO_MAKE_PARAMS) $(MAKE) -C vendor/status-go statusgo-shared-library SHELL=/bin/sh \ + SENTRY_CONTEXT_NAME="status-desktop" \ + SENTRY_CONTEXT_VERSION="$(DESKTOP_VERSION)" \ + $(HANDLE_OUTPUT) +endif status-go: $(STATUSGO) @@ -611,7 +701,33 @@ $(NIM_STATUS_CLIENT): update-qmake-previous endif $(NIM_STATUS_CLIENT): NIM_PARAMS += $(RESOURCES_LAYOUT) -$(NIM_STATUS_CLIENT): $(NIM_SOURCES) | statusq dotherside check-qt-dir $(STATUSGO) $(STATUSKEYCARDGO) $(QRCODEGEN) rcc deps +ifeq ($(mkspecs),win32) +# Copy DLLs to bin directory for Windows runtime +copy-windows-dlls: | statusq dotherside $(STATUSGO) $(STATUSKEYCARDGO) $(NIMSDS_LIBFILE) + @echo -e "\033[92mCopying:\033[39m Windows DLLs to bin directory" + @mkdir -p $(STATUSQ_INSTALL_PATH) + @mkdir -p $(STATUSQ_INSTALL_PATH)/StatusQ + @if [ -f "$(STATUSQ_INSTALL_PATH)/StatusQ/StatusQ.dll" ]; then \ + echo "StatusQ.dll already in $(STATUSQ_INSTALL_PATH)/StatusQ/"; \ + elif [ -f "$(STATUSQ_BUILD_PATH)/bin/$(COMMON_CMAKE_BUILD_TYPE)/StatusQ.dll" ]; then \ + cp "$(STATUSQ_BUILD_PATH)/bin/$(COMMON_CMAKE_BUILD_TYPE)/StatusQ.dll" "$(STATUSQ_INSTALL_PATH)/StatusQ/" 2>/dev/null || true; \ + fi + @rm -f "$(STATUSQ_INSTALL_PATH)/StatusQ.dll" 2>/dev/null || true + @if [ -f "$(DOTHERSIDE_LIBFILE)" ]; then \ + cp "$(DOTHERSIDE_LIBFILE)" "$(STATUSQ_INSTALL_PATH)/" 2>/dev/null || true; \ + fi + @if [ -f "$(STATUSGO)" ]; then \ + cp "$(STATUSGO)" "$(STATUSQ_INSTALL_PATH)/" 2>/dev/null || true; \ + fi + @if [ -f "$(STATUSKEYCARDGO)" ]; then \ + cp "$(STATUSKEYCARDGO)" "$(STATUSQ_INSTALL_PATH)/" 2>/dev/null || true; \ + fi + @if [ -f "$(NIMSDS_LIBFILE)" ]; then \ + cp "$(NIMSDS_LIBFILE)" "$(STATUSQ_INSTALL_PATH)/" 2>/dev/null || true; \ + fi +endif + +$(NIM_STATUS_CLIENT): $(NIM_SOURCES) | statusq dotherside check-qt-dir $(STATUSGO) $(STATUSKEYCARDGO) $(QRCODEGEN) rcc deps $(if $(filter win32,$(mkspecs)),copy-windows-dlls) echo -e $(BUILD_MSG) "$@" $(ENV_SCRIPT) nim c $(NIM_PARAMS) \ --mm:refc \ @@ -887,9 +1003,9 @@ run-macos: nim_status_client ./bin/StatusDev.app/Contents/MacOS/nim_status_client $(ARGS) run-windows: STATUS_RC_FILE = status-dev.rc -run-windows: compile_windows_resources nim_status_client +run-windows: compile_windows_resources nim_status_client $(if $(filter win32,$(mkspecs)),copy-windows-dlls) echo -e "\033[92mRunning:\033[39m bin/nim_status_client.exe" - PATH="$(DOTHERSIDE_LIBDIR)":"$(STATUSGO_LIBDIR)":"$(STATUSKEYCARDGO_LIBDIR)":"$(STATUSQ_INSTALL_PATH)/StatusQ":"$(PATH)" \ + PATH="$(DOTHERSIDE_LIBDIR)":"$(STATUSGO_LIBDIR)":"$(STATUSKEYCARDGO_LIBDIR)":"$(STATUSQ_INSTALL_PATH)/StatusQ":"$(STATUSQ_INSTALL_PATH)":"$(PATH)" \ ./bin/nim_status_client.exe $(ARGS) NIM_TEST_FILES := $(wildcard test/nim/*.nim) diff --git a/WINDOWS_BUILD_FIXES.md b/WINDOWS_BUILD_FIXES.md new file mode 100644 index 00000000000..627da6997f6 --- /dev/null +++ b/WINDOWS_BUILD_FIXES.md @@ -0,0 +1,191 @@ +# Windows Build Process Fixes + +This document explains the automated fixes added to the Makefile for Windows/MinGW builds. + +## Overview + +Three main issues were fixed and automated: +1. **nim-sds library build** - Ensures the library is built before linking +2. **Import library generation** - Creates `.dll.a` files for MinGW from DLLs +3. **DLL copying** - Copies all required DLLs to `bin/` directory for runtime + +## Changes Made + +### 1. nim-sds Build Automation + +**Location:** Lines ~255-282 in Makefile + +**What it does:** +- Builds the `nim-sds` library if it doesn't exist +- On Windows, automatically creates the import library (`libsds.dll.a`) after building the DLL +- Uses `dlltool` to generate the import library from the DLL + +**Key targets:** +- `nim-sds` - Builds nim-sds library and import library (Windows only) +- `$(NIMSDS_LIBFILE)` - Dependency that triggers the build + +**How it works:** +```makefile +$(NIMSDS_LIBFILE): | deps + # Builds libsds.dll + $(MAKE) -C $(NIM_SDS_SOURCE_DIR) libsds + + # Creates import library + dlltool --dllname libsds.dll --def libsds.def --output-lib libsds.dll.a +``` + +### 2. StatusQ Import Library Generation + +**Location:** Lines ~376-397 in Makefile + +**What it does:** +- After StatusQ is installed, automatically creates `libStatusQ.dll.a` import library +- Creates a `.def` file with the exported symbols (`statusq_registerQmlTypes`, `statusq_getMobileUIScaleFactor`) +- Uses `dlltool` to generate the MinGW-compatible import library + +**Key targets:** +- `statusq-import-lib` - Creates the import library +- `statusq` - Now depends on `statusq-import-lib` on Windows + +**Files created:** +- `bin/StatusQ/StatusQ.def` - Module definition file +- `bin/StatusQ/libStatusQ.dll.a` - Import library for MinGW + +**How it works:** +```makefile +$(STATUSQ_DEF): $(STATUSQ_DLL) + # Creates .def file with exports + echo "EXPORTS" > StatusQ.def + echo "statusq_registerQmlTypes" >> StatusQ.def + echo "statusq_getMobileUIScaleFactor" >> StatusQ.def + +$(STATUSQ_IMPORT_LIB): $(STATUSQ_DLL) $(STATUSQ_DEF) + # Creates import library + dlltool --dllname StatusQ.dll --def StatusQ.def --output-lib libStatusQ.dll.a +``` + +### 3. DLL Copying for Runtime + +**Location:** Lines ~680-690 in Makefile + +**What it does:** +- Copies all required DLLs to the `bin/` directory before building +- Ensures the executable can find DLLs at runtime (Windows searches the executable's directory) + +**Key targets:** +- `copy-windows-dlls` - Copies all DLLs to bin/ + +**DLLs copied:** +- `StatusQ.dll` +- `DOtherSide.dll` +- `libstatus.dll` +- `libkeycard.dll` +- `libsds.dll` + +**How it works:** +```makefile +copy-windows-dlls: | statusq dotherside $(STATUSGO) $(STATUSKEYCARDGO) $(NIMSDS_LIBFILE) + cp $(STATUSQ_INSTALL_PATH)/StatusQ/StatusQ.dll $(STATUSQ_INSTALL_PATH)/ + cp $(DOTHERSIDE_LIBFILE) $(STATUSQ_INSTALL_PATH)/ + # ... copies other DLLs +``` + +### 4. Updated Dependencies + +**Location:** Line ~692 in Makefile + +**What changed:** +- `nim_status_client` now depends on: + - `nim-sds` (Windows only) - Ensures nim-sds is built + - `copy-windows-dlls` (Windows only) - Ensures DLLs are in place + +**Before:** +```makefile +$(NIM_STATUS_CLIENT): ... | statusq dotherside ... +``` + +**After:** +```makefile +$(NIM_STATUS_CLIENT): ... | statusq dotherside ... $(if $(filter win32,$(mkspecs)),nim-sds copy-windows-dlls) +``` + +## Requirements + +### Tools Required + +1. **dlltool** - Part of MinGW toolchain + - Location: Usually in `C:\ProgramData\scoop\apps\gcc\current\bin\dlltool.exe` + - Used to create import libraries from DLLs + +2. **nim-sds source** - Must be cloned + - Default location: `../nim-sds` (relative to status-app) + - Can be overridden with `NIM_SDS_SOURCE_DIR` environment variable + +## Usage + +### Normal Build + +Just run the normal build command: +```bash +make nim_status_client +``` + +The build process will automatically: +1. Build nim-sds if needed +2. Build StatusQ and create import library +3. Copy DLLs to bin directory +4. Build the executable + +### Manual Steps (if needed) + +If you need to rebuild just the import libraries: + +```bash +# Rebuild StatusQ import library +make statusq-import-lib + +# Rebuild nim-sds import library +make nim-sds + +# Copy DLLs manually +make copy-windows-dlls +``` + +## Troubleshooting + +### Error: "dlltool not found" +- Ensure MinGW is installed and in PATH +- Or set the full path to dlltool in the Makefile + +### Error: "nim-sds directory not found" +- Clone nim-sds: `git clone https://github.com/waku-org/nim-sds.git ../nim-sds` +- Or set `NIM_SDS_SOURCE_DIR` environment variable + +### Import library creation fails silently +- Check that `dlltool` is available: `which dlltool` (Git Bash) or `where dlltool` (PowerShell) +- Verify the DLL exists before creating import library +- Check the `.def` file was created correctly + +## Technical Details + +### Why Import Libraries Are Needed + +On Windows with MinGW: +- MSVC creates `.lib` files (not compatible with MinGW linker) +- MinGW linker needs `.dll.a` import libraries +- These contain stub functions that redirect to the DLL at runtime + +### Symbol Export + +The `statusq_registerQmlTypes` function is exported from StatusQ.dll using: +- `Q_DECL_EXPORT` macro in C++ +- `extern "C"` linkage for C compatibility +- Listed in the `.def` file for import library generation + +## Future Improvements + +1. **Auto-detect exports** - Use `objdump` or `pexports` to automatically extract symbols +2. **Better error handling** - Fail build if import library creation fails +3. **Cleanup targets** - Add targets to remove generated import libraries +4. **Cross-platform** - Ensure these changes don't affect Linux/macOS builds + diff --git a/WINDOWS_DEF_FILES.md b/WINDOWS_DEF_FILES.md new file mode 100644 index 00000000000..052003128fd --- /dev/null +++ b/WINDOWS_DEF_FILES.md @@ -0,0 +1,101 @@ +# Windows Import Library Definition Files + +This document describes the `.def` files used to create MinGW import libraries on Windows. + +## File Locations + +### Static Template Files (for reference/documentation) +- `windows-build-files/libsds.def` - Definition file for nim-sds library +- `windows-build-files/StatusQ.def` - Definition file for StatusQ library + +### Generated Files (created during build) +- `../nim-sds/build/libsds.def` - Generated from Makefile (line 261-274) +- `bin/StatusQ/StatusQ.def` - Generated from Makefile (line 393-396) + +## File Contents + +### libsds.def +``` +EXPORTS +SdsCleanupReliabilityManager +SdsMarkDependenciesMet +SdsNewReliabilityManager +SdsResetReliabilityManager +SdsSetEventCallback +SdsStartPeriodicTasks +SdsUnwrapReceivedMessage +SdsWrapOutgoingMessage +libsdsNimDestroyGlobals +libsdsNimMain +``` + +### StatusQ.def +``` +EXPORTS +statusq_getMobileUIScaleFactor +statusq_registerQmlTypes +``` + +## Makefile Changes + +The `.def` files are automatically generated in the Makefile at: + +### libsds.def generation (lines 261-274) +```makefile +$(NIMSDS_DEF): $(NIMSDS_DLL) + @echo -e "\033[92mCreating:\033[39m libsds.def" + @mkdir -p $(NIMSDS_LIBDIR) + @(echo "EXPORTS"; \ + echo "SdsCleanupReliabilityManager"; \ + echo "SdsMarkDependenciesMet"; \ + echo "SdsNewReliabilityManager"; \ + echo "SdsResetReliabilityManager"; \ + echo "SdsSetEventCallback"; \ + echo "SdsStartPeriodicTasks"; \ + echo "SdsUnwrapReceivedMessage"; \ + echo "SdsWrapOutgoingMessage"; \ + echo "libsdsNimDestroyGlobals"; \ + echo "libsdsNimMain") > $(NIMSDS_DEF) +``` + +### StatusQ.def generation (lines 393-396) +```makefile +$(STATUSQ_DEF): $(STATUSQ_DLL) + @echo -e "\033[92mCreating:\033[39m StatusQ.def" + @mkdir -p $(STATUSQ_INSTALL_PATH)/StatusQ || true + @(echo "EXPORTS"; \ + echo "statusq_getMobileUIScaleFactor"; \ + echo "statusq_registerQmlTypes") > $(STATUSQ_DEF) +``` + +## Purpose + +These `.def` files list the exported symbols from the DLLs. They are used by `dlltool` to create MinGW-compatible import libraries (`.dll.a` files) that allow the linker to resolve symbols at link time. + +## Why These Symbols? + +### libsds.def +All symbols exported from `libsds.dll` as determined by: +```bash +objdump -p libsds.dll | grep Sds +``` + +These are the C functions that status-go's CGO code calls. + +### StatusQ.def +The two C functions exported from StatusQ.dll: +- `statusq_registerQmlTypes` - Called from Nim to register QML types +- `statusq_getMobileUIScaleFactor` - Called from Nim for mobile UI scaling + +## Alternative: Using Static Files + +If you prefer to use the static files instead of generating them, you could modify the Makefile to copy from the static location: + +```makefile +$(NIMSDS_DEF): windows-build-files/libsds.def + @mkdir -p $(NIMSDS_LIBDIR) + @cp windows-build-files/libsds.def $(NIMSDS_DEF) +``` + +However, the current approach (generating them) ensures they're always in sync with the actual DLL exports. + diff --git a/windows-build-files/StatusQ.def b/windows-build-files/StatusQ.def new file mode 100644 index 00000000000..fb909681fbb --- /dev/null +++ b/windows-build-files/StatusQ.def @@ -0,0 +1,4 @@ +EXPORTS +statusq_getMobileUIScaleFactor +statusq_registerQmlTypes + diff --git a/windows-build-files/libsds.def b/windows-build-files/libsds.def new file mode 100644 index 00000000000..2d78f0192a5 --- /dev/null +++ b/windows-build-files/libsds.def @@ -0,0 +1,12 @@ +EXPORTS +SdsCleanupReliabilityManager +SdsMarkDependenciesMet +SdsNewReliabilityManager +SdsResetReliabilityManager +SdsSetEventCallback +SdsStartPeriodicTasks +SdsUnwrapReceivedMessage +SdsWrapOutgoingMessage +libsdsNimDestroyGlobals +libsdsNimMain +