mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-17 05:41:29 +02:00
use ffi for mweb (#2456)
* chore: add ffi and ffigen dependencies to pubspec.yaml * refactor: replace method channel with FFI implementation for MWeb module * fix: correct `cd` command in build_mwebd.sh script * chore: add go.sum file with dependency checksums * fix: ensure ANDROID_NDK_VERSION is set before building and dynamically update NDK_BIN path * fix: update NDK_BIN path to dynamically detect platform in build_mwebd.sh script * refactor: remove unused mwebd dependencies and clean up CwMwebPlugin code * Update scripts/android/build_mwebd.sh Co-authored-by: cyan <cyjan@mrcyjanek.net> * refactor: replace iOS MoneroWallet framework with Mwebd.xcframework and clean up plugin implementation [skip-ci] * fix: mwebd ffi ios * refactor: update MWebFfi class to use non-nullable `lib` and improve address debug logging * chore: remove unused iOS/Android build scripts for mwebd * refactor: replace mweb.so with libmweb.so, use sync methods in MWebFfi, and update iOS/Android frameworks/scripts accordingly * chore: unify mwebd build process in workflows, remove unused gomobile init command --------- Co-authored-by: cyan <cyjan@mrcyjanek.net>
This commit is contained in:
co-authored by
cyan
parent
52e778f275
commit
309ad1836e
@@ -6,14 +6,43 @@ else
|
||||
sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.24.1.linux-amd64.tar.gz
|
||||
export PATH=$PATH:/usr/local/go/bin
|
||||
export PATH=$PATH:~/go/bin
|
||||
go install golang.org/x/mobile/cmd/gomobile@latest
|
||||
gomobile init
|
||||
fi
|
||||
|
||||
# build mwebd:
|
||||
git clone https://github.com/ltcmweb/mwebd
|
||||
cd mwebd
|
||||
git reset --hard f75cb9edef07d03360ee2d33e6edae4243a890b1
|
||||
gomobile bind -target=android -androidapi 21 .
|
||||
mkdir -p ../../../cw_mweb/android/libs/
|
||||
cp ./mwebd.aar $_
|
||||
cd ../../cw_mweb/go
|
||||
|
||||
if [[ "x$ANDROID_NDK_VERSION" == "x" ]];
|
||||
then
|
||||
echo "ANDROID_NDK_VERSION is missing, please declare it before building"
|
||||
echo "You have these versions installed on your system currently:"
|
||||
ls ${ANDROID_HOME}/ndk/ | cat | awk '{ print "- " $1 }'
|
||||
echo "echo > ~/.zprofile"
|
||||
echo "echo 'export ANDROID_NDK_VERSION=..... > ~/.zprofile"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export ANDROID_OUT=../android/src/main/jniLibs
|
||||
export ANDROID_SDK="${HOME}/Library/Android/sdk"
|
||||
export NDK_BIN="${ANDROID_HOME}/ndk/${ANDROID_NDK_VERSION}/toolchains/llvm/prebuilt/$(uname | tr '[:upper:]' '[:lower:]')-x86_64/bin"
|
||||
|
||||
# Compile for x86_64 architecture and place the binary file in the android/src/main/jniLibs/x86_64 folder
|
||||
CGO_ENABLED=1 \
|
||||
GOOS=android \
|
||||
GOARCH=amd64 \
|
||||
CC=${NDK_BIN}/x86_64-linux-android21-clang \
|
||||
go build -buildmode=c-shared -o ${ANDROID_OUT}/x86_64/libmweb.so .
|
||||
|
||||
# Compile for arm64 architecture and place the binary file in the android/src/main/jniLibs/arm64-v8a folder
|
||||
CGO_ENABLED=1 \
|
||||
GOOS=android \
|
||||
GOARCH=arm64 \
|
||||
CC=${NDK_BIN}/aarch64-linux-android21-clang \
|
||||
go build -buildmode=c-shared -o ${ANDROID_OUT}/arm64-v8a/libmweb.so .
|
||||
|
||||
# Compile for armv7a architecture and place the binary file in the android/src/main/jniLibs/armeabi-v7a folder
|
||||
CGO_ENABLED=1 \
|
||||
GOOS=android \
|
||||
GOARCH=arm \
|
||||
CC=${NDK_BIN}/armv7a-linux-androideabi21-clang \
|
||||
go build -buildmode=c-shared -o ${ANDROID_OUT}/armeabi-v7a/libmweb.so .
|
||||
cd ../
|
||||
dart run ffigen --config ffigen_config.yaml
|
||||
|
||||
+258
-11
@@ -1,20 +1,267 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e -x
|
||||
|
||||
if [[ "$1" == "--dont-install" ]]; then
|
||||
echo "Skipping Go installation as per --dont-install flag"
|
||||
else
|
||||
# install go > 1.24:
|
||||
brew install go
|
||||
export PATH=$PATH:~/go/bin
|
||||
go install golang.org/x/mobile/cmd/gomobile@latest
|
||||
gomobile init
|
||||
fi
|
||||
|
||||
# build mwebd:
|
||||
git clone https://github.com/ltcmweb/mwebd
|
||||
cd mwebd
|
||||
git reset --hard f75cb9edef07d03360ee2d33e6edae4243a890b1
|
||||
gomobile bind -target=ios .
|
||||
mv -fn ./Mwebd.xcframework ../../../cw_mweb/ios/
|
||||
# cleanup:
|
||||
cd ..
|
||||
rm -rf mwebd
|
||||
BASE_DIR="$(pwd)"
|
||||
MWEB_GO_DIR="${BASE_DIR}/../../cw_mweb/go"
|
||||
IOS_OUTPUT_DIR="${BASE_DIR}/../../cw_mweb/ios"
|
||||
TMP_DIR="${BASE_DIR}/tmp_mweb_frameworks"
|
||||
FRAMEWORK_NAME="Mwebd"
|
||||
|
||||
rm -rf "$TMP_DIR"
|
||||
mkdir -p "$TMP_DIR"
|
||||
|
||||
mkdir -p "$IOS_OUTPUT_DIR"
|
||||
|
||||
write_info_plist() {
|
||||
local framework_bundle="$1"
|
||||
local framework_name="$2"
|
||||
local target="$3"
|
||||
local arch="$4"
|
||||
local plist_path="${framework_bundle}/Info.plist"
|
||||
|
||||
local platform min_os_version dtplatformname dtsdkname
|
||||
|
||||
if [[ "$target" == "ios-simulator" ]]; then
|
||||
platform="iPhoneSimulator"
|
||||
dtplatformname="iphonesimulator"
|
||||
dtsdkname="iphonesimulator17.4"
|
||||
min_os_version="12.0"
|
||||
elif [[ "$target" == "ios" ]]; then
|
||||
platform="iPhoneOS"
|
||||
dtplatformname="iphoneos"
|
||||
dtsdkname="iphoneos17.4"
|
||||
min_os_version="12.0"
|
||||
else
|
||||
echo "Unknown target: $target"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat > "$plist_path" <<EOF
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildMachineOSBuild</key>
|
||||
<string>23F79</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${framework_name}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.cakewallet.${framework_name}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${framework_name}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>${platform}</string>
|
||||
</array>
|
||||
<key>DTCompiler</key>
|
||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||
<key>DTPlatformName</key>
|
||||
<string>${dtplatformname}</string>
|
||||
<key>DTPlatformVersion</key>
|
||||
<string>17.4</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>21E213</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>${dtsdkname}</string>
|
||||
<key>DTSDKVersion</key>
|
||||
<string>17.4</string>
|
||||
<key>DTXcode</key>
|
||||
<string>1530</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>15E204a</string>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>${min_os_version}</string>
|
||||
<key>UIDeviceFamily</key>
|
||||
<array>
|
||||
<integer>1</integer>
|
||||
<integer>2</integer>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
EOF
|
||||
}
|
||||
|
||||
build_go_library() {
|
||||
local goos="$1"
|
||||
local goarch="$2"
|
||||
local cc_target="$3"
|
||||
local sdk="$4"
|
||||
local output_file="$5"
|
||||
|
||||
echo "Building Go library for ${goos}/${goarch} with target ${cc_target}..."
|
||||
|
||||
cd "$MWEB_GO_DIR"
|
||||
|
||||
export GOOS="$goos"
|
||||
export GOARCH="$goarch"
|
||||
export CGO_ENABLED=1
|
||||
export CGO_CFLAGS="-fembed-bitcode"
|
||||
|
||||
if [[ "$sdk" == "iphoneos" ]]; then
|
||||
export CC="$(xcrun -f clang) -target $cc_target -mios-version-min=12 --sysroot $(xcrun --sdk iphoneos --show-sdk-path)"
|
||||
else
|
||||
export CC="$(xcrun -f clang) -target $cc_target -mios-simulator-version-min=12 --sysroot $(xcrun --sdk iphonesimulator --show-sdk-path)"
|
||||
fi
|
||||
|
||||
go build -buildmode=c-archive -trimpath -o "$output_file" mweb.go
|
||||
|
||||
echo "Built: $output_file"
|
||||
cd - > /dev/null
|
||||
}
|
||||
|
||||
create_framework() {
|
||||
local archive_path="$1"
|
||||
local framework_name="$2"
|
||||
local target="$3"
|
||||
local out_dir="$4"
|
||||
local arch="$5"
|
||||
|
||||
echo "Creating ${framework_name}.framework for target ${target} (${arch}) in ${out_dir}..."
|
||||
|
||||
local framework_bundle="${out_dir}/${framework_name}.framework"
|
||||
|
||||
rm -rf "$framework_bundle"
|
||||
mkdir -p "$framework_bundle"
|
||||
|
||||
if [[ ! -f "$archive_path" ]]; then
|
||||
echo "Error: Input archive not found: $archive_path"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local temp_dir="${TMP_DIR}/temp_${arch}"
|
||||
mkdir -p "$temp_dir"
|
||||
|
||||
pushd "$temp_dir"
|
||||
ar x "$archive_path"
|
||||
|
||||
if [[ "$target" == "ios" ]]; then
|
||||
xcrun -sdk iphoneos clang -dynamiclib -arch "${arch}" -mios-version-min=12 \
|
||||
-install_name "@rpath/${framework_name}.framework/${framework_name}" \
|
||||
-framework CoreFoundation -framework Security -lresolv \
|
||||
-o "${framework_bundle}/${framework_name}" ./*.o
|
||||
else
|
||||
xcrun -sdk iphonesimulator clang -dynamiclib -arch "${arch}" -mios-simulator-version-min=12 \
|
||||
-install_name "@rpath/${framework_name}.framework/${framework_name}" \
|
||||
-framework CoreFoundation -framework Security -lresolv \
|
||||
-o "${framework_bundle}/${framework_name}" ./*.o
|
||||
fi
|
||||
popd
|
||||
|
||||
echo "Created binary: ${framework_bundle}/${framework_name}"
|
||||
|
||||
write_info_plist "$framework_bundle" "$framework_name" "$target" "$arch"
|
||||
|
||||
mkdir -p "${framework_bundle}/Headers"
|
||||
local header_file="${archive_path%.a}.h"
|
||||
if [[ -f "$header_file" ]]; then
|
||||
cp "$header_file" "${framework_bundle}/Headers/${framework_name}.h"
|
||||
echo "Copied header: ${framework_bundle}/Headers/${framework_name}.h"
|
||||
fi
|
||||
|
||||
echo "Framework created: ${framework_bundle}"
|
||||
}
|
||||
|
||||
create_xcframework() {
|
||||
local framework_name="$1"
|
||||
local xcframework_output="$2"
|
||||
shift 2
|
||||
local frameworks=("$@")
|
||||
|
||||
echo "Creating ${xcframework_output} by bundling:"
|
||||
for fw in "${frameworks[@]}"; do
|
||||
echo " Framework: ${fw}"
|
||||
done
|
||||
|
||||
local xcodebuild_args=()
|
||||
for fw in "${frameworks[@]}"; do
|
||||
xcodebuild_args+=("-framework" "$fw")
|
||||
done
|
||||
|
||||
rm -rf "$xcframework_output"
|
||||
xcodebuild -create-xcframework "${xcodebuild_args[@]}" -output "$xcframework_output"
|
||||
|
||||
echo "Created XCFramework: ${xcframework_output}"
|
||||
}
|
||||
|
||||
echo "Building MWEB XCFramework for iOS..."
|
||||
|
||||
IOS_DEVICE_OUT="${TMP_DIR}/ios_device"
|
||||
IOS_SIMULATOR_ARM64_OUT="${TMP_DIR}/ios_simulator_arm64"
|
||||
IOS_SIMULATOR_X86_64_OUT="${TMP_DIR}/ios_simulator_x86_64"
|
||||
|
||||
mkdir -p "$IOS_DEVICE_OUT" "$IOS_SIMULATOR_ARM64_OUT" "$IOS_SIMULATOR_X86_64_OUT"
|
||||
|
||||
IOS_DEVICE_ARCHIVE="${TMP_DIR}/${FRAMEWORK_NAME}_device.a"
|
||||
IOS_SIMULATOR_ARM64_ARCHIVE="${TMP_DIR}/${FRAMEWORK_NAME}_sim_arm64.a"
|
||||
IOS_SIMULATOR_X86_64_ARCHIVE="${TMP_DIR}/${FRAMEWORK_NAME}_sim_x86_64.a"
|
||||
|
||||
build_go_library "ios" "arm64" "aarch64-apple-ios" "iphoneos" "$IOS_DEVICE_ARCHIVE"
|
||||
build_go_library "ios" "arm64" "aarch64-apple-ios-simulator" "iphonesimulator" "$IOS_SIMULATOR_ARM64_ARCHIVE"
|
||||
build_go_library "ios" "amd64" "x86_64-apple-ios-simulator" "iphonesimulator" "$IOS_SIMULATOR_X86_64_ARCHIVE"
|
||||
|
||||
create_framework "$IOS_DEVICE_ARCHIVE" "$FRAMEWORK_NAME" "ios" "$IOS_DEVICE_OUT" "arm64"
|
||||
create_framework "$IOS_SIMULATOR_ARM64_ARCHIVE" "$FRAMEWORK_NAME" "ios-simulator" "$IOS_SIMULATOR_ARM64_OUT" "arm64"
|
||||
create_framework "$IOS_SIMULATOR_X86_64_ARCHIVE" "$FRAMEWORK_NAME" "ios-simulator" "$IOS_SIMULATOR_X86_64_OUT" "x86_64"
|
||||
|
||||
IOS_SIMULATOR_UNIVERSAL_OUT="${TMP_DIR}/ios_simulator_universal"
|
||||
mkdir -p "$IOS_SIMULATOR_UNIVERSAL_OUT"
|
||||
|
||||
SIMULATOR_UNIVERSAL_FRAMEWORK="${IOS_SIMULATOR_UNIVERSAL_OUT}/${FRAMEWORK_NAME}.framework"
|
||||
mkdir -p "$SIMULATOR_UNIVERSAL_FRAMEWORK"
|
||||
|
||||
lipo -create \
|
||||
"${IOS_SIMULATOR_ARM64_OUT}/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}" \
|
||||
"${IOS_SIMULATOR_X86_64_OUT}/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}" \
|
||||
-output "${SIMULATOR_UNIVERSAL_FRAMEWORK}/${FRAMEWORK_NAME}"
|
||||
|
||||
echo "Created universal simulator binary: ${SIMULATOR_UNIVERSAL_FRAMEWORK}/${FRAMEWORK_NAME}"
|
||||
|
||||
cp -r "${IOS_SIMULATOR_ARM64_OUT}/${FRAMEWORK_NAME}.framework/Info.plist" "${SIMULATOR_UNIVERSAL_FRAMEWORK}/"
|
||||
cp -r "${IOS_SIMULATOR_ARM64_OUT}/${FRAMEWORK_NAME}.framework/Headers" "${SIMULATOR_UNIVERSAL_FRAMEWORK}/"
|
||||
|
||||
IOS_DEVICE_FRAMEWORK="${IOS_DEVICE_OUT}/${FRAMEWORK_NAME}.framework"
|
||||
IOS_SIMULATOR_FRAMEWORK="${SIMULATOR_UNIVERSAL_FRAMEWORK}"
|
||||
|
||||
IOS_XCFRAMEWORK="${IOS_OUTPUT_DIR}/${FRAMEWORK_NAME}.xcframework"
|
||||
create_xcframework "$FRAMEWORK_NAME" "$IOS_XCFRAMEWORK" "$IOS_DEVICE_FRAMEWORK" "$IOS_SIMULATOR_FRAMEWORK"
|
||||
|
||||
echo ""
|
||||
echo "XCFramework created successfully:"
|
||||
echo " iOS XCFramework: ${IOS_XCFRAMEWORK}"
|
||||
echo ""
|
||||
|
||||
FFIGEN_CONFIG="${BASE_DIR}/../../cw_mweb/ffigen_config.yaml"
|
||||
if [[ -f "$FFIGEN_CONFIG" ]]; then
|
||||
echo "Updating ffigen configuration..."
|
||||
sed -i.bak "s|android/src/main/jniLibs/arm64-v8a/mweb.h|ios/${FRAMEWORK_NAME}.xcframework/ios-arm64/${FRAMEWORK_NAME}.framework/Headers/${FRAMEWORK_NAME}.h|g" "$FFIGEN_CONFIG"
|
||||
mv "$FFIGEN_CONFIG.bak" "$FFIGEN_CONFIG"
|
||||
echo "Updated ffigen config to use XCFramework header"
|
||||
fi
|
||||
|
||||
cd "${BASE_DIR}/../../cw_mweb"
|
||||
echo "Generating Dart FFI bindings..."
|
||||
dart run ffigen --config ffigen_config.yaml
|
||||
|
||||
echo "Build completed successfully!"
|
||||
|
||||
rm -rf "$TMP_DIR"
|
||||
echo "Temporary files cleaned up."
|
||||
Reference in New Issue
Block a user