@mcesystems/apple-kit 1.0.68 → 1.0.70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,258 +1,258 @@
1
- # @mcesystems/apple-kit
2
-
3
- iOS device management toolkit using libimobiledevice and go-ios command-line tools. We use both because they each provide capabilities that the other does not. The package provides app installation/uninstallation, port forwarding, activation, and device property access.
4
-
5
- ## Features
6
-
7
- - **App Management**: Install and uninstall iOS applications (.ipa files)
8
- - **Port Forwarding**: Forward local ports to device ports (for debugging, etc.)
9
- - **Device Activation**: Activate devices and skip setup steps
10
- - **Trust/Pairing**: Handle device trust and pairing
11
- - **Device Info**: Access device properties (name, model, iOS version, UDID, etc.)
12
- - **Profile Management**: List and remove configuration profiles
13
- - **Device Wipe**: Erase device data (factory reset)
14
- - **Cross-platform**: Works on Windows, macOS, and Linux
15
-
16
- ## Installation
17
-
18
- ```bash
19
- npm install @mcesystems/apple-kit
20
- ```
21
-
22
- ## Requirements
23
-
24
- - Node.js 18+
25
- - iOS device connected via USB
26
- - Device must be trusted/paired with the computer
27
- - libimobiledevice tools (idevice\*)
28
- - go-ios `ios` CLI binary
29
-
30
- ### Platform-specific Requirements
31
-
32
- #### Windows
33
- - libimobiledevice binaries - use the export script (see below)
34
- - go-ios `ios.exe` (see Resources section below)
35
- - iTunes installed OR Apple Mobile Device Support
36
-
37
- #### macOS
38
- **Option 1: Use bundled binaries (recommended for distribution)**
39
-
40
- Use the export script to bundle libimobiledevice for your application:
41
- ```bash
42
- # Using npx (after installing the package)
43
- npx export-apple-resources /path/to/your-app/resources/apple-kit
44
-
45
- # Or run the script directly
46
- npx tsx node_modules/@mcesystems/apple-kit/scripts/export-resources.ts /path/to/your-app/resources
47
- ```
48
-
49
- See [scripts/README.md](./scripts/README.md) for detailed prerequisites and instructions.
50
-
51
- **Option 2: Use Homebrew installation (for development)**
52
- - Install via Homebrew: `brew install libimobiledevice ideviceinstaller`
53
- - Tools are auto-detected from `/opt/homebrew/bin` (Apple Silicon) or `/usr/local/bin` (Intel)
54
-
55
- #### Linux
56
- - libimobiledevice-utils: `sudo apt install libimobiledevice-utils`
57
- - Tools are auto-detected from `/usr/bin` or `/usr/local/bin`
58
-
59
- ### Resources and Binary Resolution
60
-
61
- Set a resources directory once so both toolchains can be located:
62
-
63
- ```typescript
64
- import path from "node:path";
65
- import { AppleDeviceKit } from "@mcesystems/apple-kit";
66
-
67
- AppleDeviceKit.setResourcesDir(path.join(process.cwd(), "resources"));
68
- ```
69
-
70
- If you do not set a resources directory, make sure both toolchains are on your PATH.
71
-
72
- The package looks for tools in this order:
73
- 1. `resourcesDir/ios/bin/{platform}/` (go-ios `ios` and libimobiledevice tools)
74
- 2. Homebrew paths on macOS (`/opt/homebrew/bin`, `/usr/local/bin`)
75
- 3. System PATH (for global installations)
76
-
77
- ## Usage
78
-
79
- ### List Devices (go-ios)
80
-
81
- ```typescript
82
- import { createIosCli } from "@mcesystems/apple-kit";
83
-
84
- // Example: <resourcesDir>/ios/bin/{platform}/ios(.exe)
85
- const cli = createIosCli("path/to/ios");
86
- const list = await cli.listDevices();
87
- console.log(list.udids);
88
- ```
89
-
90
- ### Install/Uninstall Agent
91
-
92
- ```typescript
93
- import { AppleDeviceKit } from '@mcesystems/apple-kit';
94
-
95
- const device = new AppleDeviceKit('device-udid', 1);
96
-
97
- // Install app locally, then (if MDM is configured) take over management
98
- await device.installApp('/path/to/agent.ipa', {
99
- appId: 'com.example.agent',
100
- url: 'https://example.com/agent.ipa',
101
- waitForInstalled: true
102
- });
103
-
104
- // Check if installed
105
- const isInstalled = await device.isAppInstalled('com.example.agent');
106
-
107
- // List all installed apps
108
- const apps = await device.listApps();
109
-
110
- // Uninstall an agent/app
111
- await device.uninstallApp('com.example.agent');
112
- ```
113
-
114
- ### Device Info
115
-
116
- ```typescript
117
- const device = new AppleDeviceKit('device-udid', 1);
118
-
119
- const info = await device.info();
120
- console.log(`Device: ${info.DeviceName}`);
121
- console.log(`Model: ${info.ProductType}`);
122
- console.log(`iOS: ${info.ProductVersion} (${info.BuildVersion})`);
123
- console.log(`Serial: ${info.SerialNumber}`);
124
- console.log(`UDID: ${info.UniqueDeviceID}`);
125
- ```
126
-
127
- ### Trust/Pairing
128
-
129
- ```typescript
130
- const device = new AppleDeviceKit('device-udid', 1);
131
-
132
- // Check if device is trusted
133
- const isPaired = await device.isPaired();
134
-
135
- // Trust the device (initiates pairing and waits for user acceptance)
136
- await device.trustDevice(60000);
137
-
138
- // Unpair device
139
- await device.unpair();
140
- ```
141
-
142
- ### Port Forwarding
143
-
144
- ```typescript
145
- const device = new AppleDeviceKit('device-udid', 1);
146
-
147
- // Forward device port 8080 to a local port (auto-allocated)
148
- const forward = await device.startPortForwardAsync(8080);
149
- console.log(`Local port: ${forward.localPort}`);
150
-
151
- // Use the forwarded connection...
152
- // connect to localhost:8080 to reach device:8080
153
-
154
- // Stop forwarding when done
155
- device.closePortForward();
156
- ```
157
-
158
- ### Activation
159
-
160
- ```typescript
161
- const device = new AppleDeviceKit('device-udid', 1);
162
-
163
- // Get activation state
164
- const state = await device.getActivationState();
165
- console.log(`Activated: ${state.isActivated}`);
166
- console.log(`State: ${state.activationState}`);
167
-
168
- // Activate device (uses go-ios and MDM client)
169
- const cleanup = await device.activate();
170
- if (cleanup) {
171
- await cleanup(); // removes WiFi profile when done
172
- }
173
- ```
174
-
175
- The activation flow can install a WiFi profile based on environment variables:
176
- `WIFI_SSID`, `WIFI_PASSWORD`, `WIFI_ENCRYPTION`, `WIFI_HIDDEN`, `WIFI_ENTERPRISE`,
177
- `WIFI_USERNAME`, and `WIFI_EAP_TYPE`.
178
-
179
- ### Profiles
180
-
181
- ```typescript
182
- const device = new AppleDeviceKit('device-udid', 1);
183
-
184
- // List profiles
185
- const profiles = await device.listProfiles();
186
- console.log(profiles.profiles);
187
-
188
- // Remove a profile by identifier
189
- await device.removeProfile("com.example.profile");
190
- ```
191
-
192
- ### Wipe Device
193
-
194
- ```typescript
195
- const device = new AppleDeviceKit('device-udid', 1);
196
-
197
- // WARNING: this erases all data
198
- await device.wipe();
199
- ```
200
-
201
- ## API Reference
202
-
203
- ### AppleDeviceKit
204
-
205
- **Static methods:**
206
- - `setResourcesDir(dir)`: Configure resources location
207
-
208
- **Device Info:**
209
- - `info()`: Get device properties
210
- - `getDeviceId()`: Get the device UDID
211
- - `getLogicalPort()`: Get the logical port number
212
- - `getDevicePort()`: Get current local forwarded port (or null)
213
-
214
- **App Management:**
215
- - `installApp(ipaPath, options)`: Install IPA and take over via MDM if configured
216
- - `uninstallApp(bundleId)`: Uninstall an app by bundle ID
217
- - `isAppInstalled(bundleId)`: Check if app is installed
218
- - `listApps()`: List all installed user apps
219
-
220
- **Trust/Pairing:**
221
- - `isPaired()`: Check if device is paired/trusted
222
- - `pair()`: Initiate pairing (user must accept on device)
223
- - `trustDevice(timeout?, onWaiting?)`: Pair and wait for user acceptance
224
- - `unpair()`: Remove pairing/trust
225
- - `waitForPairing(timeout?, pollInterval?)`: Wait for device to be paired
226
-
227
- **Port Forwarding:**
228
- - `startPortForwardAsync(devicePort, startupTimeout?)`: Start and wait for ready
229
- - `closePortForward()`: Stop forwarding
230
-
231
- **Profiles:**
232
- - `listProfiles()`: List installed profiles
233
- - `removeProfile(identifier)`: Remove profile by identifier
234
-
235
- **Activation:**
236
- - `getActivationState()`: Get activation state
237
- - `activate()`: Activate the device (returns cleanup function)
238
-
239
- **Device Wipe:**
240
- - `wipe()`: Erase device data
241
-
242
- **Lifecycle:**
243
- - `dispose()`: Clean up resources and port forwards
244
-
245
- ### Types
246
-
247
- ```typescript
248
- interface ActivationState {
249
- isActivated: boolean;
250
- activationState: string;
251
- }
252
- ```
253
-
254
- ## License
255
-
256
- ISC
257
-
258
- libimobiledevice is licensed under LGPL-2.1.
1
+ # @mcesystems/apple-kit
2
+
3
+ iOS device management toolkit using libimobiledevice and go-ios command-line tools. We use both because they each provide capabilities that the other does not. The package provides app installation/uninstallation, port forwarding, activation, and device property access.
4
+
5
+ ## Features
6
+
7
+ - **App Management**: Install and uninstall iOS applications (.ipa files)
8
+ - **Port Forwarding**: Forward local ports to device ports (for debugging, etc.)
9
+ - **Device Activation**: Activate devices and skip setup steps
10
+ - **Trust/Pairing**: Handle device trust and pairing
11
+ - **Device Info**: Access device properties (name, model, iOS version, UDID, etc.)
12
+ - **Profile Management**: List and remove configuration profiles
13
+ - **Device Wipe**: Erase device data (factory reset)
14
+ - **Cross-platform**: Works on Windows, macOS, and Linux
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @mcesystems/apple-kit
20
+ ```
21
+
22
+ ## Requirements
23
+
24
+ - Node.js 18+
25
+ - iOS device connected via USB
26
+ - Device must be trusted/paired with the computer
27
+ - libimobiledevice tools (idevice\*)
28
+ - go-ios `ios` CLI binary
29
+
30
+ ### Platform-specific Requirements
31
+
32
+ #### Windows
33
+ - libimobiledevice binaries - use the export script (see below)
34
+ - go-ios `ios.exe` (see Resources section below)
35
+ - iTunes installed OR Apple Mobile Device Support
36
+
37
+ #### macOS
38
+ **Option 1: Use bundled binaries (recommended for distribution)**
39
+
40
+ Use the export script to bundle libimobiledevice for your application:
41
+ ```bash
42
+ # Using npx (after installing the package)
43
+ npx export-apple-resources /path/to/your-app/resources/apple-kit
44
+
45
+ # Or run the script directly
46
+ npx tsx node_modules/@mcesystems/apple-kit/scripts/export-resources.ts /path/to/your-app/resources
47
+ ```
48
+
49
+ See [scripts/README.md](./scripts/README.md) for detailed prerequisites and instructions.
50
+
51
+ **Option 2: Use Homebrew installation (for development)**
52
+ - Install via Homebrew: `brew install libimobiledevice ideviceinstaller`
53
+ - Tools are auto-detected from `/opt/homebrew/bin` (Apple Silicon) or `/usr/local/bin` (Intel)
54
+
55
+ #### Linux
56
+ - libimobiledevice-utils: `sudo apt install libimobiledevice-utils`
57
+ - Tools are auto-detected from `/usr/bin` or `/usr/local/bin`
58
+
59
+ ### Resources and Binary Resolution
60
+
61
+ Set a resources directory once so both toolchains can be located:
62
+
63
+ ```typescript
64
+ import path from "node:path";
65
+ import { AppleDeviceKit } from "@mcesystems/apple-kit";
66
+
67
+ AppleDeviceKit.setResourcesDir(path.join(process.cwd(), "resources"));
68
+ ```
69
+
70
+ If you do not set a resources directory, make sure both toolchains are on your PATH.
71
+
72
+ The package looks for tools in this order:
73
+ 1. `resourcesDir/ios/bin/{platform}/` (go-ios `ios` and libimobiledevice tools)
74
+ 2. Homebrew paths on macOS (`/opt/homebrew/bin`, `/usr/local/bin`)
75
+ 3. System PATH (for global installations)
76
+
77
+ ## Usage
78
+
79
+ ### List Devices (go-ios)
80
+
81
+ ```typescript
82
+ import { createIosCli } from "@mcesystems/apple-kit";
83
+
84
+ // Example: <resourcesDir>/ios/bin/{platform}/ios(.exe)
85
+ const cli = createIosCli("path/to/ios");
86
+ const list = await cli.listDevices();
87
+ console.log(list.udids);
88
+ ```
89
+
90
+ ### Install/Uninstall Agent
91
+
92
+ ```typescript
93
+ import { AppleDeviceKit } from '@mcesystems/apple-kit';
94
+
95
+ const device = new AppleDeviceKit('device-udid', 1);
96
+
97
+ // Install app locally, then (if MDM is configured) take over management
98
+ await device.installApp('/path/to/agent.ipa', {
99
+ appId: 'com.example.agent',
100
+ url: 'https://example.com/agent.ipa',
101
+ waitForInstalled: true
102
+ });
103
+
104
+ // Check if installed
105
+ const isInstalled = await device.isAppInstalled('com.example.agent');
106
+
107
+ // List all installed apps
108
+ const apps = await device.listApps();
109
+
110
+ // Uninstall an agent/app
111
+ await device.uninstallApp('com.example.agent');
112
+ ```
113
+
114
+ ### Device Info
115
+
116
+ ```typescript
117
+ const device = new AppleDeviceKit('device-udid', 1);
118
+
119
+ const info = await device.info();
120
+ console.log(`Device: ${info.DeviceName}`);
121
+ console.log(`Model: ${info.ProductType}`);
122
+ console.log(`iOS: ${info.ProductVersion} (${info.BuildVersion})`);
123
+ console.log(`Serial: ${info.SerialNumber}`);
124
+ console.log(`UDID: ${info.UniqueDeviceID}`);
125
+ ```
126
+
127
+ ### Trust/Pairing
128
+
129
+ ```typescript
130
+ const device = new AppleDeviceKit('device-udid', 1);
131
+
132
+ // Check if device is trusted
133
+ const isPaired = await device.isPaired();
134
+
135
+ // Trust the device (initiates pairing and waits for user acceptance)
136
+ await device.trustDevice(60000);
137
+
138
+ // Unpair device
139
+ await device.unpair();
140
+ ```
141
+
142
+ ### Port Forwarding
143
+
144
+ ```typescript
145
+ const device = new AppleDeviceKit('device-udid', 1);
146
+
147
+ // Forward device port 8080 to a local port (auto-allocated)
148
+ const forward = await device.startPortForwardAsync(8080);
149
+ console.log(`Local port: ${forward.localPort}`);
150
+
151
+ // Use the forwarded connection...
152
+ // connect to localhost:8080 to reach device:8080
153
+
154
+ // Stop forwarding when done
155
+ device.closePortForward();
156
+ ```
157
+
158
+ ### Activation
159
+
160
+ ```typescript
161
+ const device = new AppleDeviceKit('device-udid', 1);
162
+
163
+ // Get activation state
164
+ const state = await device.getActivationState();
165
+ console.log(`Activated: ${state.isActivated}`);
166
+ console.log(`State: ${state.activationState}`);
167
+
168
+ // Activate device (uses go-ios and MDM client)
169
+ const cleanup = await device.activate();
170
+ if (cleanup) {
171
+ await cleanup(); // removes WiFi profile when done
172
+ }
173
+ ```
174
+
175
+ The activation flow can install a WiFi profile based on environment variables:
176
+ `WIFI_SSID`, `WIFI_PASSWORD`, `WIFI_ENCRYPTION`, `WIFI_HIDDEN`, `WIFI_ENTERPRISE`,
177
+ `WIFI_USERNAME`, and `WIFI_EAP_TYPE`.
178
+
179
+ ### Profiles
180
+
181
+ ```typescript
182
+ const device = new AppleDeviceKit('device-udid', 1);
183
+
184
+ // List profiles
185
+ const profiles = await device.listProfiles();
186
+ console.log(profiles.profiles);
187
+
188
+ // Remove a profile by identifier
189
+ await device.removeProfile("com.example.profile");
190
+ ```
191
+
192
+ ### Wipe Device
193
+
194
+ ```typescript
195
+ const device = new AppleDeviceKit('device-udid', 1);
196
+
197
+ // WARNING: this erases all data
198
+ await device.wipe();
199
+ ```
200
+
201
+ ## API Reference
202
+
203
+ ### AppleDeviceKit
204
+
205
+ **Static methods:**
206
+ - `setResourcesDir(dir)`: Configure resources location
207
+
208
+ **Device Info:**
209
+ - `info()`: Get device properties
210
+ - `getDeviceId()`: Get the device UDID
211
+ - `getLogicalPort()`: Get the logical port number
212
+ - `getDevicePort()`: Get current local forwarded port (or null)
213
+
214
+ **App Management:**
215
+ - `installApp(ipaPath, options)`: Install IPA and take over via MDM if configured
216
+ - `uninstallApp(bundleId)`: Uninstall an app by bundle ID
217
+ - `isAppInstalled(bundleId)`: Check if app is installed
218
+ - `listApps()`: List all installed user apps
219
+
220
+ **Trust/Pairing:**
221
+ - `isPaired()`: Check if device is paired/trusted
222
+ - `pair()`: Initiate pairing (user must accept on device)
223
+ - `trustDevice(timeout?, onWaiting?)`: Pair and wait for user acceptance
224
+ - `unpair()`: Remove pairing/trust
225
+ - `waitForPairing(timeout?, pollInterval?)`: Wait for device to be paired
226
+
227
+ **Port Forwarding:**
228
+ - `startPortForwardAsync(devicePort, startupTimeout?)`: Start and wait for ready
229
+ - `closePortForward()`: Stop forwarding
230
+
231
+ **Profiles:**
232
+ - `listProfiles()`: List installed profiles
233
+ - `removeProfile(identifier)`: Remove profile by identifier
234
+
235
+ **Activation:**
236
+ - `getActivationState()`: Get activation state
237
+ - `activate()`: Activate the device (returns cleanup function)
238
+
239
+ **Device Wipe:**
240
+ - `wipe()`: Erase device data
241
+
242
+ **Lifecycle:**
243
+ - `dispose()`: Clean up resources and port forwards
244
+
245
+ ### Types
246
+
247
+ ```typescript
248
+ interface ActivationState {
249
+ isActivated: boolean;
250
+ activationState: string;
251
+ }
252
+ ```
253
+
254
+ ## License
255
+
256
+ ISC
257
+
258
+ libimobiledevice is licensed under LGPL-2.1.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcesystems/apple-kit",
3
- "version": "1.0.68",
3
+ "version": "1.0.70",
4
4
  "description": "iOS device management toolkit using libimobiledevice command-line tools",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -36,8 +36,8 @@
36
36
  "graphql": "^14.5.8",
37
37
  "graphql-request": "^5.2.0",
38
38
  "tsx": "^4.21.0",
39
- "@mcesystems/mdm-client-g4": "1.0.68",
40
- "@mcesystems/tool-debug-g4": "1.0.68"
39
+ "@mcesystems/tool-debug-g4": "1.0.70",
40
+ "@mcesystems/mdm-client-g4": "1.0.70"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/node": "^22.10.2",
@@ -46,6 +46,7 @@
46
46
  "esbuild": "^0.27.0",
47
47
  "esbuild-plugin-copy": "^2.1.1",
48
48
  "go-ios": "^1.0.188",
49
+ "pnpm": "10.24.0",
49
50
  "rimraf": "^6.0.1",
50
51
  "typescript": "^5.7.2",
51
52
  "vitest": "^2.1.8"
@@ -64,6 +65,7 @@
64
65
  },
65
66
  "scripts": {
66
67
  "build": "tsx esbuild.config.mts && tsc --emitDeclarationOnly",
68
+ "build:all": "pnpm --filter @mcesystems/apple-kit... build",
67
69
  "clean": "rimraf dist",
68
70
  "check:types": "tsc --noEmit",
69
71
  "activate:example": "tsx src/examples/activationExample.ts",
@@ -1,222 +1,222 @@
1
- #!/bin/bash
2
- # =============================================================================
3
- # libimobiledevice Windows Build Script
4
- # =============================================================================
5
- #
6
- # This script builds libimobiledevice and related tools from source using
7
- # MSYS2/MinGW environment.
8
- #
9
- # Prerequisites:
10
- # 1. MSYS2 installed (https://www.msys2.org/)
11
- # 2. Run this script from MSYS2 MinGW 64-bit shell
12
- # 3. Required packages installed (see below)
13
- #
14
- # To install required packages, run in MSYS2 MinGW 64-bit shell:
15
- # pacman -S base-devel git mingw-w64-x86_64-gcc make libtool autoconf automake-wrapper
16
- #
17
- # Usage:
18
- # bash build-windows.sh
19
- #
20
- # =============================================================================
21
-
22
- set -e
23
-
24
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
25
- TARGET_DIR="{{TARGET_DIR}}"
26
- BUILD_DIR="$SCRIPT_DIR/limd-build"
27
-
28
- echo "=== libimobiledevice Windows Build ==="
29
- echo ""
30
- echo "Target directory: $TARGET_DIR"
31
- echo "Build directory: $BUILD_DIR"
32
- echo ""
33
-
34
- # Check if running in MinGW environment
35
- if [[ -z "$MSYSTEM" ]] || [[ "$MSYSTEM" != "MINGW64" ]]; then
36
- echo "Error: This script must be run from MSYS2 MinGW 64-bit shell"
37
- echo "Open 'MSYS2 MinGW 64-bit' from Start menu and run this script again."
38
- exit 1
39
- fi
40
-
41
- # Check for required tools
42
- echo "Checking prerequisites..."
43
- for cmd in gcc make git autoconf automake libtool; do
44
- if ! command -v $cmd &> /dev/null; then
45
- echo "Error: $cmd not found. Please install required packages:"
46
- echo " pacman -S base-devel git mingw-w64-x86_64-gcc make libtool autoconf automake-wrapper"
47
- exit 1
48
- fi
49
- done
50
- echo "✓ All prerequisites found"
51
- echo ""
52
-
53
- # Create build directory
54
- mkdir -p "$BUILD_DIR"
55
- cd "$BUILD_DIR"
56
-
57
- # Download and run the official build script
58
- echo "Downloading libimobiledevice build script..."
59
- curl -Ls -o limd-build-msys2.sh https://is.gd/limdmsys2
60
-
61
- echo ""
62
- echo "Running libimobiledevice build script..."
63
- echo "(This may take 10-30 minutes depending on your system)"
64
- echo ""
65
-
66
- bash ./limd-build-msys2.sh
67
-
68
- # After build, copy the binaries to target directory
69
- echo ""
70
- echo "Copying binaries to target directory..."
71
-
72
- mkdir -p "$TARGET_DIR"
73
-
74
- # The build script installs to /mingw64 by default
75
- MINGW_BIN="/mingw64/bin"
76
-
77
- TOOLS=(
78
- "idevice_id.exe"
79
- "ideviceinfo.exe"
80
- "idevicepair.exe"
81
- "idevicename.exe"
82
- "idevicedebug.exe"
83
- "ideviceinstaller.exe"
84
- "iproxy.exe"
85
- "ideviceactivation.exe"
86
- "idevicesyslog.exe"
87
- "idevicescreenshot.exe"
88
- "idevicediagnostics.exe"
89
- "idevicerestore.exe"
90
- )
91
-
92
- for tool in "${TOOLS[@]}"; do
93
- if [[ -f "$MINGW_BIN/$tool" ]]; then
94
- cp "$MINGW_BIN/$tool" "$TARGET_DIR/"
95
- echo "✓ Copied $tool"
96
- else
97
- echo "- Skipping $tool (not found)"
98
- fi
99
- done
100
-
101
- # Copy required DLLs by discovering dependencies
102
- echo ""
103
- echo "Discovering and copying required DLLs..."
104
-
105
- # Function to recursively find all DLL dependencies
106
- find_dll_deps() {
107
- local file="$1"
108
- ldd "$file" 2>/dev/null | grep '/mingw64' | awk '{print $3}' | sort -u
109
- }
110
-
111
- # Collect all unique DLLs needed by all tools
112
- ALL_DLLS=""
113
- for tool in "${TOOLS[@]}"; do
114
- if [[ -f "$TARGET_DIR/$tool" ]]; then
115
- TOOL_DLLS=$(find_dll_deps "$TARGET_DIR/$tool")
116
- ALL_DLLS="$ALL_DLLS $TOOL_DLLS"
117
- fi
118
- done
119
-
120
- # Also check dependencies of the DLLs themselves (transitive deps)
121
- # Do multiple passes to ensure we get all nested dependencies
122
- for pass in {1..3}; do
123
- for dll_path in $ALL_DLLS; do
124
- if [[ -f "$dll_path" ]]; then
125
- NESTED_DLLS=$(find_dll_deps "$dll_path")
126
- ALL_DLLS="$ALL_DLLS $NESTED_DLLS"
127
- fi
128
- done
129
- done
130
-
131
- # Get unique list
132
- UNIQUE_DLLS=$(echo "$ALL_DLLS" | tr ' ' '\n' | sort -u | grep -v '^$')
133
-
134
- # Copy each DLL
135
- for dll_path in $UNIQUE_DLLS; do
136
- if [[ -f "$dll_path" ]]; then
137
- dll_name=$(basename "$dll_path")
138
- cp "$dll_path" "$TARGET_DIR/"
139
- echo "✓ Copied $dll_name"
140
- fi
141
- done
142
-
143
- # Specifically check for idevicerestore dependencies (libirecovery, libidevicerestore)
144
- if [[ -f "$TARGET_DIR/idevicerestore.exe" ]]; then
145
- echo ""
146
- echo "Checking idevicerestore-specific dependencies..."
147
-
148
- # Look for libirecovery and libidevicerestore DLLs
149
- IRECOVERY_DLLS=$(find "$MINGW_BIN" -name "libirecovery*.dll" 2>/dev/null || true)
150
- IDEVICERESTORE_DLLS=$(find "$MINGW_BIN" -name "libidevicerestore*.dll" 2>/dev/null || true)
151
-
152
- for dll in $IRECOVERY_DLLS $IDEVICERESTORE_DLLS; do
153
- if [[ -f "$dll" ]]; then
154
- dll_name=$(basename "$dll")
155
- if [[ ! -f "$TARGET_DIR/$dll_name" ]]; then
156
- cp "$dll" "$TARGET_DIR/"
157
- echo "✓ Copied $dll_name (idevicerestore dependency)"
158
- fi
159
- fi
160
- done
161
- fi
162
-
163
- # Explicitly copy all libimobiledevice core libraries
164
- echo ""
165
- echo "Copying libimobiledevice core libraries..."
166
- CORE_LIBS=(
167
- "libimobiledevice-1.0.dll"
168
- "libimobiledevice-glue-1.0.dll"
169
- "libusbmuxd-2.0.dll"
170
- "libplist-2.0.dll"
171
- "libirecovery-1.0.dll"
172
- "libidevicerestore-1.0.dll"
173
- "libideviceactivation-1.0.dll"
174
- )
175
-
176
- for lib in "${CORE_LIBS[@]}"; do
177
- if [[ -f "$MINGW_BIN/$lib" ]] && [[ ! -f "$TARGET_DIR/$lib" ]]; then
178
- cp "$MINGW_BIN/$lib" "$TARGET_DIR/"
179
- echo "✓ Copied $lib (core library)"
180
- fi
181
- done
182
-
183
- # Also copy these common runtime DLLs that might not show up in ldd
184
- RUNTIME_DLLS=(
185
- "libgcc_s_seh-1.dll"
186
- "libwinpthread-1.dll"
187
- "libstdc++-6.dll"
188
- "libssl-3-x64.dll"
189
- "libcrypto-3-x64.dll"
190
- "liblzma-5.dll"
191
- "libzstd.dll"
192
- "zlib1.dll"
193
- )
194
-
195
- echo ""
196
- echo "Copying runtime DLLs..."
197
- for dll in "${RUNTIME_DLLS[@]}"; do
198
- if [[ -f "$MINGW_BIN/$dll" ]] && [[ ! -f "$TARGET_DIR/$dll" ]]; then
199
- cp "$MINGW_BIN/$dll" "$TARGET_DIR/"
200
- echo "✓ Copied $dll"
201
- fi
202
- done
203
-
204
- # List all DLLs that were copied for verification
205
- echo ""
206
- echo "=== Summary of copied libraries ==="
207
- echo "Core libimobiledevice libraries:"
208
- for lib in "${CORE_LIBS[@]}"; do
209
- if [[ -f "$TARGET_DIR/$lib" ]]; then
210
- echo " ✓ $lib"
211
- else
212
- echo " ✗ $lib (missing)"
213
- fi
214
- done
215
-
216
- echo ""
217
- echo "=== Build Complete ==="
218
- echo "Windows binaries exported to: $TARGET_DIR"
219
- echo ""
220
- echo "Note: On Windows, iTunes or Apple Mobile Device Support must be installed"
221
- echo "for USB communication to work."
222
-
1
+ #!/bin/bash
2
+ # =============================================================================
3
+ # libimobiledevice Windows Build Script
4
+ # =============================================================================
5
+ #
6
+ # This script builds libimobiledevice and related tools from source using
7
+ # MSYS2/MinGW environment.
8
+ #
9
+ # Prerequisites:
10
+ # 1. MSYS2 installed (https://www.msys2.org/)
11
+ # 2. Run this script from MSYS2 MinGW 64-bit shell
12
+ # 3. Required packages installed (see below)
13
+ #
14
+ # To install required packages, run in MSYS2 MinGW 64-bit shell:
15
+ # pacman -S base-devel git mingw-w64-x86_64-gcc make libtool autoconf automake-wrapper
16
+ #
17
+ # Usage:
18
+ # bash build-windows.sh
19
+ #
20
+ # =============================================================================
21
+
22
+ set -e
23
+
24
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
25
+ TARGET_DIR="{{TARGET_DIR}}"
26
+ BUILD_DIR="$SCRIPT_DIR/limd-build"
27
+
28
+ echo "=== libimobiledevice Windows Build ==="
29
+ echo ""
30
+ echo "Target directory: $TARGET_DIR"
31
+ echo "Build directory: $BUILD_DIR"
32
+ echo ""
33
+
34
+ # Check if running in MinGW environment
35
+ if [[ -z "$MSYSTEM" ]] || [[ "$MSYSTEM" != "MINGW64" ]]; then
36
+ echo "Error: This script must be run from MSYS2 MinGW 64-bit shell"
37
+ echo "Open 'MSYS2 MinGW 64-bit' from Start menu and run this script again."
38
+ exit 1
39
+ fi
40
+
41
+ # Check for required tools
42
+ echo "Checking prerequisites..."
43
+ for cmd in gcc make git autoconf automake libtool; do
44
+ if ! command -v $cmd &> /dev/null; then
45
+ echo "Error: $cmd not found. Please install required packages:"
46
+ echo " pacman -S base-devel git mingw-w64-x86_64-gcc make libtool autoconf automake-wrapper"
47
+ exit 1
48
+ fi
49
+ done
50
+ echo "✓ All prerequisites found"
51
+ echo ""
52
+
53
+ # Create build directory
54
+ mkdir -p "$BUILD_DIR"
55
+ cd "$BUILD_DIR"
56
+
57
+ # Download and run the official build script
58
+ echo "Downloading libimobiledevice build script..."
59
+ curl -Ls -o limd-build-msys2.sh https://is.gd/limdmsys2
60
+
61
+ echo ""
62
+ echo "Running libimobiledevice build script..."
63
+ echo "(This may take 10-30 minutes depending on your system)"
64
+ echo ""
65
+
66
+ bash ./limd-build-msys2.sh
67
+
68
+ # After build, copy the binaries to target directory
69
+ echo ""
70
+ echo "Copying binaries to target directory..."
71
+
72
+ mkdir -p "$TARGET_DIR"
73
+
74
+ # The build script installs to /mingw64 by default
75
+ MINGW_BIN="/mingw64/bin"
76
+
77
+ TOOLS=(
78
+ "idevice_id.exe"
79
+ "ideviceinfo.exe"
80
+ "idevicepair.exe"
81
+ "idevicename.exe"
82
+ "idevicedebug.exe"
83
+ "ideviceinstaller.exe"
84
+ "iproxy.exe"
85
+ "ideviceactivation.exe"
86
+ "idevicesyslog.exe"
87
+ "idevicescreenshot.exe"
88
+ "idevicediagnostics.exe"
89
+ "idevicerestore.exe"
90
+ )
91
+
92
+ for tool in "${TOOLS[@]}"; do
93
+ if [[ -f "$MINGW_BIN/$tool" ]]; then
94
+ cp "$MINGW_BIN/$tool" "$TARGET_DIR/"
95
+ echo "✓ Copied $tool"
96
+ else
97
+ echo "- Skipping $tool (not found)"
98
+ fi
99
+ done
100
+
101
+ # Copy required DLLs by discovering dependencies
102
+ echo ""
103
+ echo "Discovering and copying required DLLs..."
104
+
105
+ # Function to recursively find all DLL dependencies
106
+ find_dll_deps() {
107
+ local file="$1"
108
+ ldd "$file" 2>/dev/null | grep '/mingw64' | awk '{print $3}' | sort -u
109
+ }
110
+
111
+ # Collect all unique DLLs needed by all tools
112
+ ALL_DLLS=""
113
+ for tool in "${TOOLS[@]}"; do
114
+ if [[ -f "$TARGET_DIR/$tool" ]]; then
115
+ TOOL_DLLS=$(find_dll_deps "$TARGET_DIR/$tool")
116
+ ALL_DLLS="$ALL_DLLS $TOOL_DLLS"
117
+ fi
118
+ done
119
+
120
+ # Also check dependencies of the DLLs themselves (transitive deps)
121
+ # Do multiple passes to ensure we get all nested dependencies
122
+ for pass in {1..3}; do
123
+ for dll_path in $ALL_DLLS; do
124
+ if [[ -f "$dll_path" ]]; then
125
+ NESTED_DLLS=$(find_dll_deps "$dll_path")
126
+ ALL_DLLS="$ALL_DLLS $NESTED_DLLS"
127
+ fi
128
+ done
129
+ done
130
+
131
+ # Get unique list
132
+ UNIQUE_DLLS=$(echo "$ALL_DLLS" | tr ' ' '\n' | sort -u | grep -v '^$')
133
+
134
+ # Copy each DLL
135
+ for dll_path in $UNIQUE_DLLS; do
136
+ if [[ -f "$dll_path" ]]; then
137
+ dll_name=$(basename "$dll_path")
138
+ cp "$dll_path" "$TARGET_DIR/"
139
+ echo "✓ Copied $dll_name"
140
+ fi
141
+ done
142
+
143
+ # Specifically check for idevicerestore dependencies (libirecovery, libidevicerestore)
144
+ if [[ -f "$TARGET_DIR/idevicerestore.exe" ]]; then
145
+ echo ""
146
+ echo "Checking idevicerestore-specific dependencies..."
147
+
148
+ # Look for libirecovery and libidevicerestore DLLs
149
+ IRECOVERY_DLLS=$(find "$MINGW_BIN" -name "libirecovery*.dll" 2>/dev/null || true)
150
+ IDEVICERESTORE_DLLS=$(find "$MINGW_BIN" -name "libidevicerestore*.dll" 2>/dev/null || true)
151
+
152
+ for dll in $IRECOVERY_DLLS $IDEVICERESTORE_DLLS; do
153
+ if [[ -f "$dll" ]]; then
154
+ dll_name=$(basename "$dll")
155
+ if [[ ! -f "$TARGET_DIR/$dll_name" ]]; then
156
+ cp "$dll" "$TARGET_DIR/"
157
+ echo "✓ Copied $dll_name (idevicerestore dependency)"
158
+ fi
159
+ fi
160
+ done
161
+ fi
162
+
163
+ # Explicitly copy all libimobiledevice core libraries
164
+ echo ""
165
+ echo "Copying libimobiledevice core libraries..."
166
+ CORE_LIBS=(
167
+ "libimobiledevice-1.0.dll"
168
+ "libimobiledevice-glue-1.0.dll"
169
+ "libusbmuxd-2.0.dll"
170
+ "libplist-2.0.dll"
171
+ "libirecovery-1.0.dll"
172
+ "libidevicerestore-1.0.dll"
173
+ "libideviceactivation-1.0.dll"
174
+ )
175
+
176
+ for lib in "${CORE_LIBS[@]}"; do
177
+ if [[ -f "$MINGW_BIN/$lib" ]] && [[ ! -f "$TARGET_DIR/$lib" ]]; then
178
+ cp "$MINGW_BIN/$lib" "$TARGET_DIR/"
179
+ echo "✓ Copied $lib (core library)"
180
+ fi
181
+ done
182
+
183
+ # Also copy these common runtime DLLs that might not show up in ldd
184
+ RUNTIME_DLLS=(
185
+ "libgcc_s_seh-1.dll"
186
+ "libwinpthread-1.dll"
187
+ "libstdc++-6.dll"
188
+ "libssl-3-x64.dll"
189
+ "libcrypto-3-x64.dll"
190
+ "liblzma-5.dll"
191
+ "libzstd.dll"
192
+ "zlib1.dll"
193
+ )
194
+
195
+ echo ""
196
+ echo "Copying runtime DLLs..."
197
+ for dll in "${RUNTIME_DLLS[@]}"; do
198
+ if [[ -f "$MINGW_BIN/$dll" ]] && [[ ! -f "$TARGET_DIR/$dll" ]]; then
199
+ cp "$MINGW_BIN/$dll" "$TARGET_DIR/"
200
+ echo "✓ Copied $dll"
201
+ fi
202
+ done
203
+
204
+ # List all DLLs that were copied for verification
205
+ echo ""
206
+ echo "=== Summary of copied libraries ==="
207
+ echo "Core libimobiledevice libraries:"
208
+ for lib in "${CORE_LIBS[@]}"; do
209
+ if [[ -f "$TARGET_DIR/$lib" ]]; then
210
+ echo " ✓ $lib"
211
+ else
212
+ echo " ✗ $lib (missing)"
213
+ fi
214
+ done
215
+
216
+ echo ""
217
+ echo "=== Build Complete ==="
218
+ echo "Windows binaries exported to: $TARGET_DIR"
219
+ echo ""
220
+ echo "Note: On Windows, iTunes or Apple Mobile Device Support must be installed"
221
+ echo "for USB communication to work."
222
+