Skip to content

Commit c4aa408

Browse files
committed
makefile to make windows great again
1 parent 2966e3b commit c4aa408

File tree

5 files changed

+427
-3
lines changed

5 files changed

+427
-3
lines changed

Makefile

Lines changed: 119 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ GIT_ROOT ?= $(shell git rev-parse --show-toplevel 2>/dev/null || echo .)
4444
run-statusq-sanity-checker \
4545
statusq-tests \
4646
run-statusq-tests \
47+
statusq-import-lib \
48+
nim-sds \
49+
copy-windows-dlls \
4750
storybook-build \
4851
run-storybook \
4952
run-storybook-tests \
@@ -249,6 +252,56 @@ NIMSDS_LIBFILE := $(NIMSDS_LIBDIR)/libsds.$(LIB_EXT)
249252
NIM_EXTRA_PARAMS += --passL:"-L$(NIMSDS_LIBDIR)" --passL:"-lsds"
250253
STATUSGO_MAKE_PARAMS += NIM_SDS_SOURCE_DIR="$(NIM_SDS_SOURCE_DIR)"
251254

255+
# Common nim-sds build recipe (used by both Windows and non-Windows)
256+
define BUILD_NIMSDS
257+
@echo -e "\033[92mBuilding:\033[39m nim-sds"
258+
@if [ ! -d "$(NIM_SDS_SOURCE_DIR)" ]; then \
259+
echo "Error: nim-sds directory not found at $(NIM_SDS_SOURCE_DIR)"; \
260+
echo "Please clone it or set NIM_SDS_SOURCE_DIR environment variable"; \
261+
exit 1; \
262+
fi
263+
@$(MAKE) -C $(NIM_SDS_SOURCE_DIR) libsds USE_SYSTEM_NIM=1 SHELL=/bin/bash $(HANDLE_OUTPUT)
264+
endef
265+
266+
ifeq ($(mkspecs),win32)
267+
# On Windows with MinGW, create import library for nim-sds
268+
NIMSDS_DLL := $(NIMSDS_LIBDIR)/libsds.dll
269+
NIMSDS_DEF := $(NIMSDS_LIBDIR)/libsds.def
270+
NIMSDS_IMPORT_LIB := $(NIMSDS_LIBDIR)/libsds.dll.a
271+
272+
$(NIMSDS_DEF): $(NIMSDS_DLL)
273+
@echo -e "\033[92mCreating:\033[39m libsds.def"
274+
@mkdir -p $(NIMSDS_LIBDIR)
275+
@(echo "EXPORTS"; \
276+
echo "SdsCleanupReliabilityManager"; \
277+
echo "SdsMarkDependenciesMet"; \
278+
echo "SdsNewReliabilityManager"; \
279+
echo "SdsResetReliabilityManager"; \
280+
echo "SdsSetEventCallback"; \
281+
echo "SdsStartPeriodicTasks"; \
282+
echo "SdsUnwrapReceivedMessage"; \
283+
echo "SdsWrapOutgoingMessage"; \
284+
echo "libsdsNimDestroyGlobals"; \
285+
echo "libsdsNimMain") > $(NIMSDS_DEF)
286+
287+
$(NIMSDS_IMPORT_LIB): $(NIMSDS_DLL) $(NIMSDS_DEF)
288+
@echo -e "\033[92mCreating:\033[39m libsds.dll.a"
289+
@rm -f $(NIMSDS_IMPORT_LIB)
290+
@cd $(NIMSDS_LIBDIR) && dlltool --dllname libsds.dll --def libsds.def --output-lib libsds.dll.a || \
291+
(echo "Warning: Failed to create import library. Ensure dlltool is in PATH." && exit 0)
292+
293+
$(NIMSDS_LIBFILE): | deps
294+
$(BUILD_NIMSDS)
295+
@$(MAKE) $(NIMSDS_IMPORT_LIB) || true
296+
297+
nim-sds: $(NIMSDS_LIBFILE) $(NIMSDS_IMPORT_LIB)
298+
else
299+
$(NIMSDS_LIBFILE): | deps
300+
$(BUILD_NIMSDS)
301+
302+
nim-sds: $(NIMSDS_LIBFILE)
303+
endif
304+
252305
INCLUDE_DEBUG_SYMBOLS ?= false
253306
ifeq ($(INCLUDE_DEBUG_SYMBOLS),true)
254307
# We need `-d:debug` to get Nim's default stack traces
@@ -326,10 +379,35 @@ statusq-build: | statusq-configure
326379

