Skip to content

Commit b8ed823

Browse files
committed
iOS builds for tc_helper
1 parent c4b6919 commit b8ed823

File tree

8 files changed

+219
-8
lines changed

8 files changed

+219
-8
lines changed

build_itchelper

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#!/bin/bash
2+
3+
# --- Configuration ---
4+
CRATE_NAME="tc_helper"
5+
RUST_DIR="rust"
6+
IOS_DIR="ios"
7+
FRAMEWORK_NAME="tc_helper.framework"
8+
XCFRAMEWORK_NAME="tc_helper.xcframework"
9+
BUNDLE_ID="com.ccextractor.taskwarriorflutter.tc-helper"
10+
# !!! CRITICAL FIX !!!
11+
# We force the build to target iOS 13.0.
12+
# This fixes the "___chkstk_darwin" and "version mismatch" errors.
13+
export IPHONEOS_DEPLOYMENT_TARGET=13.0
14+
15+
echo "🚀 Starting Build for $CRATE_NAME..."
16+
17+
cd $RUST_DIR
18+
19+
# 1. Build for Device (iPhone - arm64)
20+
echo "🛠️ Building for iPhone (arm64)..."
21+
# We pass the CFLAG to ensure C dependencies (like aws-lc-sys) respect the target
22+
CFLAGS="-miphoneos-version-min=13.0" \
23+
cargo build --release --target aarch64-apple-ios
24+
25+
# 2. Build for Simulator (Apple Silicon - arm64)
26+
echo "🛠️ Building for Simulator (arm64)..."
27+
CFLAGS="-miphoneos-version-min=13.0" \
28+
cargo build --release --target aarch64-apple-ios-sim
29+
30+
# 3. Build for Simulator (Intel - x86_64)
31+
echo "🛠️ Building for Simulator (x86_64)..."
32+
CFLAGS="-miphoneos-version-min=13.0" \
33+
cargo build --release --target x86_64-apple-ios
34+
35+
cd ..
36+
37+
# --- Package Creation ---
38+
echo "📦 Packaging..."
39+
40+
# Create a temporary directory for the Simulator "Fat" library
41+
mkdir -p build/ios_sim
42+
SIM_LIB="build/ios_sim/lib$CRATE_NAME.dylib"
43+
44+
# Combine the two Simulator architectures (Intel + M1) into one file
45+
lipo -create \
46+
"$RUST_DIR/target/x86_64-apple-ios/release/lib$CRATE_NAME.dylib" \
47+
"$RUST_DIR/target/aarch64-apple-ios-sim/release/lib$CRATE_NAME.dylib" \
48+
-output "$SIM_LIB"
49+
50+
# Define function to create a .framework structure
51+
create_framework() {
52+
local LIB_PATH=$1
53+
local TARGET_DIR=$2
54+
55+
mkdir -p "$TARGET_DIR/$FRAMEWORK_NAME"
56+
57+
# Copy and rename binary (libtc_helper.dylib -> tc_helper)
58+
cp "$LIB_PATH" "$TARGET_DIR/$FRAMEWORK_NAME/$CRATE_NAME"
59+
60+
# Create Info.plist
61+
cat <<EOF > "$TARGET_DIR/$FRAMEWORK_NAME/Info.plist"
62+
<?xml version="1.0" encoding="UTF-8"?>
63+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
64+
<plist version="1.0">
65+
<dict>
66+
<key>CFBundleExecutable</key>
67+
<string>$CRATE_NAME</string>
68+
<key>CFBundleIdentifier</key>
69+
<string>$BUNDLE_ID</string>
70+
<key>CFBundleInfoDictionaryVersion</key>
71+
<string>6.0</string>
72+
<key>CFBundlePackageType</key>
73+
<string>FMWK</string>
74+
<key>CFBundleSignature</key>
75+
<string>????</string>
76+
<key>CFBundleVersion</key>
77+
<string>1.0</string>
78+
<key>MinimumOSVersion</key>
79+
<string>13.0</string>
80+
</dict>
81+
</plist>
82+
EOF
83+
}
84+
85+
# Create framework structure for Simulator
86+
create_framework "$SIM_LIB" "build/ios_sim"
87+
88+
# Create framework structure for Device
89+
mkdir -p build/ios_device
90+
create_framework "$RUST_DIR/target/aarch64-apple-ios/release/lib$CRATE_NAME.dylib" "build/ios_device"
91+
92+
# --- Create XCFramework ---
93+
echo "🔗 Creating XCFramework..."
94+
rm -rf "$IOS_DIR/$XCFRAMEWORK_NAME"
95+
96+
xcodebuild -create-xcframework \
97+
-framework "build/ios_device/$FRAMEWORK_NAME" \
98+
-framework "build/ios_sim/$FRAMEWORK_NAME" \
99+
-output "$IOS_DIR/$XCFRAMEWORK_NAME"
100+
101+
# Clean up temp build folder
102+
rm -rf build/ios_sim build/ios_device
103+
104+
echo "✅ Success! Created $IOS_DIR/$XCFRAMEWORK_NAME"

