plusui-native-builder 0.1.0

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.
Files changed (2) hide show
  1. package/package.json +21 -0
  2. package/src/index.js +230 -0
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "plusui-native-builder",
3
+ "version": "0.1.0",
4
+ "description": "Multi-platform build tool for PlusUI projeplusui",
5
+ "main": "src/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "plusui-builder": "./src/index.js"
9
+ },
10
+ "scripts": {
11
+ "start": "node src/index.js",
12
+ "build": "node src/index.js",
13
+ "build:win32": "node src/index.js win32",
14
+ "build:all": "node src/index.js all"
15
+ },
16
+ "keywords": ["plusui", "build", "multiplatform", "android", "ios", "windows", "macos", "linux"],
17
+ "license": "MIT",
18
+ "dependencies": {
19
+ "plusui-native-bindgen": "*"
20
+ }
21
+ }
package/src/index.js ADDED
@@ -0,0 +1,230 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execSync, spawn } from 'child_process';
4
+ import { existsSync, mkdirSync } from 'fs';
5
+ import { join, dirname } from 'path';
6
+ import { fileURLToPath } from 'url';
7
+
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = dirname(__filename);
10
+
11
+ const COLORS = {
12
+ reset: '\x1b[0m',
13
+ bright: '\x1b[1m',
14
+ green: '\x1b[32m',
15
+ blue: '\x1b[34m',
16
+ yellow: '\x1b[33m',
17
+ red: '\x1b[31m',
18
+ };
19
+
20
+ function log(msg, color = 'reset') {
21
+ console.log(`${COLORS[color]}${msg}${COLORS.reset}`);
22
+ }
23
+
24
+ function error(msg) {
25
+ console.error(`${COLORS.red}Error: ${msg}${COLORS.reset}`);
26
+ process.exit(1);
27
+ }
28
+
29
+ const USAGE = `
30
+ PlusUI Builder - Multi-platform build tool
31
+
32
+ Usage:
33
+ plusui-builder Build for current platform
34
+ plusui-builder <platform> Build for specific platform
35
+ plusui-builder all Build for all platforms
36
+ plusui-builder generate Generate bindings only
37
+
38
+ Platforms:
39
+ win32 - Windows (x64)
40
+ macos - macOS (x64, arm64)
41
+ linux - Linux (x64)
42
+ android - Android (arm64-v8a, armeabi-v7a, x86, x86_64)
43
+ ios - iOS (simulator, device)
44
+
45
+ Options:
46
+ -h, --help Show this help
47
+ -v, --version Show version
48
+ `;
49
+
50
+ const PLATFORMS = {
51
+ win32: { name: 'Windows', ext: '.exe', arch: ['x64'] },
52
+ macos: { name: 'macOS', ext: '', arch: ['x64', 'arm64'] },
53
+ linux: { name: 'Linux', ext: '', arch: ['x64'] },
54
+ android: { name: 'Android', ext: '.so', arch: ['arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64'] },
55
+ ios: { name: 'iOS', ext: '.app', arch: ['simulator', 'device'] },
56
+ };
57
+
58
+ function runCommand(cmd, options = {}) {
59
+ const { cwd = process.cwd(), env = process.env, fatal = true } = options;
60
+ try {
61
+ execSync(cmd, { cwd, env, stdio: 'inherit' });
62
+ return true;
63
+ } catch (e) {
64
+ if (fatal) error(`Command failed: ${cmd}`);
65
+ return false;
66
+ }
67
+ }
68
+
69
+ function generateBindings() {
70
+ log('Generating bindings...', 'blue');
71
+ let bindgenPath = join(__dirname, '..', '..', 'plusui-bindgen', 'src', 'index.js');
72
+ if (!existsSync(bindgenPath)) {
73
+ // Try installed location (node_modules/@plusui-native/bindgen)
74
+ bindgenPath = join(__dirname, '..', '..', '@plusui-native', 'bindgen', 'src', 'index.js');
75
+ }
76
+
77
+ if (!existsSync(bindgenPath)) {
78
+ error('plusui-bindgen not found. Please ensure @plusui-native/bindgen is installed.');
79
+ }
80
+
81
+ runCommand(`node ${bindgenPath} ./src/services ./src`);
82
+ log('Bindings generated āœ“', 'green');
83
+ }
84
+
85
+ function getCMakePlatformArgs(platform) {
86
+ const args = [];
87
+
88
+ switch (platform) {
89
+ case 'win32':
90
+ break;
91
+ case 'macos':
92
+ args.push('-G', 'Xcode');
93
+ break;
94
+ case 'linux':
95
+ args.push('-G', 'Ninja');
96
+ break;
97
+ case 'android':
98
+ const sdkRoot = process.env.ANDROID_SDK_ROOT || process.env.ANDROID_HOME;
99
+ if (!sdkRoot) {
100
+ error('ANDROID_SDK_ROOT or ANDROID_HOME not set');
101
+ }
102
+ args.push('-G', 'Ninja');
103
+ args.push('-DCMAKE_TOOLCHAIN_FILE=' + join(sdkRoot, 'build-tools', 'cmake', 'android.toolchain.cmake'));
104
+ args.push('-DANDROID_NATIVE_API_LEVEL=24');
105
+ break;
106
+ case 'ios':
107
+ args.push('-G', 'Xcode');
108
+ args.push('-DCMAKE_SYSTEM_NAME=iOS');
109
+ break;
110
+ }
111
+
112
+ return args;
113
+ }
114
+
115
+ function findCMakeLists() {
116
+ const root = process.cwd();
117
+ if (existsSync(join(root, 'CMakeLists.txt'))) {
118
+ return root;
119
+ }
120
+ const subdirs = ['.', 'src', 'app', 'core'];
121
+ for (const dir of subdirs) {
122
+ const path = join(root, dir, 'CMakeLists.txt');
123
+ if (existsSync(path)) {
124
+ return join(root, dir);
125
+ }
126
+ }
127
+ error('CMakeLists.txt not found. Run from a PlusUI project directory.');
128
+ }
129
+
130
+ function buildPlatform(platform, arch = null) {
131
+ const cfg = PLATFORMS[platform];
132
+ if (!cfg) {
133
+ error(`Unknown platform: ${platform}`);
134
+ }
135
+
136
+ const sourceDir = findCMakeLists();
137
+ const archs = arch ? [arch] : cfg.arch;
138
+
139
+ for (const targetArch of archs) {
140
+ log(`Building ${cfg.name} (${targetArch})...`, 'blue');
141
+
142
+ const buildDir = join(sourceDir, 'build', platform, targetArch);
143
+ mkdirSync(buildDir, { recursive: true });
144
+
145
+ const cmakeArgs = ['-S' + sourceDir, `-B${buildDir}`, '-DCMAKE_BUILD_TYPE=Release'];
146
+ cmakeArgs.push(...getCMakePlatformArgs(platform));
147
+
148
+ if (platform === 'android') {
149
+ cmakeArgs.push(`-DANDROID_ABI=${targetArch}`);
150
+ }
151
+
152
+ const cmakeCmd = 'cmake ' + cmakeArgs.join(' ');
153
+ runCommand(cmakeCmd);
154
+ runCommand(`cmake --build ${buildDir} --config Release`);
155
+
156
+ log(`Built ${cfg.name} (${targetArch}) āœ“`, 'green');
157
+ }
158
+ }
159
+
160
+ function buildCurrentPlatform() {
161
+ const platform = process.platform;
162
+ const platformMap = { 'win32': 'win32', 'darwin': 'macos', 'linux': 'linux' };
163
+ const targetPlatform = platformMap[platform];
164
+
165
+ if (targetPlatform) {
166
+ buildPlatform(targetPlatform);
167
+ } else {
168
+ error(`Unsupported platform: ${platform}`);
169
+ }
170
+ }
171
+
172
+ function buildAll() {
173
+ generateBindings();
174
+
175
+ for (const platform of Object.keys(PLATFORMS)) {
176
+ log(`\n=== Building for ${PLATFORMS[platform].name} ===`, 'yellow');
177
+ buildPlatform(platform);
178
+ }
179
+
180
+ log('\nāœ“ All builds complete!', 'green');
181
+ }
182
+
183
+ function main() {
184
+ const args = process.argv.slice(2);
185
+ const cmd = args[0];
186
+
187
+ switch (cmd) {
188
+ case 'generate':
189
+ case 'gen':
190
+ generateBindings();
191
+ break;
192
+ case 'all':
193
+ buildAll();
194
+ break;
195
+ case 'win32':
196
+ case 'windows':
197
+ generateBindings();
198
+ buildPlatform('win32');
199
+ break;
200
+ case 'macos':
201
+ generateBindings();
202
+ buildPlatform('macos');
203
+ break;
204
+ case 'linux':
205
+ generateBindings();
206
+ buildPlatform('linux');
207
+ break;
208
+ case 'android':
209
+ generateBindings();
210
+ buildPlatform('android');
211
+ break;
212
+ case 'ios':
213
+ generateBindings();
214
+ buildPlatform('ios');
215
+ break;
216
+ case '-h':
217
+ case '--help':
218
+ console.log(USAGE);
219
+ break;
220
+ case '-v':
221
+ case '--version':
222
+ console.log('plusui-builder v0.1.0');
223
+ break;
224
+ default:
225
+ generateBindings();
226
+ buildCurrentPlatform();
227
+ }
228
+ }
229
+
230
+ main();