327380
statusq-install: | statusq-build
328381
echo -e "\033[92mInstalling:\033[39m StatusQ"
382+
@mkdir -p $(STATUSQ_INSTALL_PATH)/StatusQ || true
329383
cmake --install $(STATUSQ_BUILD_PATH) \
330384
$(HANDLE_OUTPUT)
331385

386+
ifeq ($(mkspecs),win32)
387+
# On Windows with MinGW, create import libraries (.dll.a) from DLLs
388+
STATUSQ_DLL := $(STATUSQ_INSTALL_PATH)/StatusQ/StatusQ.dll
389+
STATUSQ_DEF := $(STATUSQ_INSTALL_PATH)/StatusQ/StatusQ.def
390+
STATUSQ_IMPORT_LIB := $(STATUSQ_INSTALL_PATH)/StatusQ/libStatusQ.dll.a
391+
392+
$(STATUSQ_DEF): $(STATUSQ_DLL)
393+
@echo -e "\033[92mCreating:\033[39m StatusQ.def"
394+
@mkdir -p $(STATUSQ_INSTALL_PATH)/StatusQ || true
395+
@(echo "EXPORTS"; \
396+
echo "statusq_getMobileUIScaleFactor"; \
397+
echo "statusq_registerQmlTypes") > $(STATUSQ_DEF)
398+
399+
$(STATUSQ_IMPORT_LIB): $(STATUSQ_DLL) $(STATUSQ_DEF)
400+
@echo -e "\033[92mCreating:\033[39m libStatusQ.dll.a"
401+
@mkdir -p $(STATUSQ_INSTALL_PATH)/StatusQ
402+
@cd $(STATUSQ_INSTALL_PATH)/StatusQ && dlltool --dllname StatusQ.dll --def StatusQ.def --output-lib libStatusQ.dll.a || \
403+
(echo "Warning: Failed to create import library. Ensure dlltool is in PATH." && exit 0)
404+
405+
statusq-import-lib: $(STATUSQ_IMPORT_LIB)
406+
407+
statusq: | statusq-install statusq-import-lib
408+
else
332409
statusq: | statusq-install
410+
endif
333411

334412
statusq-clean:
335413
echo -e "\033[92mCleaning:\033[39m StatusQ"
@@ -474,13 +552,25 @@ STATUSGO := vendor/status-go/build/bin/libstatus.$(LIB_EXT)
474552
STATUSGO_LIBDIR := $(shell pwd)/$(shell dirname "$(STATUSGO)")
475553
export STATUSGO_LIBDIR
476554

555+
ifeq ($(mkspecs),win32)
477556
$(STATUSGO): | deps status-go-deps
478557
echo -e $(BUILD_MSG) "status-go"
479558
# FIXME: Nix shell usage breaks builds due to Glibc mismatch.
480559
$(STATUSGO_MAKE_PARAMS) $(MAKE) -C vendor/status-go statusgo-shared-library SHELL=/bin/sh \
481560
SENTRY_CONTEXT_NAME="status-desktop" \
482561
SENTRY_CONTEXT_VERSION="$(DESKTOP_VERSION)" \
483562
$(HANDLE_OUTPUT)
563+
# On Windows, ensure import library exists after status-go build
564+
@if [ -f "$(NIMSDS_LIBFILE)" ]; then $(MAKE) $(NIMSDS_IMPORT_LIB) || true; fi
565+
else
566+
$(STATUSGO): | deps status-go-deps
567+
echo -e $(BUILD_MSG) "status-go"
568+
# FIXME: Nix shell usage breaks builds due to Glibc mismatch.
569+
$(STATUSGO_MAKE_PARAMS) $(MAKE) -C vendor/status-go statusgo-shared-library SHELL=/bin/sh \
570+
SENTRY_CONTEXT_NAME="status-desktop" \
571+
SENTRY_CONTEXT_VERSION="$(DESKTOP_VERSION)" \
572+
$(HANDLE_OUTPUT)
573+
endif
484574