ios/Runner.xcodeproj/project.pbxproj

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
/* Begin PBXBuildFile section */
1010
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11+
197929182EE87FCF00023EC4 /* tc_helper.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 197929172EE87FCF00023EC4 /* tc_helper.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
1112
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
1213
64C7FEE08035BC9BB0C038EF /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 089D9819C0366C673FE320BF /* Pods_Runner.framework */; };
1314
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
@@ -32,10 +33,11 @@
3233
/* Begin PBXCopyFilesBuildPhase section */
3334
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
3435
isa = PBXCopyFilesBuildPhase;
35-
buildActionMask = 2147483647;
36+
buildActionMask = 12;
3637
dstPath = "";
3738
dstSubfolderSpec = 10;
3839
files = (
40+
197929182EE87FCF00023EC4 /* tc_helper.xcframework in Embed Frameworks */,
3941
);
4042
name = "Embed Frameworks";
4143
runOnlyForDeploymentPostprocessing = 0;
@@ -58,6 +60,7 @@
5860
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
5961
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
6062
162E9301614D923D4E360425 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
63+
197929172EE87FCF00023EC4 /* tc_helper.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = tc_helper.xcframework; sourceTree = "<group>"; };
6164
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
6265
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
6366
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@@ -79,7 +82,7 @@
7982
/* End PBXFileReference section */
8083

