Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -36,14 +34,13 @@ class KdfExecutableFinder {
/// Attempts to find the KDF executable in standard and platform-specific
/// locations
Future<File?> 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',
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Dart Code Mismatch with Podspec Path

The Dart code expects the kdf binary within the framework at Versions/Current/Helpers/kdf, but the podspec copies it to Contents/Helpers/kdf. This path mismatch prevents the executable finder from locating the binary at runtime.

Additional Locations (1)

Fix in Cursor Fix in Web

executableName,
]);

Expand All @@ -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,
Expand Down
110 changes: 63 additions & 47 deletions packages/komodo_defi_framework/macos/komodo_defi_framework.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,22 @@ 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']
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Missing kdf Executable in App Bundle

The bin/kdf executable is no longer included in resource_bundles (L19) and its s.preserve_paths directive is commented out (L22). This prevents CocoaPods from making the file available, causing the build script's copy operation (L40) to fail. Consequently, the kdf executable is missing from the app bundle, breaking runtime functionality.

Fix in Cursor Fix in Web


s.script_phase = {
:name => 'Install kdf executable and/or dylib',
:execution_position => :before_compile,
:script => <<-SCRIPT
# 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"

Comment on lines 28 to 35
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Copy kdf binary into framework Helpers path

The macOS script now defines HELPERS_DIR as ${TARGET_BUILD_DIR}/${CONTENTS_FOLDER_PATH}/Helpers and copies the executable there. However, kdf_executable_finder.dart was simultaneously updated to only look in Frameworks/komodo_defi_framework.framework/Versions/Current/Helpers/kdf. Because the script no longer places the binary inside the framework’s Helpers directory, the runtime search path no longer contains the copied file and the kdf executable cannot be found on macOS builds. Update HELPERS_DIR to point at ${FRAMEWORKS_DIR}/komodo_defi_framework.framework/Versions/Current/Helpers (or add that location to the finder) so the binary ends up where the Dart code expects it.

Useful? React with 👍 / 👎.

# Track if we found at least one of the required files
FOUND_REQUIRED_FILE=0
Expand All @@ -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*)
Comment on lines +60 to +61
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The case statement is missing a pattern terminator (;;). Shell case syntax requires ';;' after the commands for the Release* branch; without it the script will error at 'esac'. Add ';;' after the last command inside the Release* section before line 101.

Copilot uses AI. Check for mistakes.
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
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The case statement is missing a pattern terminator (;;). Shell case syntax requires ';;' after the commands for the Release* branch; without it the script will error at 'esac'. Add ';;' after the last command inside the Release* section before line 101.

Suggested change
if [ -f "$FRAMEWORKS_DIR/libkdflib.dylib" ]; then install_name_tool -id "@rpath/libkdflib.dylib" "$FRAMEWORKS_DIR/libkdflib.dylib"; fi
if [ -f "$FRAMEWORKS_DIR/libkdflib.dylib" ]; then install_name_tool -id "@rpath/libkdflib.dylib" "$FRAMEWORKS_DIR/libkdflib.dylib"; fi
;;

Copilot uses AI. Check for mistakes.
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
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The kdf binary is signed before being copied into Helpers, but the copy placed in Helpers (the only lookup location) is never re-signed. This can leave the executed binary unsigned, triggering Gatekeeper or runtime issues. Invoke code_sign_if_enabled on '$HELPERS_DIR/kdf' after the copy (or copy first, then sign both locations if backward compatibility is needed).

Suggested change
if [ -f "$APP_SUPPORT_DIR/kdf" ]; then cp "$APP_SUPPORT_DIR/kdf" "$HELPERS_DIR/kdf"; fi
if [ -f "$APP_SUPPORT_DIR/kdf" ]; then cp "$APP_SUPPORT_DIR/kdf" "$HELPERS_DIR/kdf"; fi
code_sign_if_enabled "$HELPERS_DIR/kdf" || true

Copilot uses AI. Check for mistakes.
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."
Expand Down
Loading