485575
status-go: $(STATUSGO)
486576

@@ -611,7 +701,33 @@ $(NIM_STATUS_CLIENT): update-qmake-previous
611701
endif
612702

613703
$(NIM_STATUS_CLIENT): NIM_PARAMS += $(RESOURCES_LAYOUT)
614-
$(NIM_STATUS_CLIENT): $(NIM_SOURCES) | statusq dotherside check-qt-dir $(STATUSGO) $(STATUSKEYCARDGO) $(QRCODEGEN) rcc deps
704+
ifeq ($(mkspecs),win32)
705+
# Copy DLLs to bin directory for Windows runtime
706+
copy-windows-dlls: | statusq dotherside $(STATUSGO) $(STATUSKEYCARDGO) $(NIMSDS_LIBFILE)
707+
@echo -e "\033[92mCopying:\033[39m Windows DLLs to bin directory"
708+
@mkdir -p $(STATUSQ_INSTALL_PATH)
709+
@mkdir -p $(STATUSQ_INSTALL_PATH)/StatusQ
710+
@if [ -f "$(STATUSQ_INSTALL_PATH)/StatusQ/StatusQ.dll" ]; then \
711+
echo "StatusQ.dll already in $(STATUSQ_INSTALL_PATH)/StatusQ/"; \
712+
elif [ -f "$(STATUSQ_BUILD_PATH)/bin/$(COMMON_CMAKE_BUILD_TYPE)/StatusQ.dll" ]; then \
713+
cp "$(STATUSQ_BUILD_PATH)/bin/$(COMMON_CMAKE_BUILD_TYPE)/StatusQ.dll" "$(STATUSQ_INSTALL_PATH)/StatusQ/" 2>/dev/null || true; \
714+
fi
715+
@rm -f "$(STATUSQ_INSTALL_PATH)/StatusQ.dll" 2>/dev/null || true
716+
@if [ -f "$(DOTHERSIDE_LIBFILE)" ]; then \
717+
cp "$(DOTHERSIDE_LIBFILE)" "$(STATUSQ_INSTALL_PATH)/" 2>/dev/null || true; \
718+
fi
719+
@if [ -f "$(STATUSGO)" ]; then \
720+
cp "$(STATUSGO)" "$(STATUSQ_INSTALL_PATH)/" 2>/dev/null || true; \
721+
fi
722+
@if [ -f "$(STATUSKEYCARDGO)" ]; then \
723+
cp "$(STATUSKEYCARDGO)" "$(STATUSQ_INSTALL_PATH)/" 2>/dev/null || true; \
724+
fi
725+
@if [ -f "$(NIMSDS_LIBFILE)" ]; then \
726+
cp "$(NIMSDS_LIBFILE)" "$(STATUSQ_INSTALL_PATH)/" 2>/dev/null || true; \
727+
fi
728+
endif
729+
730+
$(NIM_STATUS_CLIENT): $(NIM_SOURCES) | statusq dotherside check-qt-dir $(STATUSGO) $(STATUSKEYCARDGO) $(QRCODEGEN) rcc deps $(if $(filter win32,$(mkspecs)),copy-windows-dlls)
615731
echo -e $(BUILD_MSG) "$@"
616732
$(ENV_SCRIPT) nim c $(NIM_PARAMS) \
617733
--mm:refc \
@@ -887,9 +1003,9 @@ run-macos: nim_status_client
8871003
./bin/StatusDev.app/Contents/MacOS/nim_status_client $(ARGS)
8881004

8891005
run-windows: STATUS_RC_FILE = status-dev.rc
890-
run-windows: compile_windows_resources nim_status_client
1006+
run-windows: compile_windows_resources nim_status_client $(if $(filter win32,$(mkspecs)),copy-windows-dlls)
8911007
echo -e "\033[92mRunning:\033[39m bin/nim_status_client.exe"
892-
PATH="$(DOTHERSIDE_LIBDIR)":"$(STATUSGO_LIBDIR)":"$(STATUSKEYCARDGO_LIBDIR)":"$(STATUSQ_INSTALL_PATH)/StatusQ":"$(PATH)" \
1008+
PATH="$(DOTHERSIDE_LIBDIR)":"$(STATUSGO_LIBDIR)":"$(STATUSKEYCARDGO_LIBDIR)":"$(STATUSQ_INSTALL_PATH)/StatusQ":"$(STATUSQ_INSTALL_PATH)":"$(PATH)" \
8931009
./bin/nim_status_client.exe $(ARGS)
8941010

