1616
1717# Load version info
1818source " $ROOT /version.env"
19+ source " $ROOT /Scripts/package_product_paths.sh"
1920
2021# Clean build only when explicitly requested (slower).
2122if [[ " ${CODEXBAR_FORCE_CLEAN:- 0} " == " 1" ]]; then
@@ -112,15 +113,6 @@ if [[ ! -f "$KEYBOARD_SHORTCUTS_UTIL" ]]; then
112113fi
113114patch_keyboard_shortcuts
114115
115- build_product_path () {
116- local name=" $1 "
117- local arch=" $2 "
118- case " $arch " in
119- arm64|x86_64) echo " .build/${arch} -apple-macosx/$CONF /$name " ;;
120- * ) echo " .build/$CONF /$name " ;;
121- esac
122- }
123-
124116# Resolve SwiftPM's current output path without relying on a fixed build-system layout.
125117# The output variable keeps the per-arch cache in this shell instead of losing it to
126118# command substitution.
@@ -130,7 +122,9 @@ swiftpm_bin_path() {
130122 local cache_var=" SWIFTPM_BIN_PATH_${arch// [^A-Za-z0-9]/ _} "
131123 if [[ -z " ${! cache_var+set} " ]]; then
132124 local resolved
133- resolved=$( swift build --show-bin-path -c " $CONF " --arch " $arch " 2> /dev/null || true)
125+ if ! resolved=$( codexbar_swiftpm_bin_path " $CONF " " $arch " ) ; then
126+ return 1
127+ fi
134128 printf -v " $cache_var " ' %s' " $resolved "
135129 fi
136130 printf -v " $output_var " ' %s' " ${! cache_var} "
@@ -147,24 +141,31 @@ binary_has_arch() {
147141PRODUCT_STAGE_ROOT=" $ROOT /.build/package-products/$LOWER_CONF "
148142rm -rf " $PRODUCT_STAGE_ROOT "
149143
150- stage_binary_products () {
144+ stage_build_products () {
151145 local arch=" $1 "
152- local bin_dir stage_dir name
146+ local bin_dir stage_dir name product
153147 swiftpm_bin_path " $arch " bin_dir
154- [[ -n " $bin_dir " ]] || return 0
155148
156149 stage_dir=" $PRODUCT_STAGE_ROOT /$arch "
157150 mkdir -p " $stage_dir "
158151 for name in CodexBar CodexBarCLI CodexBarClaudeWatchdog; do
159- if binary_has_arch " $bin_dir /$name " " $arch " ; then
160- cp " $bin_dir /$name " " $stage_dir /$name "
152+ if ! product=$( codexbar_require_product_file " $bin_dir " " $name " " $arch " ) ; then
153+ return 1
154+ fi
155+ if ! binary_has_arch " $product " " $arch " ; then
156+ echo " ERROR: ${product} does not contain required architecture: ${arch} " >&2
157+ return 1
161158 fi
159+ cp " $product " " $stage_dir /$name "
162160 done
161+ if [[ -d " $bin_dir /CodexBar.dSYM" ]]; then
162+ cp -R " $bin_dir /CodexBar.dSYM" " $stage_dir /"
163+ fi
163164}
164165
165166for ARCH in " ${ARCH_LIST[@]} " ; do
166167 swift build -c " $CONF " --arch " $ARCH "
167- stage_binary_products " $ARCH "
168+ stage_build_products " $ARCH "
168169done
169170
170171APP_FINAL=" $ROOT /CodexBar.app"
@@ -263,30 +264,21 @@ cat > "$APP/Contents/Info.plist" <<PLIST
263264</plist>
264265PLIST
265266
266- # Resolve path to a built binary. Prefer the per-arch snapshot, then SwiftPM's
267- # reported directory, then legacy layouts for older toolchains.
267+ # Resolve a built binary from the fresh per-arch snapshot or SwiftPM's reported directory.
268268resolve_binary_path () {
269269 local name=" $1 "
270270 local arch=" $2 "
271271 local bin_dir candidate
272- candidate=" $PRODUCT_STAGE_ROOT /$arch /$name "
273- if binary_has_arch " $candidate " " $arch " ; then
274- echo " $candidate "
275- return
276- fi
277272 swiftpm_bin_path " $arch " bin_dir
278- if [[ -n " $bin_dir " ]] && binary_has_arch " $bin_dir / $name " " $arch " ; then
279- echo " $bin_dir / $name "
280- return
273+ if ! candidate= $( codexbar_resolve_staged_or_reported_file \
274+ " $PRODUCT_STAGE_ROOT " " $bin_dir " " $name " " $arch " ) ; then
275+ return 1
281276 fi
282- candidate=$( build_product_path " $name " " $arch " )
283- if binary_has_arch " $candidate " " $arch " ; then
284- echo " $candidate "
285- return
286- fi
287- if [[ " $arch " == " arm64" || " $arch " == " x86_64" ]] && binary_has_arch " .build/$CONF /$name " " $arch " ; then
288- echo " .build/$CONF /$name "
277+ if ! binary_has_arch " $candidate " " $arch " ; then
278+ echo " ERROR: ${candidate} does not contain required architecture: ${arch} " >&2
279+ return 1
289280 fi
281+ echo " $candidate "
290282}
291283
292284verify_binary_arches () {
@@ -314,11 +306,8 @@ install_binary() {
314306 local dest=" $2 "
315307 local binaries=()
316308 for arch in " ${ARCH_LIST[@]} " ; do
317- local src bin_dir
318- src=$( resolve_binary_path " $name " " $arch " )
319- if [[ -z " $src " || ! -f " $src " ]]; then
320- swiftpm_bin_path " $arch " bin_dir
321- echo " ERROR: Missing ${name} build for ${arch} (looked in: $PRODUCT_STAGE_ROOT /$arch , $bin_dir , $( build_product_path " $name " " $arch " ) , .build/$CONF )" >&2
309+ local src
310+ if ! src=$( resolve_binary_path " $name " " $arch " ) ; then
322311 exit 1
323312 fi
324313 binaries+=(" $src " )
@@ -420,21 +409,20 @@ install_widget_extension() {
420409
421410install_binary " CodexBar" " $APP /Contents/MacOS/CodexBar"
422411# Ship CodexBarCLI alongside the app for easy symlinking.
423- if [[ -n " $( resolve_binary_path " CodexBarCLI" " ${ARCH_LIST[0]} " ) " ]]; then
424- install_binary " CodexBarCLI" " $APP /Contents/Helpers/CodexBarCLI"
425- fi
412+ install_binary " CodexBarCLI" " $APP /Contents/Helpers/CodexBarCLI"
426413# Watchdog helper: ensures `claude` probes die when CodexBar crashes/gets killed.
427- if [[ -n " $( resolve_binary_path " CodexBarClaudeWatchdog" " ${ARCH_LIST[0]} " ) " ]]; then
428- install_binary " CodexBarClaudeWatchdog" " $APP /Contents/Helpers/CodexBarClaudeWatchdog"
429- fi
414+ install_binary " CodexBarClaudeWatchdog" " $APP /Contents/Helpers/CodexBarClaudeWatchdog"
430415install_widget_extension
416+
417+ swiftpm_bin_path " ${ARCH_LIST[0]} " PREFERRED_BUILD_DIR
418+
431419# Embed Sparkle.framework
432- if [[ -d " .build/ $CONF / Sparkle.framework" ]] ; then
433- cp -R " .build/ $CONF /Sparkle.framework " " $APP /Contents/Frameworks/"
434- chmod -R a+rX " $APP /Contents/Frameworks/Sparkle.framework"
435- install_name_tool -add_rpath " @executable_path/../Frameworks" " $APP /Contents/MacOS/CodexBar"
436- # Re-sign Sparkle and all nested components with Developer ID + timestamp
437- SPARKLE=" $APP /Contents/Frameworks/Sparkle.framework"
420+ SPARKLE_SOURCE= $( codexbar_require_product_directory " $PREFERRED_BUILD_DIR " Sparkle.framework packaging )
421+ cp -R " $SPARKLE_SOURCE " " $APP /Contents/Frameworks/"
422+ chmod -R a+rX " $APP /Contents/Frameworks/Sparkle.framework"
423+ install_name_tool -add_rpath " @executable_path/../Frameworks" " $APP /Contents/MacOS/CodexBar"
424+ # Re-sign Sparkle and all nested components with Developer ID + timestamp
425+ SPARKLE=" $APP /Contents/Frameworks/Sparkle.framework"
438426if [[ " $SIGNING_MODE " == " adhoc" ]]; then
439427 CODESIGN_ID=" -"
440428 CODESIGN_ARGS=(--force --sign " $CODESIGN_ID " )
@@ -446,19 +434,18 @@ else
446434 CODESIGN_ARGS=(--force --timestamp --options runtime --sign " $CODESIGN_ID " )
447435fi
448436function resign() { codesign " ${CODESIGN_ARGS[@]} " " $1 " ; }
449- # Sign innermost binaries first, then the framework root to seal resources
450- resign " $SPARKLE "
451- resign " $SPARKLE /Versions/B/Sparkle"
452- resign " $SPARKLE /Versions/B/Autoupdate"
453- resign " $SPARKLE /Versions/B/Updater.app"
454- resign " $SPARKLE /Versions/B/Updater.app/Contents/MacOS/Updater"
455- resign " $SPARKLE /Versions/B/XPCServices/Downloader.xpc"
456- resign " $SPARKLE /Versions/B/XPCServices/Downloader.xpc/Contents/MacOS/Downloader"
457- resign " $SPARKLE /Versions/B/XPCServices/Installer.xpc"
458- resign " $SPARKLE /Versions/B/XPCServices/Installer.xpc/Contents/MacOS/Installer"
459- resign " $SPARKLE /Versions/B"
460- resign " $SPARKLE "
461- fi
437+ # Sign innermost binaries first, then the framework root to seal resources
438+ resign " $SPARKLE "
439+ resign " $SPARKLE /Versions/B/Sparkle"
440+ resign " $SPARKLE /Versions/B/Autoupdate"
441+ resign " $SPARKLE /Versions/B/Updater.app"
442+ resign " $SPARKLE /Versions/B/Updater.app/Contents/MacOS/Updater"
443+ resign " $SPARKLE /Versions/B/XPCServices/Downloader.xpc"
444+ resign " $SPARKLE /Versions/B/XPCServices/Downloader.xpc/Contents/MacOS/Downloader"
445+ resign " $SPARKLE /Versions/B/XPCServices/Installer.xpc"
446+ resign " $SPARKLE /Versions/B/XPCServices/Installer.xpc/Contents/MacOS/Installer"
447+ resign " $SPARKLE /Versions/B"
448+ resign " $SPARKLE "
462449
463450if [[ -f " $ICON_TARGET " ]]; then
464451 cp " $ICON_TARGET " " $APP /Contents/Resources/Icon.icns"
@@ -475,11 +462,6 @@ if [[ ! -f "$APP/Contents/Resources/Icon-classic.icns" ]]; then
475462fi
476463
477464# SwiftPM resource bundles (e.g. KeyboardShortcuts) are emitted next to the built binary.
478- swiftpm_bin_path " ${ARCH_LIST[0]} " PREFERRED_BUILD_DIR
479- if [[ -z " $PREFERRED_BUILD_DIR " ]]; then
480- CODEXBAR_BINARY=" $( resolve_binary_path " CodexBar" " ${ARCH_LIST[0]} " ) "
481- PREFERRED_BUILD_DIR=" $( dirname " ${CODEXBAR_BINARY:- $(build_product_path " CodexBar" " ${ARCH_LIST[0]} " )} " ) "
482- fi
483465shopt -s nullglob
484466SWIFTPM_BUNDLES=(" ${PREFERRED_BUILD_DIR} /" * .bundle)
485467shopt -u nullglob
0 commit comments