@bobfrankston/msger 0.1.116 โ 0.1.117
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.
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/msger-native/build-pi.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { spawn } from 'child_process';
|
|
3
|
+
import { styleText } from 'node:util';
|
|
4
|
+
import dns from 'dns/promises';
|
|
3
5
|
import fs from 'fs';
|
|
4
6
|
import path from 'path';
|
|
5
7
|
import packageJson from '../package.json' with { type: 'json' };
|
|
@@ -8,21 +10,90 @@ import packageJson from '../package.json' with { type: 'json' };
|
|
|
8
10
|
const PI_HOST = 'pi4c'; // or 'pi@raspberrypi.local' or 'pi@192.168.1.xxx'
|
|
9
11
|
const PI_BUILD_DIR = '/tmp/msger-native-build';
|
|
10
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Run SSH command using spawn to avoid quoting issues
|
|
15
|
+
* @param args - Command arguments (e.g., ['pi4c', 'echo Connected'])
|
|
16
|
+
* @param options - Spawn options
|
|
17
|
+
* @returns Promise that resolves on success
|
|
18
|
+
*/
|
|
19
|
+
function ssh(...args: string[]): Promise<void> {
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
const proc = spawn('ssh', args, { stdio: 'inherit' });
|
|
22
|
+
proc.on('close', (code) => {
|
|
23
|
+
if (code === 0) {
|
|
24
|
+
resolve();
|
|
25
|
+
} else {
|
|
26
|
+
reject(new Error(`SSH command failed with code ${code}`));
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
proc.on('error', reject);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Run SCP command using spawn to avoid quoting issues
|
|
35
|
+
* @param args - Command arguments (e.g., ['file.txt', 'pi4c:/tmp/'])
|
|
36
|
+
* @param options - Spawn options
|
|
37
|
+
* @returns Promise that resolves on success
|
|
38
|
+
*/
|
|
39
|
+
function scp(...args: string[]): Promise<void> {
|
|
40
|
+
return new Promise((resolve, reject) => {
|
|
41
|
+
const proc = spawn('scp', args, { stdio: 'inherit' });
|
|
42
|
+
proc.on('close', (code) => {
|
|
43
|
+
if (code === 0) {
|
|
44
|
+
resolve();
|
|
45
|
+
} else {
|
|
46
|
+
reject(new Error(`SCP command failed with code ${code}`));
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
proc.on('error', reject);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Run SSH command and capture output
|
|
55
|
+
* @param args - Command arguments
|
|
56
|
+
* @returns Promise that resolves with stdout
|
|
57
|
+
*/
|
|
58
|
+
function sshCapture(...args: string[]): Promise<string> {
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
let stdout = '';
|
|
61
|
+
const proc = spawn('ssh', args, { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
62
|
+
proc.stdout.on('data', (data) => stdout += data.toString());
|
|
63
|
+
proc.on('close', (code) => {
|
|
64
|
+
if (code === 0) {
|
|
65
|
+
resolve(stdout);
|
|
66
|
+
} else {
|
|
67
|
+
reject(new Error(`SSH command failed with code ${code}`));
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
proc.on('error', reject);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
11
74
|
console.log('๐ฆพ Building ARM64 binary via SSH to Raspberry Pi...');
|
|
12
75
|
console.log(`๐ Target: ${PI_HOST}`);
|
|
13
76
|
|
|
77
|
+
// Debug: Test DNS resolution first
|
|
78
|
+
console.log('๐ Testing DNS resolution...');
|
|
79
|
+
try {
|
|
80
|
+
const result = await dns.lookup(PI_HOST);
|
|
81
|
+
console.log(`โ
DNS lookup successful: ${PI_HOST} -> ${result.address} (family: IPv${result.family})`);
|
|
82
|
+
} catch (error: any) {
|
|
83
|
+
console.log(`โ ๏ธ DNS lookup failed for ${PI_HOST}: ${error.message}`);
|
|
84
|
+
console.log(' Continuing anyway - SSH may have its own resolution...');
|
|
85
|
+
}
|
|
86
|
+
|
|
14
87
|
try {
|
|
15
88
|
// Test SSH connection
|
|
16
89
|
console.log('๐ Testing SSH connection...');
|
|
17
|
-
|
|
90
|
+
await sshCapture(PI_HOST, 'echo Connected');
|
|
18
91
|
console.log('โ
SSH connection successful');
|
|
19
92
|
} catch (error) {
|
|
20
93
|
// Yellow/orange banner for warning (not an error)
|
|
21
|
-
console.log(
|
|
22
|
-
console.log('
|
|
23
|
-
console.log('
|
|
24
|
-
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
25
|
-
console.log('\x1b[0m'); // Reset colors
|
|
94
|
+
console.log(styleText(['yellow', 'bold'], 'โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ'));
|
|
95
|
+
console.log(styleText(['yellow', 'bold'], 'โ โน๏ธ RASPBERRY PI NOT AVAILABLE - SKIPPING ARM64 BUILD โ'));
|
|
96
|
+
console.log(styleText(['yellow', 'bold'], 'โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ'));
|
|
26
97
|
console.log('');
|
|
27
98
|
console.log(`Cannot connect to Pi: ${PI_HOST}`);
|
|
28
99
|
console.log('To enable Pi builds:');
|
|
@@ -36,7 +107,7 @@ try {
|
|
|
36
107
|
|
|
37
108
|
// Create build directory on Pi
|
|
38
109
|
console.log('๐ Creating build directory on Pi...');
|
|
39
|
-
|
|
110
|
+
await ssh(PI_HOST, `mkdir -p ${PI_BUILD_DIR}/src`);
|
|
40
111
|
|
|
41
112
|
// Check if build is needed (compare source file mtimes with existing binary)
|
|
42
113
|
console.log('๐ Checking if build is needed...');
|
|
@@ -76,60 +147,52 @@ if (fs.existsSync(destPath)) {
|
|
|
76
147
|
|
|
77
148
|
// Copy source files to Pi
|
|
78
149
|
console.log('๐ค Copying source files to Pi...');
|
|
79
|
-
|
|
80
|
-
|
|
150
|
+
const origDir = process.cwd();
|
|
151
|
+
process.chdir(import.meta.dirname);
|
|
152
|
+
await scp('Cargo.toml', `${PI_HOST}:${PI_BUILD_DIR}/`);
|
|
153
|
+
await scp('-r', 'src/*', `${PI_HOST}:${PI_BUILD_DIR}/src/`);
|
|
154
|
+
process.chdir(origDir);
|
|
81
155
|
|
|
82
156
|
// Check for C compiler (gcc/cc) on Pi
|
|
83
157
|
console.log('๐ Checking for C compiler on Pi...');
|
|
84
158
|
try {
|
|
85
|
-
|
|
159
|
+
await sshCapture(PI_HOST, 'command -v gcc');
|
|
86
160
|
console.log('โ
C compiler found');
|
|
87
161
|
} catch {
|
|
88
|
-
console.log('
|
|
89
|
-
|
|
90
|
-
console.log('โ
build-essential installed');
|
|
162
|
+
console.log('โ ๏ธ C compiler not found - build will likely fail');
|
|
163
|
+
console.log(' To fix: ssh pi4c "sudo apt-get install -y build-essential"');
|
|
91
164
|
}
|
|
92
165
|
|
|
93
166
|
// Check for Rust on Pi
|
|
94
167
|
console.log('๐ Checking for Rust/Cargo on Pi...');
|
|
95
168
|
try {
|
|
96
|
-
|
|
169
|
+
await sshCapture(PI_HOST, 'source ~/.cargo/env 2>/dev/null; command -v cargo');
|
|
97
170
|
console.log('โ
Rust/Cargo found');
|
|
98
171
|
} catch {
|
|
99
|
-
console.log('
|
|
100
|
-
|
|
101
|
-
|
|
172
|
+
console.log('โ ๏ธ Rust not found - build will fail');
|
|
173
|
+
console.log(' To fix: ssh pi4c "curl --proto \'=https\' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y"');
|
|
174
|
+
process.exit(0);
|
|
102
175
|
}
|
|
103
176
|
|
|
104
177
|
// Ensure pkg-config is installed first (required to check for other dependencies)
|
|
105
178
|
console.log('๐ง Ensuring pkg-config is installed on Pi...');
|
|
106
179
|
try {
|
|
107
|
-
|
|
180
|
+
await sshCapture(PI_HOST, 'command -v pkg-config');
|
|
108
181
|
console.log('โ
pkg-config found');
|
|
109
182
|
} catch {
|
|
110
|
-
console.log('
|
|
111
|
-
|
|
112
|
-
console.log('โ
pkg-config installed');
|
|
183
|
+
console.log('โ ๏ธ pkg-config not found - build will likely fail');
|
|
184
|
+
console.log(' To fix: ssh pi4c "sudo apt-get install -y pkg-config"');
|
|
113
185
|
}
|
|
114
186
|
|
|
115
187
|
// Check for build dependencies on Pi
|
|
116
188
|
console.log('๐ Checking for build dependencies on Pi...');
|
|
117
189
|
try {
|
|
118
190
|
// Check for all required libraries: glib, gobject, gio, gtk, webkit
|
|
119
|
-
|
|
191
|
+
await sshCapture(PI_HOST, 'pkg-config --exists glib-2.0 gobject-2.0 gio-2.0 gtk+-3.0 && (pkg-config --exists webkit2gtk-4.1 || pkg-config --exists webkit2gtk-4.0)');
|
|
120
192
|
console.log('โ
Build dependencies found');
|
|
121
193
|
} catch {
|
|
122
|
-
console.log('
|
|
123
|
-
|
|
124
|
-
// Try webkit2gtk-4.1 first (newer), fallback to 4.0 if not available
|
|
125
|
-
try {
|
|
126
|
-
execSync(`ssh ${PI_HOST} "sudo apt-get install -y libglib2.0-dev libgtk-3-dev libwebkit2gtk-4.1-dev"`, { stdio: 'inherit' });
|
|
127
|
-
console.log('โ
Build dependencies installed (webkit2gtk-4.1)');
|
|
128
|
-
} catch {
|
|
129
|
-
console.log('โน๏ธ webkit2gtk-4.1 not available, trying 4.0...');
|
|
130
|
-
execSync(`ssh ${PI_HOST} "sudo apt-get install -y libglib2.0-dev libgtk-3-dev libwebkit2gtk-4.0-dev libsoup2.4-dev"`, { stdio: 'inherit' });
|
|
131
|
-
console.log('โ
Build dependencies installed (webkit2gtk-4.0)');
|
|
132
|
-
}
|
|
194
|
+
console.log('โ ๏ธ Build dependencies not found - build will likely fail');
|
|
195
|
+
console.log(' To fix: ssh pi4c "sudo apt-get install -y libglib2.0-dev libgtk-3-dev libwebkit2gtk-4.1-dev"');
|
|
133
196
|
}
|
|
134
197
|
|
|
135
198
|
// Get NPM version from imported package.json
|
|
@@ -138,20 +201,19 @@ console.log(`๐ Package version: ${npmVersion}`);
|
|
|
138
201
|
|
|
139
202
|
// Copy package.json to Pi (needed for version)
|
|
140
203
|
console.log('๐ค Copying package.json to Pi...');
|
|
141
|
-
|
|
204
|
+
process.chdir(import.meta.dirname);
|
|
205
|
+
await scp('package.json', `${PI_HOST}:${PI_BUILD_DIR}/`);
|
|
206
|
+
process.chdir(origDir);
|
|
142
207
|
|
|
143
208
|
// Build on Pi
|
|
144
209
|
console.log('\n๐ฆ Building ARM64 binary on Pi...');
|
|
145
210
|
try {
|
|
146
211
|
// Source cargo env and build (ensures cargo can find all its dependencies including cc)
|
|
147
212
|
// Export NPM_VERSION for Rust build
|
|
148
|
-
|
|
213
|
+
await ssh(PI_HOST, `cd ${PI_BUILD_DIR} && source ~/.cargo/env && export PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig && export NPM_VERSION=${npmVersion} && cargo build --release`);
|
|
149
214
|
console.log('โ
ARM64 build completed');
|
|
150
215
|
} catch (error: any) {
|
|
151
216
|
console.error('โ Pi build failed:');
|
|
152
|
-
console.error(error.stdout?.toString());
|
|
153
|
-
console.error(error.stderr?.toString());
|
|
154
|
-
console.error('');
|
|
155
217
|
console.error('โ ๏ธ Continuing without Pi binary...');
|
|
156
218
|
process.exit(0); // Exit gracefully to not break overall build
|
|
157
219
|
}
|
|
@@ -163,7 +225,7 @@ if (!fs.existsSync(destDir)) {
|
|
|
163
225
|
fs.mkdirSync(destDir, { recursive: true });
|
|
164
226
|
}
|
|
165
227
|
|
|
166
|
-
|
|
228
|
+
await scp(`${PI_HOST}:${PI_BUILD_DIR}/target/release/msgernative`, destPath);
|
|
167
229
|
|
|
168
230
|
// Set execute permissions
|
|
169
231
|
fs.chmodSync(destPath, 0o755);
|
|
@@ -175,6 +237,6 @@ console.log(`๐ Binary size: ${sizeMB} MB`);
|
|
|
175
237
|
|
|
176
238
|
// Cleanup on Pi
|
|
177
239
|
console.log('๐งน Cleaning up on Pi...');
|
|
178
|
-
|
|
240
|
+
await ssh(PI_HOST, `rm -rf ${PI_BUILD_DIR}`);
|
|
179
241
|
|
|
180
242
|
console.log('\n๐ ARM64 build process completed!');
|
package/msgernative-linux-x64
CHANGED
|
Binary file
|