8951011
NIM_TEST_FILES := $(wildcard test/nim/*.nim)

WINDOWS_BUILD_FIXES.md

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
# Windows Build Process Fixes
2+
3+
This document explains the automated fixes added to the Makefile for Windows/MinGW builds.
4+
5+
## Overview
6+
7+
Three main issues were fixed and automated:
8+
1. **nim-sds library build** - Ensures the library is built before linking
9+
2. **Import library generation** - Creates `.dll.a` files for MinGW from DLLs
10+
3. **DLL copying** - Copies all required DLLs to `bin/` directory for runtime
11+
12+
## Changes Made
13+
14+
### 1. nim-sds Build Automation
15+
16+
**Location:** Lines ~255-282 in Makefile
17+
18+
**What it does:**
19+
- Builds the `nim-sds` library if it doesn't exist
20+
- On Windows, automatically creates the import library (`libsds.dll.a`) after building the DLL
21+
- Uses `dlltool` to generate the import library from the DLL
22+
23+
**Key targets:**
24+
- `nim-sds` - Builds nim-sds library and import library (Windows only)
25+
- `$(NIMSDS_LIBFILE)` - Dependency that triggers the build
26+
27+
**How it works:**
28+
```makefile
29+
$(NIMSDS_LIBFILE): | deps
30+
# Builds libsds.dll
31+
$(MAKE) -C $(NIM_SDS_SOURCE_DIR) libsds
32+
33+
# Creates import library
34+
dlltool --dllname libsds.dll --def libsds.def --output-lib libsds.dll.a
35+
```
36+
37+
### 2. StatusQ Import Library Generation
38+
39+
**Location:** Lines ~376-397 in Makefile
40+
41+
**What it does:**
42+
- After StatusQ is installed, automatically creates `libStatusQ.dll.a` import library
43+
- Creates a `.def` file with the exported symbols (`statusq_registerQmlTypes`, `statusq_getMobileUIScaleFactor`)
44+
- Uses `dlltool` to generate the MinGW-compatible import library
45+
46+
**Key targets:**
47+
- `statusq-import-lib` - Creates the import library
48+
- `statusq` - Now depends on `statusq-import-lib` on Windows
49+
50+
**Files created:**
51+
- `bin/StatusQ/StatusQ.def` - Module definition file
52+
- `bin/StatusQ/libStatusQ.dll.a` - Import library for MinGW
53+
54+
**How it works:**
55+
```makefile
56+
$(STATUSQ_DEF): $(STATUSQ_DLL)
57+
# Creates .def file with exports
58+
echo "EXPORTS" > StatusQ.def
59+
echo "statusq_registerQmlTypes" >> StatusQ.def
60+
echo "statusq_getMobileUIScaleFactor" >> StatusQ.def
61+
62+
$(STATUSQ_IMPORT_LIB): $(STATUSQ_DLL) $(STATUSQ_DEF)
63+
# Creates import library
64+
dlltool --dllname StatusQ.dll --def StatusQ.def --output-lib libStatusQ.dll.a
65+
```
66+
67+
### 3. DLL Copying for Runtime
68+
69+
**Location:** Lines ~680-690 in Makefile
70+
71+
**What it does:**
72+
- Copies all required DLLs to the `bin/` directory before building
73+
- Ensures the executable can find DLLs at runtime (Windows searches the executable's directory)
74+
75+
**Key targets:**
76+
- `copy-windows-dlls` - Copies all DLLs to bin/
77+
78+
**DLLs copied:**
79+
- `StatusQ.dll`
80+
- `DOtherSide.dll`
81+
- `libstatus.dll`
82+
- `libkeycard.dll`
83+
- `libsds.dll`
84+
85+
**How it works:**
86+
```makefile
87+
copy-windows-dlls: | statusq dotherside $(STATUSGO) $(STATUSKEYCARDGO) $(NIMSDS_LIBFILE)
88+
cp $(STATUSQ_INSTALL_PATH)/StatusQ/StatusQ.dll $(STATUSQ_INSTALL_PATH)/
89+
cp $(DOTHERSIDE_LIBFILE) $(STATUSQ_INSTALL_PATH)/
90+
# ... copies other DLLs
91+
```
92+
93+
### 4. Updated Dependencies
94+
95+
**Location:** Line ~692 in Makefile
96+
97+
**What changed:**
98+
- `nim_status_client` now depends on:
99+
- `nim-sds` (Windows only) - Ensures nim-sds is built
100+
- `copy-windows-dlls` (Windows only) - Ensures DLLs are in place
101+
102+
**Before:**
103+
```makefile
104+
$(NIM_STATUS_CLIENT): ... | statusq dotherside ...
105+
```
106+
107+
**After:**
108+
```makefile
109+
$(NIM_STATUS_CLIENT): ... | statusq dotherside ... $(if $(filter win32,$(mkspecs)),nim-sds copy-windows-dlls)
110+
```
111+
112+
## Requirements
113+
114+
### Tools Required
115+
116+
1. **dlltool** - Part of MinGW toolchain
117+
- Location: Usually in `C:\ProgramData\scoop\apps\gcc\current\bin\dlltool.exe`
118+
- Used to create import libraries from DLLs
119+
120+
2. **nim-sds source** - Must be cloned
121+
- Default location: `../nim-sds` (relative to status-app)
122+
- Can be overridden with `NIM_SDS_SOURCE_DIR` environment variable
123+
124+
## Usage
125+
126+
### Normal Build
127+
128+
Just run the normal build command:
129+
```bash
130+
make nim_status_client
131+
```
132+
133+
The build process will automatically:
134+
1. Build nim-sds if needed
135+
2. Build StatusQ and create import library
136+
3. Copy DLLs to bin directory
137+
4. Build the executable
138+
139+
### Manual Steps (if needed)
140+
141+
If you need to rebuild just the import libraries:
142+
143+
```bash
144+
# Rebuild StatusQ import library
145+
make statusq-import-lib
146+
147+
# Rebuild nim-sds import library
148+
make nim-sds
149+
150+
# Copy DLLs manually
151+
make copy-windows-dlls
152+
```
153+
154+
## Troubleshooting
155+
156+
### Error: "dlltool not found"
157+
- Ensure MinGW is installed and in PATH
158+
- Or set the full path to dlltool in the Makefile
159+
160+
### Error: "nim-sds directory not found"
161+
- Clone nim-sds: `git clone https://github.com/waku-org/nim-sds.git ../nim-sds`
162+
- Or set `NIM_SDS_SOURCE_DIR` environment variable
163+
164+
### Import library creation fails silently
165+
- Check that `dlltool` is available: `which dlltool` (Git Bash) or `where dlltool` (PowerShell)
166+
- Verify the DLL exists before creating import library
167+
- Check the `.def` file was created correctly
168+
169+
## Technical Details
170+
171+
### Why Import Libraries Are Needed
172+
173+
On Windows with MinGW:
174+
- MSVC creates `.lib` files (not compatible with MinGW linker)
175+
- MinGW linker needs `.dll.a` import libraries
176+
- These contain stub functions that redirect to the DLL at runtime
177+
178+
### Symbol Export
179+
180+
The `statusq_registerQmlTypes` function is exported from StatusQ.dll using:
181+
- `Q_DECL_EXPORT` macro in C++
182+
- `extern "C"` linkage for C compatibility
183+
- Listed in the `.def` file for import library generation
184+
185+
## Future Improvements
186+
187+
1. **Auto-detect exports** - Use `objdump` or `pexports` to automatically extract symbols
188+
2. **Better error handling** - Fail build if import library creation fails
189+
3. **Cleanup targets** - Add targets to remove generated import libraries
190+
4. **Cross-platform** - Ensure these changes don't affect Linux/macOS builds
191+

0 commit comments

Comments
 (0)