diff --git a/Makefile b/Makefile index 91091cfd2b..5472c9b2a4 100644 --- a/Makefile +++ b/Makefile @@ -557,6 +557,9 @@ export STATUSKEYCARD_QT_LIB := $(STATUSKEYCARD_QT_LIBDIR)/$(STATUSKEYCARD_QT_LIB STATUSKEYCARD_QT_DYLIB_NAME := $(notdir $(STATUSKEYCARD_QT_LIB)) STATUSKEYCARD_QT_LINKNAME := $(patsubst lib%,%,$(basename $(STATUSKEYCARD_QT_DYLIB_NAME))) +KEYCARD_SIM_SRC_DIR := $(STATUS_KEYCARD_QT_SOURCE_DIR)/test/keycard-simulator +KEYCARD_SIM_RUNTIME_BITS := run.sh libs versions out + status-keycard-qt: $(STATUSKEYCARD_QT_LIB) $(STATUSKEYCARD_QT_LIB): | deps check-qt-dir echo -e $(BUILD_MSG) "status-keycard-qt" @@ -893,6 +896,15 @@ $(STATUS_CLIENT_DMG): nim_status_client cp status-macos.svg $(MACOS_OUTER_BUNDLE)/Contents/ cp -R resources.rcc $(MACOS_OUTER_BUNDLE)/Contents/ +# Precompile (JDK from nix) + bundle the keycard simulator into the app, before macdeployqt/signing +ifeq ($(USE_SIMULATED_KEYCARD),true) + echo -e $(BUILD_MSG) "keycard-simulator (precompile + bundle)" + nix shell .#jdk -c bash -c 'cd $(KEYCARD_SIM_SRC_DIR) && ./build.sh' + mkdir -p $(MACOS_OUTER_BUNDLE)/Contents/Resources/keycard-simulator + cp -R $(addprefix $(KEYCARD_SIM_SRC_DIR)/,$(KEYCARD_SIM_RUNTIME_BITS)) \ + $(MACOS_OUTER_BUNDLE)/Contents/Resources/keycard-simulator/ +endif + echo -e $(BUILD_MSG) "app" MAC_QTQMLDIR=$(shell $(QMAKE) -query QT_INSTALL_QML) && \ macdeployqt \ diff --git a/flake.nix b/flake.nix index 0b8039254a..5f505ddfe5 100644 --- a/flake.nix +++ b/flake.nix @@ -21,6 +21,9 @@ hash = "sha256-Z2sXrNRIiZ9tSoOyGE4GV0gEROy2rJxJIoie+tnl2/s="; }; }); + + # JDK to precompile the keycard simulator when packaging a USE_SIMULATED_KEYCARD build + jdk = pkgs.jdk; } ); }; diff --git a/scripts/init_app_dir.sh b/scripts/init_app_dir.sh index 289a1924b9..844532f68e 100755 --- a/scripts/init_app_dir.sh +++ b/scripts/init_app_dir.sh @@ -25,6 +25,19 @@ copy_system_libs() { cp -P /usr/local/lib/x86_64-linux-gnu/libpcsclite*.so* "$dest/" } +bundle_keycard_simulator() { + local dest="$1" + local src="vendor/status-keycard-qt/test/keycard-simulator" + if ! command -v javac >/dev/null 2>&1; then + echo "WARNING: javac not found; skipping keycard simulator bundle." >&2 + return 0 + fi + echo "Bundling keycard simulator (precompile + copy)..." + ( cd "$src" && ./build.sh ) + mkdir -p "$dest" + cp -R "$src"/run.sh "$src"/libs "$src"/versions "$src"/out "$dest/" +} + DEST="${APP_DIR:?APP_DIR must be set}/usr" rm -rf "${APP_DIR}" @@ -48,6 +61,11 @@ cp status.png "${DEST}/" copy_native_libs "${DEST}/lib" cp "${FCITX5_QT}" "${DEST}/plugins/platforminputcontexts/" +if [[ "${USE_SIMULATED_KEYCARD:-}" == "true" ]]; then + # Bundled at usr/share/keycard-simulator; the app finds it at ../share relative to usr/bin. + bundle_keycard_simulator "${DEST}/share/keycard-simulator" +fi + # Qt WebEngine only (process + resources + locales) copy_qt_webengine() { local dest="$1" diff --git a/src/app_service/service/keycardV2/test_controller.nim b/src/app_service/service/keycardV2/test_controller.nim index 8b4dc815fb..9d8cadac8a 100644 --- a/src/app_service/service/keycardV2/test_controller.nim +++ b/src/app_service/service/keycardV2/test_controller.nim @@ -14,13 +14,28 @@ when defined(useSimulatedKeycard): const KEYCARD_SIMULATOR_DEFAULT_VERSION = "3.2" KEYCARD_SIMULATOR_DEFAULT_SIMULATOR_ADDRESS = "127.0.0.1:9025" - KEYCARD_SIMULATOR_DEFAULT_SIMULATOR_DIR = "vendor/status-keycard-qt/test/keycard-simulator" + # Subdirs (relative to the app executable) where packaging bundles the precompiled simulator: + # macOS Status.app/Contents/MacOS/nim_status_client -> ../Resources/keycard-simulator + # Linux AppDir/usr/bin/nim_status_client -> ../share/keycard-simulator + KEYCARD_SIMULATOR_BUNDLED_SUBDIRS = ["../Resources/keycard-simulator", "../share/keycard-simulator"] + KEYCARD_SIMULATOR_DEV_DIR = "vendor/status-keycard-qt/test/keycard-simulator" var ignoreKeycardLibSignals = false # used to avoid triggering of any keycard actions while setting up the test keycard proc shouldIgnoreKeycardLibSignals*(): bool = return ignoreKeycardLibSignals + proc resolveSimDir(): string = + let envDir = getEnv("STATUS_KEYCARD_SIM_DIR") + if envDir.len > 0: + return absolutePath(envDir) + let appDir = getAppDir() + for sub in KEYCARD_SIMULATOR_BUNDLED_SUBDIRS: + let candidate = normalizedPath(appDir / sub) + if dirExists(candidate): + return candidate + return absolutePath(KEYCARD_SIMULATOR_DEV_DIR) + type LoadCardArg = ref object of QObjectTaskArg params: JsonNode @@ -56,6 +71,21 @@ when defined(useSimulatedKeycard): self.QObject.delete proc startSimulator*(self: KeycardTestController, version: string) {.slot.} = + var safeVersion = "" + for c in version: + if c in {'0'..'9', '.'}: safeVersion.add(c) + if safeVersion.len == 0: + safeVersion = KEYCARD_SIMULATOR_DEFAULT_VERSION + let simDir = resolveSimDir() + if not dirExists(simDir): + error "keycard simulator directory not found; set STATUS_KEYCARD_SIM_DIR to " & + "'/vendor/status-keycard-qt/test/keycard-simulator'", dir = simDir + return + let port = getEnv("STATUS_KEYCARD_SIM_ENDPOINT", KEYCARD_SIMULATOR_DEFAULT_SIMULATOR_ADDRESS).rsplit(":", 1)[^1] + let launch = + if dirExists(simDir / "out"): "exec ./run.sh " & port & " " & safeVersion + else: "./build.sh && exec ./run.sh " & port & " " & safeVersion + if not self.simProcess.isNil and self.simProcess.running: self.simProcess.terminate() self.simProcess.close() @@ -64,16 +94,9 @@ when defined(useSimulatedKeycard): discard keycard_go.keycardTestRemoveCard() discard keycard_go.keycardTestUnplugReader() - var safeVersion = "" - for c in version: - if c in {'0'..'9', '.'}: safeVersion.add(c) - if safeVersion.len == 0: - safeVersion = KEYCARD_SIMULATOR_DEFAULT_VERSION - let simDir = getEnv("STATUS_KEYCARD_SIM_DIR", KEYCARD_SIMULATOR_DEFAULT_SIMULATOR_DIR) - let port = getEnv("STATUS_KEYCARD_SIM_ENDPOINT", KEYCARD_SIMULATOR_DEFAULT_SIMULATOR_ADDRESS).rsplit(":", 1)[^1] try: self.simProcess = startProcess("/bin/bash", - args = @["-c", "cd '" & simDir & "' && ./build.sh && exec ./run.sh " & port & " " & safeVersion], + args = @["-c", "cd '" & simDir & "' && " & launch], options = {poParentStreams}) info "starting keycard simulator", dir = simDir, port = port, version = safeVersion except CatchableError as e: diff --git a/vendor/status-keycard-qt b/vendor/status-keycard-qt index 95ba7ba6d0..81b16c5449 160000 --- a/vendor/status-keycard-qt +++ b/vendor/status-keycard-qt @@ -1 +1 @@ -Subproject commit 95ba7ba6d0a44fc25a41d031d7dbf9ef327894fd +Subproject commit 81b16c544984a652e32a95f0b24188d2f492aaf9