8184
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
82-
AABC0ECB2DA46F0E008D692D /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = {
85+
AABC0ECB2DA46F0E008D692D /* Exceptions for "TaskWarriorWidgets" folder in "TaskWarriorWidgetsExtension" target */ = {
8386
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
8487
membershipExceptions = (
8588
Info.plist,
@@ -89,7 +92,18 @@
8992
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
9093

9194
/* Begin PBXFileSystemSynchronizedRootGroup section */
92-
AABC0EBA2DA46F0C008D692D /* TaskWarriorWidgets */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (AABC0ECB2DA46F0E008D692D /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = TaskWarriorWidgets; sourceTree = "<group>"; };
95+
AABC0EBA2DA46F0C008D692D /* TaskWarriorWidgets */ = {
96+
isa = PBXFileSystemSynchronizedRootGroup;
97+
exceptions = (
98+
AABC0ECB2DA46F0E008D692D /* Exceptions for "TaskWarriorWidgets" folder in "TaskWarriorWidgetsExtension" target */,
99+
);
100+
explicitFileTypes = {
101+
};
102+
explicitFolders = (
103+
);
104+
path = TaskWarriorWidgets;
105+
sourceTree = "<group>";
106+
};
93107
/* End PBXFileSystemSynchronizedRootGroup section */
94108

95109
/* Begin PBXFrameworksBuildPhase section */
@@ -127,6 +141,7 @@
127141
97C146E51CF9000F007C117D = {
128142
isa = PBXGroup;
129143
children = (
144+
197929172EE87FCF00023EC4 /* tc_helper.xcframework */,
130145
AABC0F822DA481B0008D692D /* TaskWarriorWidgetsExtensionDebug.entitlements */,
131146
9740EEB11CF90186004384FC /* Flutter */,
132147
97C146F01CF9000F007C117D /* Runner */,
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>AvailableLibraries</key>
6+
<array>
7+
<dict>
8+
<key>BinaryPath</key>
9+
<string>tc_helper.framework/tc_helper</string>
10+
<key>LibraryIdentifier</key>
11+
<string>ios-arm64</string>
12+
<key>LibraryPath</key>
13+
<string>tc_helper.framework</string>
14+
<key>SupportedArchitectures</key>
15+
<array>
16+
<string>arm64</string>
17+
</array>
18+
<key>SupportedPlatform</key>
19+
<string>ios</string>
20+
</dict>
21+
<dict>
22+
<key>BinaryPath</key>
23+
<string>tc_helper.framework/tc_helper</string>
24+
<key>LibraryIdentifier</key>
25+
<string>ios-arm64_x86_64-simulator</string>
26+
<key>LibraryPath</key>
27+
<string>tc_helper.framework</string>
28+
<key>SupportedArchitectures</key>
29+
<array>
30+
<string>arm64</string>
31+
<string>x86_64</string>
32+
</array>
33+
<key>SupportedPlatform</key>
34+
<string>ios</string>
35+
<key>SupportedPlatformVariant</key>
36+
<string>simulator</string>
37+
</dict>
38+
</array>
39+
<key>CFBundlePackageType</key>
40+
<string>XFWK</string>
41+
<key>XCFrameworkFormatVersion</key>
42+
<string>1.0</string>
43+
</dict>
44+
</plist>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>CFBundleExecutable</key>
6+
<string>tc_helper</string>
7+
<key>CFBundleIdentifier</key>
8+
<string>com.ccextractor.taskwarriorflutter.tc-helper</string>
9+
<key>CFBundleInfoDictionaryVersion</key>
10+
<string>6.0</string>
11+
<key>CFBundlePackageType</key>
12+
<string>FMWK</string>
13+
<key>CFBundleSignature</key>
14+
<string>????</string>
15+
<key>CFBundleVersion</key>
16+
<string>1.0</string>
17+
<key>MinimumOSVersion</key>
18+
<string>13.0</string>
19+
</dict>
20+
</plist>
Binary file not shown.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>CFBundleExecutable</key>
6+
<string>tc_helper</string>
7+
<key>CFBundleIdentifier</key>
8+
<string>com.ccextractor.taskwarriorflutter.tc-helper</string>
9+
<key>CFBundleInfoDictionaryVersion</key>
10+
<string>6.0</string>
11+
<key>CFBundlePackageType</key>
12+
<string>FMWK</string>
13+
<key>CFBundleSignature</key>
14+
<string>????</string>
15+
<key>CFBundleVersion</key>
16+
<string>1.0</string>
17+
<key>MinimumOSVersion</key>
18+
<string>13.0</string>
19+
</dict>
20+
</plist>
Binary file not shown.

lib/main.dart

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import 'dart:ffi';
2-
2+
import 'dart:io';
33
import 'package:flutter/foundation.dart';
44
import 'package:flutter/material.dart';
55
import 'package:get/get.dart';
@@ -12,9 +12,17 @@ import 'app/routes/app_pages.dart';
1212

1313
LogDatabaseHelper _logDatabaseHelper = LogDatabaseHelper();
1414

15-
const buildOfTcHelperForAndroid = "libtc_helper.so";
16-
final dyLibOfTcHelperForAndroid =
17-
DynamicLibrary.open(buildOfTcHelperForAndroid);
15+
DynamicLibrary loadNativeLibrary() {
16+
if (Platform.isIOS) {
17+
return DynamicLibrary.open('Frameworks/tc_helper.framework/tc_helper');
18+
} else if (Platform.isAndroid) {
19+
return DynamicLibrary.open('libtc_helper.so');
20+
} else if (Platform.isMacOS) {
21+
return DynamicLibrary.open('tc_helper.framework/tc_helper');
22+
}
23+
throw UnsupportedError(
24+
'Platform ${Platform.operatingSystem} is not supported');
25+
}
1826

1927
void main() async {
2028
debugPrint = (String? message, {int? wrapWidth}) {
@@ -23,7 +31,7 @@ void main() async {
2331
_logDatabaseHelper.insertLog(message);
2432
}
2533
};
26-
34+
loadNativeLibrary();
2735
await RustLib.init();
2836

2937
WidgetsFlutterBinding.ensureInitialized();

0 commit comments

Comments
 (0)