diff --git a/packages/komodo_defi_framework/lib/src/native/kdf_executable_finder.dart b/packages/komodo_defi_framework/lib/src/native/kdf_executable_finder.dart index 3d7a27d5..9029babf 100644 --- a/packages/komodo_defi_framework/lib/src/native/kdf_executable_finder.dart +++ b/packages/komodo_defi_framework/lib/src/native/kdf_executable_finder.dart @@ -22,9 +22,7 @@ enum BuildMode { /// Helper class for locating the KDF executable across different platforms class KdfExecutableFinder { - KdfExecutableFinder({ - required this.logCallback, - }); + KdfExecutableFinder({required this.logCallback}); final void Function(String) logCallback; @@ -36,14 +34,13 @@ class KdfExecutableFinder { /// Attempts to find the KDF executable in standard and platform-specific /// locations Future findExecutable({String executableName = 'kdf'}) async { - final macosKdfResourcePath = p.joinAll([ + final macosHelpersInFrameworkPath = p.joinAll([ p.dirname(p.dirname(Platform.resolvedExecutable)), 'Frameworks', 'komodo_defi_framework.framework', - 'Resources', - 'kdf_resources.bundle', - 'Contents', - 'Resources', + 'Versions', + 'Current', + 'Helpers', executableName, ]); @@ -54,7 +51,7 @@ class KdfExecutableFinder { p.join(Directory.current.path, '$executableName.exe'), p.join(Directory.current.path, 'lib/$executableName'), p.join(Directory.current.path, 'lib/$executableName.exe'), - macosKdfResourcePath, + macosHelpersInFrameworkPath, constructWindowsBuildArtifactPath( mode: currentBuildMode, executableName: executableName, diff --git a/packages/komodo_defi_framework/macos/komodo_defi_framework.podspec b/packages/komodo_defi_framework/macos/komodo_defi_framework.podspec index 13cdad6b..25fdac50 100644 --- a/packages/komodo_defi_framework/macos/komodo_defi_framework.podspec +++ b/packages/komodo_defi_framework/macos/komodo_defi_framework.podspec @@ -16,9 +16,11 @@ A new Flutter FFI plugin project. s.dependency 'FlutterMacOS' s.resource_bundles = { - 'kdf_resources' => ['bin/kdf', 'lib/*.dylib'].select { |f| Dir.exist?(File.dirname(f)) } + 'kdf_resources' => ['lib/*.dylib'].select { |f| Dir.exist?(File.dirname(f)) } } + # s.preserve_paths = ['bin/kdf'] + s.script_phase = { :name => 'Install kdf executable and/or dylib', :execution_position => :before_compile, @@ -26,16 +28,10 @@ A new Flutter FFI plugin project. # Get the application support directory for macOS APP_SUPPORT_DIR="${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Contents/Library/Application Support" FRAMEWORKS_DIR="${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Contents/Frameworks" + HELPERS_DIR="${TARGET_BUILD_DIR}/${CONTENTS_FOLDER_PATH}/Helpers" - # Ensure the application support directory exists - if [ ! -d "$APP_SUPPORT_DIR" ]; then - mkdir -p "$APP_SUPPORT_DIR" - fi - - # Ensure the frameworks directory exists - if [ ! -d "$FRAMEWORKS_DIR" ]; then - mkdir -p "$FRAMEWORKS_DIR" - fi + # Create all required directories in one go + mkdir -p "$APP_SUPPORT_DIR" "$FRAMEWORKS_DIR" "$HELPERS_DIR" # Track if we found at least one of the required files FOUND_REQUIRED_FILE=0 @@ -61,54 +57,74 @@ A new Flutter FFI plugin project. fi # Prune binary slices to match $ARCHS (preserve universals) in Release builds only - if [ "$CONFIGURATION" = "Release" ]; then - TARGET_ARCHS="${ARCHS:-$(arch)}" + case "$CONFIGURATION" in + Release*) + TARGET_ARCHS="${ARCHS:-$(arch)}" - thin_binary_to_archs() { - file="$1" - keep_archs="$2" + thin_binary_to_archs() { + file="$1" + keep_archs="$2" - [ -f "$file" ] || return 0 + [ -f "$file" ] || return 0 - # Only act on fat files (multi-arch) - if ! lipo -info "$file" | grep -q 'Architectures in the fat file'; then - return 0 - fi + # Only act on fat files (multi-arch) + if ! lipo -info "$file" | grep -q 'Architectures in the fat file'; then + return 0 + fi - bin_archs="$(lipo -archs "$file" 2>/dev/null || true)" - [ -n "$bin_archs" ] || return 0 + bin_archs="$(lipo -archs "$file" 2>/dev/null || true)" + [ -n "$bin_archs" ] || return 0 - dir="$(dirname "$file")" - base="$(basename "$file")" - work="$file" + dir="$(dirname "$file")" + base="$(basename "$file")" + work="$file" - for arch in $bin_archs; do - echo "$keep_archs" | tr ' ' '\n' | grep -qx "$arch" && continue - echo "Removing architecture $arch from $base" - next="$(mktemp "$dir/.${base}.XXXXXX")" - lipo "$work" -remove "$arch" -output "$next" - [ "$work" != "$file" ] && rm -f "$work" - work="$next" - done + for arch in $bin_archs; do + echo "$keep_archs" | tr ' ' '\n' | grep -qx "$arch" && continue + echo "Removing architecture $arch from $base" + next="$(mktemp "$dir/.${base}.XXXXXX")" + lipo "$work" -remove "$arch" -output "$next" + [ "$work" != "$file" ] && rm -f "$work" + work="$next" + done - if [ "$work" != "$file" ]; then - mv -f "$work" "$file" - fi - } + if [ "$work" != "$file" ]; then + mv -f "$work" "$file" + fi + } - thin_binary_to_archs "$APP_SUPPORT_DIR/kdf" "$TARGET_ARCHS" - if [ -f "$APP_SUPPORT_DIR/kdf" ]; then chmod +x "$APP_SUPPORT_DIR/kdf"; fi + thin_binary_to_archs "$APP_SUPPORT_DIR/kdf" "$TARGET_ARCHS" + if [ -f "$APP_SUPPORT_DIR/kdf" ]; then chmod +x "$APP_SUPPORT_DIR/kdf"; fi - thin_binary_to_archs "$FRAMEWORKS_DIR/libkdflib.dylib" "$TARGET_ARCHS" - if [ -f "$FRAMEWORKS_DIR/libkdflib.dylib" ]; then install_name_tool -id "@rpath/libkdflib.dylib" "$FRAMEWORKS_DIR/libkdflib.dylib"; fi + thin_binary_to_archs "$FRAMEWORKS_DIR/libkdflib.dylib" "$TARGET_ARCHS" + if [ -f "$FRAMEWORKS_DIR/libkdflib.dylib" ]; then install_name_tool -id "@rpath/libkdflib.dylib" "$FRAMEWORKS_DIR/libkdflib.dylib"; fi + esac - # Re-sign after modifications (best-effort) - if [ -n "$EXPANDED_CODE_SIGN_IDENTITY" ]; then - codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" "$APP_SUPPORT_DIR/kdf" 2>/dev/null || true - codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" "$FRAMEWORKS_DIR/libkdflib.dylib" 2>/dev/null || true + # Signs a framework with the provided identity + code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identity + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" + else + echo "Code Signing DISABLED. Is this correct for your configuration?" fi - fi - + } + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "$APP_SUPPORT_DIR/kdf" || true + # Helpers in komodo_defi_framework is now the ONLY place where KdfExecutableFinder.findExecutable() + # will look for the kdf binary on macOS. The APP_SUPPORT_DIR copy is redundant but kept for + # backward compatibility with older builds. + if [ -f "$APP_SUPPORT_DIR/kdf" ]; then cp "$APP_SUPPORT_DIR/kdf" "$HELPERS_DIR/kdf"; fi + code_sign_if_enabled "$FRAMEWORKS_DIR/libkdflib.dylib" || true + # Fail if neither file was found if [ $FOUND_REQUIRED_FILE -eq 0 ]; then echo "Error: Neither kdf executable nor libkdflib.dylib was found. At least one is required."