diff --git a/Core/Sources/ConverterServer/ConverterServer+Snapshot.swift b/Core/Sources/ConverterServer/ConverterServer+Snapshot.swift index 979edc0ec..cc3d48b6f 100644 --- a/Core/Sources/ConverterServer/ConverterServer+Snapshot.swift +++ b/Core/Sources/ConverterServer/ConverterServer+Snapshot.swift @@ -113,7 +113,9 @@ extension ConverterServer { if let executableURL = Bundle.main.executableURL { var directoryURL = executableURL.deletingLastPathComponent() while directoryURL.path != "/" { - if directoryURL.lastPathComponent == "Contents" { + // 入力モデルはIME本体のResourcesから読み込む。 + if directoryURL.lastPathComponent == "Contents", + directoryURL.deletingLastPathComponent().lastPathComponent != "ConverterServer.app" { return directoryURL.appendingPathComponent("Resources", isDirectory: true) } directoryURL.deleteLastPathComponent() diff --git a/Core/Sources/Core/Configs/AppGroup.swift b/Core/Sources/Core/Configs/AppGroup.swift index 71fef2541..6debda0af 100644 --- a/Core/Sources/Core/Configs/AppGroup.swift +++ b/Core/Sources/Core/Configs/AppGroup.swift @@ -11,9 +11,9 @@ public enum AppGroup { /// App Group entitlementを持たない同一ユーザーのHelperから共有コンテナを参照するためのURL。 /// - /// ConverterServerはsandboxed appではなくLaunchAgentなので、FileManagerのApp Group APIは - /// `nil`を返す。その場合もクライアントと同じデータを使えるよう、macOSで定義された - /// ユーザー単位のGroup Containers配下を明示的に解決する。 + /// ConverterServerはsandbox化せずLaunchAgentとして実行する。 + /// FileManagerのApp Group APIが`nil`を返す場合もクライアントと同じデータを使えるよう、 + /// macOSで定義されたユーザー単位のGroup Containers配下を明示的に解決する。 public static func containerURL(homeDirectoryURL: URL) -> URL { homeDirectoryURL .appendingPathComponent("Library", isDirectory: true) diff --git a/README.md b/README.md index e710c7a73..26c39663a 100644 --- a/README.md +++ b/README.md @@ -99,9 +99,11 @@ ls -lh azooKeyMac/Resources/zenz-v3.1-small-gguf/ggml-model-Q5_K_M.gguf `install.sh` はアーカイブビルドを行うため、Xcode上で署名設定が通っている必要があります。Apple Developer Programに加入していない場合は、Personal Teamでの署名に切り替えてください。 * `azooKeyMac.xcodeproj` を Xcode で開く -* azooKeyMac ターゲット → Signing & Capabilities で Team を自身の Personal Team に変更 +* azooKeyMac と ConverterServer ターゲット → Signing & Capabilities で Team を自身の Personal Team に変更 * リポジトリ内のバンドルID(`dev.ensan.inputmethod.azooKeyMac` など)を、自身の所有するプレフィックスに一括置換(例: `dev.yourname.inputmethod.azooKeyMac`) +IME本体とConverterServerは、同じApp Groupの既存データを使用します。両ターゲットでApp Groupを認証するプロファイルが必要です。自動署名では`REGISTER_APP_GROUPS`を有効にしています。CLIでプロファイルを取得・更新するときは、`xcodebuild`に`-allowProvisioningUpdates`を指定してください。[Appleの説明](https://developer.apple.com/documentation/xcode/accessing-app-group-containers) + #### 3. ビルド&インストール ```bash diff --git a/Tools/ConverterServer.xcconfig b/Tools/ConverterServer.xcconfig new file mode 100644 index 000000000..8f7e93830 --- /dev/null +++ b/Tools/ConverterServer.xcconfig @@ -0,0 +1,16 @@ +CODE_SIGN_ENTITLEMENTS = azooKeyMac/ConverterServer.entitlements +CODE_SIGN_STYLE = Automatic +CURRENT_PROJECT_VERSION = 1 +DEVELOPMENT_TEAM = 9S3UXHYP65 +ENABLE_HARDENED_RUNTIME = YES +GENERATE_INFOPLIST_FILE = YES +INFOPLIST_KEY_LSBackgroundOnly = YES +LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks +MACOSX_DEPLOYMENT_TARGET = 13.0 +MARKETING_VERSION = 1.0 +PRODUCT_BUNDLE_IDENTIFIER = dev.ensan.inputmethod.azooKeyMac.ConverterServer +PRODUCT_NAME = $(TARGET_NAME) +REGISTER_APP_GROUPS = YES +SKIP_INSTALL = YES +SWIFT_OBJC_INTEROP_MODE = objcxx +SWIFT_VERSION = 6.0 diff --git a/Tools/ConverterServerResourceBundleInfo.plist b/Tools/ConverterServerResourceBundleInfo.plist deleted file mode 100644 index 49c9d7207..000000000 --- a/Tools/ConverterServerResourceBundleInfo.plist +++ /dev/null @@ -1,16 +0,0 @@ - - - - - CFBundleIdentifier - dev.ensan.inputmethod.azooKeyMac.ConverterServer.Resource - CFBundleName - ConverterServerResource - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - - diff --git a/Tools/embed_converter_server.sh b/Tools/embed_converter_server.sh index afff99bd5..518a227f8 100755 --- a/Tools/embed_converter_server.sh +++ b/Tools/embed_converter_server.sh @@ -1,62 +1,7 @@ #!/bin/sh set -eu -swift_configuration=debug -if [ "${CONFIGURATION}" = "Release" ]; then - swift_configuration=release -fi - -swift build --package-path "${SRCROOT}/Core" --product ConverterServer -c "${swift_configuration}" - -server_source="${SRCROOT}/Core/.build/${swift_configuration}/ConverterServer" -server_directory="${TARGET_BUILD_DIR}/${CONTENTS_FOLDER_PATH}/Helpers/ConverterServer" -server_destination="${server_directory}/ConverterServer" -server_build_directory="${SRCROOT}/Core/.build/${swift_configuration}" -mkdir -p "${server_directory}" -cp "${server_source}" "${server_destination}" - -# SwiftPM の Bundle.module は、実行時に Bundle.main.bundleURL 直下を最初に探し、 -# 見つからない場合はビルド時の絶対パスへフォールバックする。Helperを独立した -# Contents/Helpers配下のdirectoryに置くと、そのdirectoryがBundle.mainになるため、 -# resource bundleも同じ場所に置ける。app bundle root直下はcodesignで許可されない。 -for resource_bundle in "${server_build_directory}"/*.bundle; do - if [ -d "${resource_bundle}" ]; then - resource_bundle_name="$(basename "${resource_bundle}")" - embedded_resource_bundle="${server_directory}/${resource_bundle_name}" - ditto "${resource_bundle}" "${embedded_resource_bundle}" - # command-line SwiftPM buildが生成するbundleはInfo.plistを持たないため、 - # archiveのcodesignが正規のresource bundleとして検証できるよう補う。 - cp "${SRCROOT}/Tools/ConverterServerResourceBundleInfo.plist" "${embedded_resource_bundle}/Info.plist" - fi -done - -if ! otool -l "${server_destination}" | grep -q "@executable_path/../../Frameworks"; then - install_name_tool -add_rpath "@executable_path/../../Frameworks" "${server_destination}" -fi - -if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" ] && [ "${EXPANDED_CODE_SIGN_IDENTITY}" != "-" ]; then - server_identifier="${PRODUCT_BUNDLE_IDENTIFIER}.ConverterServer" - # ConverterServerも学習データや個人化モデルをApp Groupから読む。entitlementなしで - # Group Containersを直接参照すると、macOSが「ほかのアプリのデータ」と判定して - # ファイルごとのアクセス確認を表示するため、埋め込みHelperにも同じGroupを付与する。 - codesign \ - --force \ - --sign "${EXPANDED_CODE_SIGN_IDENTITY}" \ - --identifier "${server_identifier}" \ - --options runtime \ - --entitlements "${SRCROOT}/azooKeyMac/ConverterServer.entitlements" \ - --timestamp=none \ - "${server_destination}" - codesign --verify --strict "${server_destination}" - - for resource_bundle in "${server_directory}"/*.bundle; do - if [ -d "${resource_bundle}" ]; then - codesign \ - --force \ - --sign "${EXPANDED_CODE_SIGN_IDENTITY}" \ - --timestamp=none \ - "${resource_bundle}" - codesign --verify --strict "${resource_bundle}" - fi - done -fi +server_source="${BUILT_PRODUCTS_DIR}/ConverterServer.app" +server_destination="${TARGET_BUILD_DIR}/${CONTENTS_FOLDER_PATH}/Helpers/ConverterServer.app" +mkdir -p "$(dirname "${server_destination}")" +ditto "${server_source}" "${server_destination}" diff --git a/Tools/install_converter_server_launch_agent.sh b/Tools/install_converter_server_launch_agent.sh index 40285eca0..cc033e007 100755 --- a/Tools/install_converter_server_launch_agent.sh +++ b/Tools/install_converter_server_launch_agent.sh @@ -4,7 +4,7 @@ set -eu service_name="dev.ensan.inputmethod.azooKeyMac.ConverterServer" default_app_path="${BUILT_PRODUCTS_DIR:-/tmp/azooKeyDesktopDerivedData/Build/Products/Debug}/azooKeyMac.app" app_path="${1:-${default_app_path}}" -server_path="${app_path}/Contents/Helpers/ConverterServer/ConverterServer" +server_path="${app_path}/Contents/Helpers/ConverterServer.app/Contents/MacOS/ConverterServer" agent_dir="${HOME}/Library/LaunchAgents" agent_path="${agent_dir}/${service_name}.plist" gui_domain="gui/$(id -u)" diff --git a/azooKeyMac.xcodeproj/project.pbxproj b/azooKeyMac.xcodeproj/project.pbxproj index 3c415cf1e..4ad39da73 100644 --- a/azooKeyMac.xcodeproj/project.pbxproj +++ b/azooKeyMac.xcodeproj/project.pbxproj @@ -20,6 +20,7 @@ 556C52FC2BAAAF7E00EB343F /* en@2x.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 556C52FA2BAAAF7D00EB343F /* en@2x.tiff */; }; 55A27D022BAAADDB00512DCD /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 55A27D002BAAADDB00512DCD /* InfoPlist.strings */; }; 55A9C54B2BA847A1007F6F02 /* main@2x.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 55A9C54A2BA847A1007F6F02 /* main@2x.tiff */; }; + F10000000000000000000001 /* Core in Frameworks */ = {isa = PBXBuildFile; productRef = F10000000000000000000002 /* Core */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -58,6 +59,8 @@ 55A27D012BAAADDB00512DCD /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 55A9C54A2BA847A1007F6F02 /* main@2x.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = "main@2x.tiff"; sourceTree = ""; }; 55D3B7632DB36BDE00044FD1 /* Core */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Core; sourceTree = ""; }; + F10000000000000000000003 /* ConverterServer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ConverterServer.app; sourceTree = BUILT_PRODUCTS_DIR; }; + F10000000000000000000004 /* ConverterServer.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Tools/ConverterServer.xcconfig; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFileSystemSynchronizedRootGroup section */ @@ -67,6 +70,7 @@ 55CE06ED2CB01F160002DAF1 /* azooKeyMacTests */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = azooKeyMacTests; sourceTree = ""; }; 55CE06F12CB01F160002DAF1 /* azooKeyMacUITests */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = azooKeyMacUITests; sourceTree = ""; }; 55CE06F52CB01F180002DAF1 /* Preview Content */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = "Preview Content"; sourceTree = ""; }; + F10000000000000000000005 /* ConverterServer */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = Core/Sources/ConverterServer; sourceTree = SOURCE_ROOT; }; /* End PBXFileSystemSynchronizedRootGroup section */ /* Begin PBXFrameworksBuildPhase section */ @@ -92,6 +96,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + F10000000000000000000006 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F10000000000000000000001 /* Core in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -99,6 +111,8 @@ isa = PBXGroup; children = ( 55D3B7632DB36BDE00044FD1 /* Core */, + F10000000000000000000005 /* ConverterServer */, + F10000000000000000000004 /* ConverterServer.xcconfig */, 1A41E61626E745D9009B65D7 /* azooKeyMac */, 55CE06ED2CB01F160002DAF1 /* azooKeyMacTests */, 55CE06F12CB01F160002DAF1 /* azooKeyMacUITests */, @@ -110,6 +124,7 @@ isa = PBXGroup; children = ( 1A41E61426E745D9009B65D7 /* azooKeyMac.app */, + F10000000000000000000003 /* ConverterServer.app */, 1A41E62426E745DD009B65D7 /* azooKeyMacTests.xctest */, 1A41E62E26E745DD009B65D7 /* azooKeyMacUITests.xctest */, ); @@ -165,6 +180,7 @@ ); dependencies = ( 554A26622DB3765F003C5CFB /* PBXTargetDependency */, + F10000000000000000000009 /* PBXTargetDependency */, ); fileSystemSynchronizedGroups = ( 55CE06C72CB01F000002DAF1 /* InputController */, @@ -222,6 +238,23 @@ productReference = 1A41E62E26E745DD009B65D7 /* azooKeyMacUITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; }; + F1000000000000000000000A /* ConverterServer */ = { + isa = PBXNativeTarget; + buildConfigurationList = F1000000000000000000000B /* Build configuration list for PBXNativeTarget "ConverterServer" */; + buildPhases = ( + F10000000000000000000007 /* Sources */, + F10000000000000000000006 /* Frameworks */, + F10000000000000000000008 /* Resources */, + ); + buildRules = (); + dependencies = (); + fileSystemSynchronizedGroups = (F10000000000000000000005 /* ConverterServer */,); + name = ConverterServer; + packageProductDependencies = (F10000000000000000000002 /* Core */,); + productName = ConverterServer; + productReference = F10000000000000000000003 /* ConverterServer.app */; + productType = "com.apple.product-type.application"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -261,6 +294,7 @@ projectDirPath = ""; projectRoot = ""; targets = ( + F1000000000000000000000A /* ConverterServer */, 1A41E61326E745D9009B65D7 /* azooKeyMac */, 1A41E62326E745DD009B65D7 /* azooKeyMacTests */, 1A41E62D26E745DD009B65D7 /* azooKeyMacUITests */, @@ -301,6 +335,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + F10000000000000000000008 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -318,7 +359,7 @@ outputFileListPaths = ( ); outputPaths = ( - "$(TARGET_BUILD_DIR)/$(CONTENTS_FOLDER_PATH)/Helpers/ConverterServer/ConverterServer", + "$(TARGET_BUILD_DIR)/$(CONTENTS_FOLDER_PATH)/Helpers/ConverterServer.app/Contents/MacOS/ConverterServer", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -349,6 +390,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + F10000000000000000000007 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -366,6 +414,7 @@ isa = PBXTargetDependency; productRef = 554A26612DB3765F003C5CFB /* Core */; }; + F10000000000000000000009 /* PBXTargetDependency */ = {isa = PBXTargetDependency; target = F1000000000000000000000A /* ConverterServer */; }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -529,6 +578,7 @@ MACOSX_DEPLOYMENT_TARGET = 13.0; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = dev.ensan.inputmethod.azooKeyMac; + REGISTER_APP_GROUPS = YES; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_INTEROP_MODE = objcxx; @@ -565,6 +615,7 @@ MACOSX_DEPLOYMENT_TARGET = 13.0; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = dev.ensan.inputmethod.azooKeyMac; + REGISTER_APP_GROUPS = YES; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_INTEROP_MODE = objcxx; @@ -672,6 +723,18 @@ }; name = Release; }; + F1000000000000000000000C /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F10000000000000000000004 /* ConverterServer.xcconfig */; + buildSettings = {}; + name = Debug; + }; + F1000000000000000000000D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F10000000000000000000004 /* ConverterServer.xcconfig */; + buildSettings = {}; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -711,6 +774,12 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + F1000000000000000000000B /* Build configuration list for PBXNativeTarget "ConverterServer" */ = { + isa = XCConfigurationList; + buildConfigurations = (F1000000000000000000000C /* Debug */, F1000000000000000000000D /* Release */,); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ /* Begin XCLocalSwiftPackageReference section */ @@ -730,6 +799,7 @@ package = 554A265E2DB37657003C5CFB /* XCLocalSwiftPackageReference "Core" */; productName = Core; }; + F10000000000000000000002 /* Core */ = {isa = XCSwiftPackageProductDependency; productName = Core; }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 1A41E60C26E745D9009B65D7 /* Project object */; diff --git a/pkg-scripts/postinstall b/pkg-scripts/postinstall index 56d3b6e8e..92f90f22d 100755 --- a/pkg-scripts/postinstall +++ b/pkg-scripts/postinstall @@ -3,7 +3,7 @@ set -eu service_name="dev.ensan.inputmethod.azooKeyMac.ConverterServer" app_path="/Library/Input Methods/azooKeyMac.app" -server_path="${app_path}/Contents/MacOS/ConverterServer" +server_path="${app_path}/Contents/Helpers/ConverterServer.app/Contents/MacOS/ConverterServer" agent_dir="/Library/LaunchAgents" agent_path="${agent_dir}/${service_name}.plist" script_dir="$(cd "$(dirname "$0")" && pwd)"