#!/bin/bash # build_login_helper.sh — Xcode 构建阶段:编译 + 打包 + 签名 PangolinLoginHelper, # 嵌入主 app 的 Contents/Library/LoginItems/(供 SMAppService.loginItem 注册)。 # 学 Tailscale 的 LoginItemHelper-macsys。须在主 app 最终签名前运行(即作为 Runner 的构建阶段)。 set -euo pipefail HELPER_NAME="PangolinLoginHelper" HELPER_ID="com.pangolin.pangolin.LoginHelper" SRC="${SRCROOT}/login_helper/main.swift" DEST="${BUILT_PRODUCTS_DIR}/${CONTENTS_FOLDER_PATH}/Library/LoginItems/${HELPER_NAME}.app" WORK="${DERIVED_FILE_DIR}/login_helper" SDK="$(xcrun --sdk macosx --show-sdk-path)" rm -rf "${DEST}" mkdir -p "${WORK}" "${DEST}/Contents/MacOS" # 按 ARCHS 逐架构编译,多架构则 lipo 成 universal。 BIN="${DEST}/Contents/MacOS/${HELPER_NAME}" SLICES=() for arch in ${ARCHS}; do out="${WORK}/${HELPER_NAME}-${arch}" swiftc -O -sdk "${SDK}" -target "${arch}-apple-macos13.0" "${SRC}" -o "${out}" SLICES+=("${out}") done if [ "${#SLICES[@]}" -gt 1 ]; then lipo -create "${SLICES[@]}" -output "${BIN}" else cp "${SLICES[0]}" "${BIN}" fi # Info.plist:LSBackgroundOnly(无界面/无 Dock)+ helper bundle ID。 cat > "${DEST}/Contents/Info.plist" < CFBundleExecutable${HELPER_NAME} CFBundleIdentifier${HELPER_ID} CFBundleName${HELPER_NAME} CFBundlePackageTypeAPPL CFBundleShortVersionString1.0 CFBundleVersion1 LSBackgroundOnly LSMinimumSystemVersion13.0 PLIST # 与主 app 同身份签名(hardened runtime);时间戳跟随构建环境(可达即打,否则由外层流程决定)。 codesign --force --options runtime --timestamp -s "${EXPANDED_CODE_SIGN_IDENTITY}" "${DEST}" echo "embedded + signed login helper → ${DEST}"