diff --git a/Makefile b/Makefile index a10211f17a..559feb0fa4 100644 --- a/Makefile +++ b/Makefile @@ -18,9 +18,13 @@ BUILD_SYSTEM_DIR := vendor/nimbus-build-system bottles \ bottles-dummy \ bottles-macos \ + check-pkg-target-linux \ + check-pkg-target-macos \ + check-pkg-target-windows \ clean \ deps \ nim_status_client \ + nim_windows_launcher \ pkg \ pkg-linux \ pkg-macos \ @@ -70,13 +74,31 @@ ifeq ($(detected_OS),Darwin) else ifeq ($(detected_OS),Windows) BOTTLES_TARGET := bottles-dummy PKG_TARGET := pkg-windows + QRCODEGEN_MAKE_PARAMS := CC=gcc RUN_TARGET := run-windows + VCINSTALLDIR ?= C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\VC\\ + export VCINSTALLDIR else BOTTLES_TARGET := bottles-dummy PKG_TARGET := pkg-linux RUN_TARGET := run-linux-or-macos endif +check-pkg-target-linux: +ifneq ($(detected_OS),Linux) + $(error The pkg-linux target must be run on Linux) +endif + +check-pkg-target-macos: +ifneq ($(detected_OS),Darwin) + $(error The pkg-macos target must be run on macOS) +endif + +check-pkg-target-windows: +ifneq ($(detected_OS),Windows) + $(error The pkg-windows target must be run on Windows) +endif + bottles: $(BOTTLES_TARGET) bottles-dummy: ; @@ -142,7 +164,6 @@ else DOTHERSIDE_BUILD_CMD := cmake --build . --config Release $(HANDLE_OUTPUT) NIM_PARAMS += -L:$(DOTHERSIDE) NIM_EXTRA_PARAMS := --passL:"-lsetupapi -lhid" - QRCODEGEN_MAKE_PARAMS := CC=gcc endif # TODO: control debug/release builds with a Make var @@ -206,6 +227,7 @@ STATUS_CLIENT_APPIMAGE ?= pkg/NimStatusClient-x86_64.AppImage $(STATUS_CLIENT_APPIMAGE): nim_status_client $(APPIMAGE_TOOL) nim-status.desktop rm -rf pkg/*.AppImage + rm -rf tmp/linux/dist mkdir -p tmp/linux/dist/usr/bin mkdir -p tmp/linux/dist/usr/lib mkdir -p tmp/linux/dist/usr/qml @@ -285,18 +307,69 @@ ifdef MACOS_CODESIGN_IDENT scripts/sign-macos-pkg.sh $(STATUS_CLIENT_DMG) $(MACOS_CODESIGN_IDENT) endif -STATUS_CLIENT_EXE ?= pkg/Status.exe +NIM_WINDOWS_PREBUILT_DLLS ?= tmp/windows/tools/pcre.dll -# not implemented yet -# $(STATUS_CLIENT_EXE): nim_status_client +$(NIM_WINDOWS_PREBUILT_DLLS): + echo -e "\e[92mFetching:\e[39m prebuilt DLLs from nim-lang.org" + rm -rf tmp/windows + mkdir -p tmp/windows/tools + cd tmp/windows/tools && \ + wget https://nim-lang.org/download/dlls.zip && \ + unzip dlls.zip + +nim_windows_launcher: | deps + $(ENV_SCRIPT) nim c -d:debug --outdir:./bin --passL:"-static-libgcc -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive" src/nim_windows_launcher.nim + +STATUS_CLIENT_ZIP ?= pkg/Status.zip + +$(STATUS_CLIENT_ZIP): nim_status_client nim_windows_launcher $(NIM_WINDOWS_PREBUILT_DLLS) + rm -rf pkg/*.zip + rm -rf tmp/windows/dist + mkdir -p tmp/windows/dist/Status/bin + mkdir -p tmp/windows/dist/Status/resources + mkdir -p tmp/windows/dist/Status/vendor + cp windows-install.txt tmp/windows/dist/Status/INSTALL.txt + unix2dos -k tmp/windows/dist/Status/INSTALL.txt + # cp LICENSE tmp/windows/dist/Status/LICENSE.txt + # unix2dos -k tmp/windows/dist/Status/LICENSE.txt + cp status.ico tmp/windows/dist/Status/resources/ + cp status.svg tmp/windows/dist/Status/resources/ + cp resources.rcc tmp/windows/dist/Status/resources/ + cp bin/nim_status_client.exe tmp/windows/dist/Status/bin/Status.exe + mv bin/nim_windows_launcher.exe tmp/windows/dist/Status/Status.exe + rcedit \ + tmp/windows/dist/Status/bin/Status.exe \ + --set-icon tmp/windows/dist/Status/resources/status.ico + rcedit \ + tmp/windows/dist/Status/Status.exe \ + --set-icon tmp/windows/dist/Status/resources/status.ico + cp $(DOTHERSIDE) tmp/windows/dist/Status/bin/ + cp tmp/windows/tools/*.dll tmp/windows/dist/Status/bin/ + cp "$(shell which libgcc_s_seh-1.dll)" tmp/windows/dist/Status/bin/ + cp "$(shell which libwinpthread-1.dll)" tmp/windows/dist/Status/bin/ + + echo -e $(BUILD_MSG) "deployable folder" + windeployqt \ + --compiler-runtime \ + --qmldir ui \ + --release \ + tmp/windows/dist/Status/bin/DOtherSide.dll + mv tmp/windows/dist/Status/bin/vc_redist.x64.exe tmp/windows/dist/Status/vendor/ + # implement code signing of applicable files in deployable folder + + echo -e $(BUILD_MSG) "zip" + mkdir -p pkg + cd tmp/windows/dist/Status && \ + 7z a ../../../../pkg/Status.zip * + # can the final .zip file be code signed as well? pkg: $(PKG_TARGET) -pkg-linux: $(STATUS_CLIENT_APPIMAGE) +pkg-linux: check-pkg-target-linux $(STATUS_CLIENT_APPIMAGE) -pkg-macos: $(STATUS_CLIENT_DMG) +pkg-macos: check-pkg-target-macos $(STATUS_CLIENT_DMG) -pkg-windows: $(STATUS_CLIENT_EXE) +pkg-windows: check-pkg-target-windows $(STATUS_CLIENT_ZIP) clean: | clean-common rm -rf bin/* node_modules pkg/* tmp/* $(STATUSGO) @@ -312,10 +385,10 @@ run-linux-or-macos: LD_LIBRARY_PATH="$(QT5_LIBDIR)" \ ./bin/nim_status_client -run-windows: +run-windows: $(NIM_WINDOWS_PREBUILT_DLLS) echo -e "\e[92mRunning:\e[39m bin/nim_status_client.exe" NIM_STATUS_CLIENT_DEV="$(NIM_STATUS_CLIENT_DEV)" \ - PATH="$(shell pwd)"/"$(shell dirname "$(DOTHERSIDE)")":"$(PATH)" \ + PATH="$(shell pwd)"/"$(shell dirname "$(DOTHERSIDE)")":"$(shell pwd)"/"$(shell dirname "$(NIM_WINDOWS_PREBUILT_DLLS)")":"$(PATH)" \ ./bin/nim_status_client.exe endif # "variables.mk" was not included diff --git a/config.nims b/config.nims index 9621d8f7a3..250e48e43f 100644 --- a/config.nims +++ b/config.nims @@ -23,6 +23,7 @@ if defined(macosx): # set the minimum supported macOS version to 10.13 switch("passC", "-mmacosx-version-min=10.13") elif defined(windows): + --app:gui --tlsEmulation:off switch("passL", "-Wl,-as-needed") else: diff --git a/src/nim_status_client.nim b/src/nim_status_client.nim index 6024d4fca0..4b50954023 100644 --- a/src/nim_status_client.nim +++ b/src/nim_status_client.nim @@ -25,9 +25,19 @@ proc mainProc() = initializeOpenGL() let app = newQApplication("Nim Status Client") - QResource.registerResource(app.applicationDirPath & "/../resources.rcc") + let resources = + if defined(windows) and getEnv("NIM_STATUS_CLIENT_DEV").string == "": + "/../resources/resources.rcc" + else: + "/../resources.rcc" + QResource.registerResource(app.applicationDirPath & resources) - app.icon(app.applicationDirPath & "/../status.svg") + let statusSvg = + if defined(windows) and getEnv("NIM_STATUS_CLIENT_DEV").string == "": + "/../resources/status.svg" + else: + "/../status.svg" + app.icon(app.applicationDirPath & statusSvg) let engine = newQQmlApplicationEngine() let signalController = signals.newController(app) @@ -54,7 +64,7 @@ proc mainProc() = profile.init(args.account) wallet.init() chat.init() - + var login = login.newController(status) var onboarding = onboarding.newController(status) @@ -84,7 +94,7 @@ proc mainProc() = node.init() login.init() onboarding.init() - + initControllers() # Handle node.stopped signal when user has logged out @@ -100,7 +110,7 @@ proc mainProc() = # node.reset() # wallet.reset() # profile.reset() - + # 2. Re-init controllers that don't require a running node initControllers() diff --git a/src/nim_windows_launcher.nim b/src/nim_windows_launcher.nim new file mode 100644 index 0000000000..f17642c08f --- /dev/null +++ b/src/nim_windows_launcher.nim @@ -0,0 +1,17 @@ +from os import getCurrentDir, joinPath +from winlean import Handle, shellExecuteW + +const NULL: Handle = 0 +let cwd = getCurrentDir() +let workDir_str = joinPath(cwd, "bin") +let exePath_str = joinPath(workDir_str, "Status.exe") +let open_str = "open" +let params_str = "" +let workDir = newWideCString(workDir_str) +let exePath = newWideCString(exePath_str) +let open = newWideCString(open_str) +let params = newWideCString(params_str) +# SW_SHOW (5): activates window and displays it in its current size and position +const showCmd: int32 = 5 + +discard shellExecuteW(NULL, open, exePath, params, workDir, showCmd) diff --git a/windows-install.txt b/windows-install.txt new file mode 100644 index 0000000000..719dd22708 --- /dev/null +++ b/windows-install.txt @@ -0,0 +1,42 @@ +REQUIREMENTS +============ + +This application requires 64-bit Windows 7 or newer. + +INSTALLING +========== + +After unzipping Status.zip, the Status folder can be placed wherever you prefer +(and have permissions) on your computer. + +RUNNING +======= + +Double-click Status.exe in the Status folder to launch the application. + +If you see an error complaining about a DLL file, you should open +vc_redist.x64.exe in the Status\vendor folder to install the Microsoft Visual +C++ Redistributable. This is usually necessary only on versions of Windows +older than Windows 10. Then retry launching the application. + +You may wish to right-click Status.exe and "Send to > Desktop (create shortcut)". +The application can then be launched by double-clicking the shortcut on your +desktop. + +Status.exe persists settings and encrypted data in your %LOCALAPPDATA%\Status +folder. + +UPGRADING +========= + +To upgrade this application download the latest Status.zip, delete this Status +folder and the older Status.zip, unzip the newer one, and then place the new +Status folder in your preferred location. + +If you place the new Status folder in a different location than the old one +then you should recreate any shortcuts you created for Status.exe. + +UNINSTALLING +============ + +Delete this Status folder and delete your %LOCALAPPDATA%\Status folder.