cpp.js 1.0.0-beta.25 → 1.0.0-beta.27
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/package.json +1 -1
- package/src/actions/buildJs.js +0 -1
- package/src/actions/buildWasm.js +2 -2
- package/src/actions/createInterface.js +4 -5
- package/src/actions/createLib.js +4 -3
- package/src/actions/createXCFramework.js +20 -16
- package/src/actions/getCmakeParameters.js +6 -0
- package/src/actions/run.js +60 -57
- package/src/assets/CMakeLists.txt +1 -1
- package/src/assets/bridge.cpp +17 -0
- package/src/assets/cppjsemptysource.cpp +0 -0
- package/src/bin.js +138 -56
- package/src/integration/getCppJsScript.js +1 -1
- package/src/integration/getDependFilePath.js +16 -4
- package/src/state/index.js +2 -2
- package/src/state/loadConfig.js +8 -1
- package/src/utils/downloadAndExtractFile.js +2 -2
- package/src/utils/getOsUserAndGroupId.js +1 -1
- package/src/utils/getParentPath.js +1 -1
- package/src/utils/hash.js +2 -2
- package/src/utils/loadJs.js +1 -1
- package/src/utils/loadJson.js +1 -1
- package/src/utils/pullDockerImage.js +2 -2
- package/src/utils/systemKeys.js +18 -0
- package/src/utils/writeJson.js +1 -1
package/package.json
CHANGED
package/src/actions/buildJs.js
CHANGED
package/src/actions/buildWasm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
1
|
+
import fs from 'node:fs';
|
|
2
2
|
import run from './run.js';
|
|
3
3
|
import getDependLibs from './getDependLibs.js';
|
|
4
4
|
import getData from './getData.js';
|
|
@@ -8,7 +8,7 @@ import state from '../state/index.js';
|
|
|
8
8
|
export default async function buildWasm(type, isProd = false) {
|
|
9
9
|
const buildType = isProd ? 'Release' : 'Debug';
|
|
10
10
|
const libs = [
|
|
11
|
-
getDependLibs(),
|
|
11
|
+
...getDependLibs(),
|
|
12
12
|
`${state.config.paths.build}/Source-${buildType}/Emscripten-x86_64/lib${state.config.general.name}.a`,
|
|
13
13
|
`${state.config.paths.build}/Bridge-${buildType}/Emscripten-x86_64/lib${state.config.general.name}.a`,
|
|
14
14
|
];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable prefer-destructuring */
|
|
2
|
-
import fs from 'fs';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
3
|
import state, { saveCache } from '../state/index.js';
|
|
4
4
|
import { getFileHash } from '../utils/hash.js';
|
|
5
5
|
import run from './run.js';
|
|
@@ -36,8 +36,7 @@ function createInterfaceFile(headerOrModuleFilePath) {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
const headerPaths = (state.config.dependencyParameters?.pathsOfCmakeDepends?.split(';') || [])
|
|
39
|
-
.filter((d) => d.startsWith(state.config.paths.base))
|
|
40
|
-
.map((d) => d.replace(`${state.config.paths.base}/`, ''));
|
|
39
|
+
.filter((d) => d.startsWith(state.config.paths.base));
|
|
41
40
|
|
|
42
41
|
const temp2 = headerPaths
|
|
43
42
|
.map((p) => headerOrModuleFilePath.match(new RegExp(`^${p}/.*?/include/(.*?)$`, 'i')))
|
|
@@ -47,10 +46,10 @@ function createInterfaceFile(headerOrModuleFilePath) {
|
|
|
47
46
|
if (temp.length < 2) return null;
|
|
48
47
|
|
|
49
48
|
const filePathWithoutExt = temp[1];
|
|
50
|
-
const interfaceFile = `${
|
|
49
|
+
const interfaceFile = `${filePathWithoutExt}.i`;
|
|
51
50
|
|
|
52
51
|
if (fs.existsSync(interfaceFile)) {
|
|
53
|
-
const newPath = `${state.config.paths.build}/interface/${
|
|
52
|
+
const newPath = `${state.config.paths.build}/interface/${interfaceFile.split('/').at(-1)}`;
|
|
54
53
|
fs.copyFileSync(interfaceFile, newPath);
|
|
55
54
|
state.cache.interfaces[headerOrModuleFilePath] = newPath;
|
|
56
55
|
state.cache.hashes[headerOrModuleFilePath] = fileHash;
|
package/src/actions/createLib.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import os from 'os';
|
|
2
|
-
import fs from 'fs';
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
3
|
import replace from 'replace';
|
|
4
4
|
import run from './run.js';
|
|
5
5
|
import getCmakeParameters from './getCmakeParameters.js';
|
|
@@ -32,7 +32,8 @@ export default function createLib(platform, fileType, options = {}) {
|
|
|
32
32
|
const ext = sharedPlatforms.includes(basePlatform) ? 'so' : 'a';
|
|
33
33
|
buildParams = getBuildParams ? getBuildParams(platform, depPaths, ext, buildPath) : [];
|
|
34
34
|
if (state.config.build?.buildType !== 'configure') {
|
|
35
|
-
|
|
35
|
+
const cmakeBuildType = sharedPlatforms.includes(basePlatform) ? 'SHARED' : 'STATIC';
|
|
36
|
+
buildParams.push(`-DCMAKE_PREFIX_PATH=${libdir}`, `-DCMAKE_FIND_ROOT_PATH=${libdir}`, `-DBUILD_TYPE=${cmakeBuildType}`);
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
const cFlags = Object.values(depPaths).map((d) => `-I${d.header}`).join(' ');
|
|
@@ -1,40 +1,44 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import upath from 'upath';
|
|
3
|
+
import { execFileSync } from 'node:child_process';
|
|
3
4
|
import state from '../state/index.js';
|
|
4
5
|
|
|
5
|
-
export default function createXCFramework(
|
|
6
|
+
export default function createXCFramework(overrideConfig = null) {
|
|
6
7
|
if (process.platform !== 'darwin') {
|
|
7
8
|
return;
|
|
8
9
|
}
|
|
9
|
-
|
|
10
|
+
|
|
11
|
+
const output = overrideConfig?.paths?.output || state.config.paths.output;
|
|
12
|
+
const projectPath = overrideConfig?.paths?.project || state.config.paths.project;
|
|
13
|
+
const libName = overrideConfig?.export?.libName || state.config.export.libName;
|
|
14
|
+
|
|
10
15
|
if (
|
|
11
16
|
!fs.existsSync(`${output}/prebuilt/iOS-iphoneos/lib`)
|
|
12
17
|
|| !fs.existsSync(`${output}/prebuilt/iOS-iphonesimulator/lib`)
|
|
13
18
|
) return;
|
|
14
19
|
|
|
15
20
|
const options = {
|
|
16
|
-
cwd:
|
|
21
|
+
cwd: projectPath,
|
|
17
22
|
stdio: 'inherit',
|
|
18
23
|
};
|
|
19
24
|
|
|
20
|
-
|
|
21
|
-
|
|
25
|
+
const relativeOutput = upath.relative(projectPath, output);
|
|
26
|
+
|
|
27
|
+
libName.forEach((fileName) => {
|
|
28
|
+
if (!fs.existsSync(`${projectPath}/${fileName}.xcframework`)) {
|
|
22
29
|
const params = [
|
|
23
30
|
'-create-xcframework',
|
|
24
|
-
'-library',
|
|
25
|
-
'-headers',
|
|
26
|
-
'-library',
|
|
27
|
-
'-headers',
|
|
31
|
+
'-library', `${relativeOutput}/prebuilt/iOS-iphoneos/lib/lib${fileName}.a`,
|
|
32
|
+
'-headers', `${relativeOutput}/prebuilt/iOS-iphoneos/include`,
|
|
33
|
+
'-library', `${relativeOutput}/prebuilt/iOS-iphonesimulator/lib/lib${fileName}.a`,
|
|
34
|
+
'-headers', `${relativeOutput}/prebuilt/iOS-iphonesimulator/include`,
|
|
28
35
|
'-output', `${fileName}.xcframework`,
|
|
29
36
|
];
|
|
30
37
|
execFileSync('xcodebuild', params, options);
|
|
31
38
|
}
|
|
32
39
|
|
|
33
|
-
if (!fs.existsSync(`${
|
|
34
|
-
execFileSync('zip', ['-y', '-r',
|
|
35
|
-
}
|
|
36
|
-
if (createLink && !fs.existsSync(`${state.config.paths.project}/${fileName}.xcframework`)) {
|
|
37
|
-
fs.symlinkSync(`${options.cwd}/${fileName}.xcframework`, `${state.config.paths.project}/${fileName}.xcframework`);
|
|
40
|
+
if (!fs.existsSync(`${output}/prebuilt/${fileName}.xcframework.zip`)) {
|
|
41
|
+
execFileSync('zip', ['-y', '-r', `${relativeOutput}/prebuilt/${fileName}.xcframework.zip`, `${fileName}.xcframework`], options);
|
|
38
42
|
}
|
|
39
43
|
});
|
|
40
44
|
}
|
|
@@ -12,7 +12,12 @@ export default function getCmakeParameters(platform, options = {}) {
|
|
|
12
12
|
const externalNativeGlob = [
|
|
13
13
|
...(options.nativeGlob || []),
|
|
14
14
|
];
|
|
15
|
+
const externalBridgeGlob = [
|
|
16
|
+
`${state.config.paths.cli}/assets/bridge.cpp`,
|
|
17
|
+
...(options.bridgeGlob || []),
|
|
18
|
+
];
|
|
15
19
|
const nativeGlob = [
|
|
20
|
+
`${state.config.paths.cli}/assets/cppjsemptysource.cpp`,
|
|
16
21
|
...(dependParams.nativeGlob || []),
|
|
17
22
|
];
|
|
18
23
|
const headerGlob = [
|
|
@@ -34,6 +39,7 @@ export default function getCmakeParameters(platform, options = {}) {
|
|
|
34
39
|
`-DPROJECT_NAME=${options.name || state.config.general.name}`,
|
|
35
40
|
`-DBASE_DIR=${state.config.paths.project}`,
|
|
36
41
|
`-DEXTERNAL_NATIVE_GLOB=${externalNativeGlob.join(';')}`,
|
|
42
|
+
`-DEXTERNAL_BRIDGE_GLOB=${externalBridgeGlob.join(';')}`,
|
|
37
43
|
`-DNATIVE_GLOB=${nativeGlob.join(';')}`,
|
|
38
44
|
`-DHEADER_GLOB=${headerGlob.join(';')}`,
|
|
39
45
|
`-DHEADER_DIR=${headerDirs.join(';')}`,
|
package/src/actions/run.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { execFileSync } from 'child_process';
|
|
2
|
-
import fs from 'fs';
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
3
|
import pullDockerImage, { getDockerImage } from '../utils/pullDockerImage.js';
|
|
4
4
|
import getOsUserAndGroupId from '../utils/getOsUserAndGroupId.js';
|
|
5
|
+
import { getContentHash } from '../utils/hash.js';
|
|
5
6
|
import state from '../state/index.js';
|
|
6
7
|
|
|
7
8
|
const CROSSCOMPILER = 'aarch64-linux-android33';
|
|
@@ -151,92 +152,94 @@ export default function run(program, params = [], platformPrefix = null, platfor
|
|
|
151
152
|
default:
|
|
152
153
|
}
|
|
153
154
|
}
|
|
154
|
-
|
|
155
|
+
|
|
156
|
+
const env = {};
|
|
157
|
+
let runner = 'DOCKER';
|
|
158
|
+
if ((basePlatform === 'iOS' && program === null) || state.config.system.RUNNER === 'LOCAL') {
|
|
159
|
+
runner = 'LOCAL';
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (runner === 'LOCAL') {
|
|
155
163
|
const allowedEnv = [
|
|
156
164
|
'^PWD$', '^SHELL$', '^LC_CTYPE$', '^PATH$', '^HOME$', '^TMPDIR$', '^USER$',
|
|
157
165
|
'^PODS_*', '^CONFIGURATION_BUILD_DIR$', '^UNLOCALIZED_RESOURCES_FOLDER_PATH$',
|
|
158
166
|
];
|
|
159
|
-
const env = {};
|
|
160
167
|
Object.entries(process.env).forEach(([key, value]) => {
|
|
161
168
|
if (allowedEnv.some((e) => key.match(e))) {
|
|
162
169
|
env[key] = value;
|
|
163
170
|
}
|
|
164
171
|
});
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
else env[key] = v;
|
|
177
|
-
} else {
|
|
178
|
-
env[key] = value;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const pParams = [...platformParams, ...(dockerOptions.params || [])];
|
|
175
|
+
for (let i = 0; i < pParams.length; i += 2) {
|
|
176
|
+
if (pParams[i] === '-e') {
|
|
177
|
+
const [key, ...rest] = pParams[i + 1].split('=');
|
|
178
|
+
const value = rest.join('=');
|
|
179
|
+
if (['CFLAGS', 'CXXFLAGS', 'CPPFLAGS', 'LDFLAGS'].includes(key)) {
|
|
180
|
+
let v = value;
|
|
181
|
+
if (v.startsWith('\'') || v.startsWith('"')) {
|
|
182
|
+
v = v.substring(1, v.length - 1);
|
|
179
183
|
}
|
|
184
|
+
if (env[key]) env[key] += ` ${v}`;
|
|
185
|
+
else env[key] = v;
|
|
186
|
+
} else {
|
|
187
|
+
env[key] = value;
|
|
180
188
|
}
|
|
181
189
|
}
|
|
190
|
+
}
|
|
182
191
|
|
|
192
|
+
let fileExecParams;
|
|
193
|
+
if (runner === 'LOCAL') {
|
|
183
194
|
env.PATH = `/opt/homebrew/bin:${env.PATH}`;
|
|
184
195
|
|
|
185
196
|
const options = {
|
|
186
197
|
cwd: dockerOptions.workdir || buildPath,
|
|
187
|
-
stdio: dockerOptions.console ? 'inherit' : 'ignore',
|
|
198
|
+
stdio: dockerOptions.console ? 'inherit' : ['ignore', 'pipe', 'pipe'],
|
|
188
199
|
env,
|
|
189
200
|
};
|
|
190
|
-
|
|
191
|
-
} else if (
|
|
192
|
-
const options = { cwd: buildPath, stdio: dockerOptions.console ? 'inherit' : 'ignore' };
|
|
193
|
-
const args = [
|
|
194
|
-
'exec',
|
|
195
|
-
'--user', getOsUserAndGroupId(),
|
|
196
|
-
'--workdir', dockerOptions.workdir || replaceBasePathForDocker(buildPath),
|
|
197
|
-
'cppjs-builder',
|
|
198
|
-
dProgram,
|
|
199
|
-
...replaceBasePathForDocker(dParams),
|
|
200
|
-
];
|
|
201
|
-
execFileSync('docker', args, options);
|
|
202
|
-
} else {
|
|
203
|
-
const env = {};
|
|
204
|
-
const pParams = [...platformParams, ...(dockerOptions.params || [])];
|
|
205
|
-
for (let i = 0; i < pParams.length; i += 2) {
|
|
206
|
-
if (pParams[i] === '-e') {
|
|
207
|
-
const [key, ...rest] = pParams[i + 1].split('=');
|
|
208
|
-
const value = rest.join('=');
|
|
209
|
-
if (['CFLAGS', 'CXXFLAGS', 'CPPFLAGS', 'LDFLAGS'].includes(key)) {
|
|
210
|
-
let v = value;
|
|
211
|
-
if (v.startsWith('\'') || v.startsWith('"')) {
|
|
212
|
-
v = v.substring(1, v.length - 1);
|
|
213
|
-
}
|
|
214
|
-
if (env[key]) env[key] += ` ${v}`;
|
|
215
|
-
else env[key] = v;
|
|
216
|
-
} else {
|
|
217
|
-
env[key] = value;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
201
|
+
fileExecParams = [dProgram, dParams, options];
|
|
202
|
+
} else if (runner === 'DOCKER') {
|
|
222
203
|
const dockerEnv = [];
|
|
223
204
|
Object.entries(env).forEach(([key, value]) => {
|
|
224
205
|
dockerEnv.push('-e', `${key}=${value}`);
|
|
225
206
|
});
|
|
226
|
-
const options = { cwd: buildPath, stdio: dockerOptions.console ? 'inherit' : 'ignore' };
|
|
207
|
+
const options = { cwd: buildPath, stdio: dockerOptions.console ? 'inherit' : ['ignore', 'pipe', 'pipe'] };
|
|
208
|
+
|
|
209
|
+
let runnerParams = [];
|
|
210
|
+
let imageOrContainer = null;
|
|
211
|
+
if (state.config.system.RUNNER === 'DOCKER_RUN') {
|
|
212
|
+
imageOrContainer = getDockerImage();
|
|
213
|
+
runnerParams = ['run', '--rm', '-v', `${state.config.paths.base}:/tmp/cppjs/live`];
|
|
214
|
+
} else if (state.config.system.RUNNER === 'DOCKER_EXEC') {
|
|
215
|
+
imageOrContainer = `${getDockerImage()}-${getContentHash(state.config.paths.base)}`.replace('/', '-').replace(':', '-');
|
|
216
|
+
runnerParams = ['exec'];
|
|
217
|
+
} else {
|
|
218
|
+
throw new Error(`The runner ${state.config.system.RUNNER} is invalid.`);
|
|
219
|
+
}
|
|
220
|
+
|
|
227
221
|
const args = [
|
|
228
|
-
|
|
229
|
-
'--rm',
|
|
222
|
+
...runnerParams,
|
|
230
223
|
'--user', getOsUserAndGroupId(),
|
|
231
|
-
'-v', `${state.config.paths.base}:/tmp/cppjs/live`,
|
|
232
224
|
'--workdir', replaceBasePathForDocker(dockerOptions.workdir || buildPath),
|
|
233
225
|
...replaceBasePathForDocker(dockerEnv),
|
|
234
226
|
// '-e', replaceBasePathForDocker(`CCACHE_DIR=${state.config.paths.build}/ccache`),
|
|
235
|
-
|
|
227
|
+
imageOrContainer,
|
|
236
228
|
replaceBasePathForDocker(dProgram),
|
|
237
229
|
...replaceBasePathForDocker(dParams),
|
|
238
230
|
];
|
|
239
|
-
|
|
231
|
+
fileExecParams = ['docker', args, options];
|
|
232
|
+
} else {
|
|
233
|
+
throw new Error(`The runner ${state.config.system.RUNNER} or command is invalid.`);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
try {
|
|
237
|
+
execFileSync(...fileExecParams);
|
|
238
|
+
} catch (e) {
|
|
239
|
+
console.log(e?.stdout?.toString() || 'stdout is empty');
|
|
240
|
+
console.error(e?.stderr?.toString() || 'stderr is empty');
|
|
241
|
+
console.error('An error occurred while running the application. Please check the logs for more details.');
|
|
242
|
+
process.exit();
|
|
240
243
|
}
|
|
241
244
|
}
|
|
242
245
|
|
|
@@ -26,7 +26,7 @@ if (BUILD_SOURCE)
|
|
|
26
26
|
endif(BUILD_SOURCE)
|
|
27
27
|
|
|
28
28
|
if (BUILD_BRIDGE)
|
|
29
|
-
file(GLOB BRIDGE_SRC_FILES "${BRIDGE_DIR}/*.i.cpp")
|
|
29
|
+
file(GLOB BRIDGE_SRC_FILES "${BRIDGE_DIR}/*.i.cpp;${EXTERNAL_BRIDGE_GLOB}")
|
|
30
30
|
endif(BUILD_BRIDGE)
|
|
31
31
|
|
|
32
32
|
file(GLOB_RECURSE EXTERNAL_SRC_FILES ${EXTERNAL_NATIVE_GLOB})
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#include <emscripten/bind.h>
|
|
2
|
+
|
|
3
|
+
EMSCRIPTEN_BINDINGS(stl_wrappers) {
|
|
4
|
+
emscripten::register_vector<bool>("VectorBool");
|
|
5
|
+
emscripten::register_vector<char>("VectorChar");
|
|
6
|
+
emscripten::register_vector<short>("VectorShort");
|
|
7
|
+
emscripten::register_vector<int>("VectorInt");
|
|
8
|
+
emscripten::register_vector<int64_t>("VectorInt64");
|
|
9
|
+
emscripten::register_vector<float>("VectorFloat");
|
|
10
|
+
emscripten::register_vector<double>("VectorDouble");
|
|
11
|
+
emscripten::register_vector<std::string>("VectorString");
|
|
12
|
+
|
|
13
|
+
emscripten::register_map<int,int>("MapIntInt");
|
|
14
|
+
emscripten::register_map<int,std::string>("MapIntString");
|
|
15
|
+
emscripten::register_map<std::string,std::string>("MapStringString");
|
|
16
|
+
emscripten::register_map<std::string,int>("MapStringInt");
|
|
17
|
+
}
|
|
File without changes
|
package/src/bin.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import fs from 'fs';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import { execFileSync } from 'node:child_process';
|
|
4
5
|
import { Command, Option } from 'commander';
|
|
5
6
|
import glob from 'glob';
|
|
6
7
|
import upath from 'upath';
|
|
@@ -14,6 +15,10 @@ import createXCFramework from './actions/createXCFramework.js';
|
|
|
14
15
|
import runCppjsApp from './actions/run.js';
|
|
15
16
|
import downloadAndExtractFile from './utils/downloadAndExtractFile.js';
|
|
16
17
|
import writeJson from './utils/writeJson.js';
|
|
18
|
+
import systemKeys from './utils/systemKeys.js';
|
|
19
|
+
|
|
20
|
+
import { getDockerImage } from './utils/pullDockerImage.js';
|
|
21
|
+
import { getContentHash } from './utils/hash.js';
|
|
17
22
|
|
|
18
23
|
const packageJSON = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url)));
|
|
19
24
|
|
|
@@ -29,20 +34,22 @@ const commandBuild = program.command('build')
|
|
|
29
34
|
.description('compile the project that was set up using Cpp.js')
|
|
30
35
|
.addOption(new Option('-p, --platform <platform>', 'target platform').default('All').choices(['All', 'WebAssembly', 'Android', 'iOS']));
|
|
31
36
|
|
|
32
|
-
const
|
|
33
|
-
.description('
|
|
37
|
+
const commandDocker = program.command('docker')
|
|
38
|
+
.description('manage docker');
|
|
39
|
+
const commandRun = commandDocker.command('run').description('run docker application');
|
|
40
|
+
commandDocker.command('create').description('create docker container');
|
|
41
|
+
commandDocker.command('start').description('start docker container');
|
|
42
|
+
commandDocker.command('stop').description('stop docker container');
|
|
43
|
+
commandDocker.command('delete').description('delete docker container');
|
|
34
44
|
|
|
35
45
|
const commandConfig = program.command('config')
|
|
36
|
-
.description('Manage the
|
|
37
|
-
|
|
38
|
-
commandConfig.command('
|
|
39
|
-
commandConfig.command('
|
|
40
|
-
commandConfig.command('
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const commandPostInstall = program.command('postinstall')
|
|
45
|
-
.description('prepare the required packages for Cpp.js after installation');
|
|
46
|
+
.description('Manage the Cpp.js configuration files');
|
|
47
|
+
commandConfig.command('get').description('get the Cpp.js system configuration');
|
|
48
|
+
commandConfig.command('set').description('set the Cpp.js system configuration');
|
|
49
|
+
commandConfig.command('delete').description('delete the Cpp.js system configuration');
|
|
50
|
+
const commandConfigList = commandConfig.command('list').description('list the Cpp.js configurations')
|
|
51
|
+
.addOption(new Option('-t, --type <type>', 'config type').default('system').choices(['all', 'system', 'project']));
|
|
52
|
+
commandConfig.command('keys').description('list all available system configuration keys for Cpp.js');
|
|
46
53
|
|
|
47
54
|
program.parse(process.argv);
|
|
48
55
|
|
|
@@ -56,9 +63,72 @@ switch (program.args[0]) {
|
|
|
56
63
|
}
|
|
57
64
|
break;
|
|
58
65
|
}
|
|
59
|
-
case '
|
|
60
|
-
|
|
61
|
-
|
|
66
|
+
case 'docker': {
|
|
67
|
+
switch (program.args[1]) {
|
|
68
|
+
case 'run': {
|
|
69
|
+
const [programName, ...params] = commandRun.args;
|
|
70
|
+
run(programName, params);
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
case 'create': {
|
|
74
|
+
const args = [
|
|
75
|
+
'run',
|
|
76
|
+
'-dit',
|
|
77
|
+
'--name',
|
|
78
|
+
`${getDockerImage()}-${getContentHash(state.config.paths.base)}`.replace('/', '-').replace(':', '-'),
|
|
79
|
+
'-v', `${state.config.paths.base}:/tmp/cppjs/live`,
|
|
80
|
+
getDockerImage(),
|
|
81
|
+
'bash',
|
|
82
|
+
];
|
|
83
|
+
try {
|
|
84
|
+
execFileSync('docker', args, { stdio: 'inherit' });
|
|
85
|
+
} catch (e) {
|
|
86
|
+
console.error('An error occurred while running the application. Please check the logs for more details.');
|
|
87
|
+
process.exit();
|
|
88
|
+
}
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
case 'start': {
|
|
92
|
+
const args = [
|
|
93
|
+
'start',
|
|
94
|
+
`${getDockerImage()}-${getContentHash(state.config.paths.base)}`.replace('/', '-').replace(':', '-'),
|
|
95
|
+
];
|
|
96
|
+
try {
|
|
97
|
+
execFileSync('docker', args, { stdio: 'inherit' });
|
|
98
|
+
} catch (e) {
|
|
99
|
+
console.error('An error occurred while running the application. Please check the logs for more details.');
|
|
100
|
+
process.exit();
|
|
101
|
+
}
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
case 'stop': {
|
|
105
|
+
const args = [
|
|
106
|
+
'stop',
|
|
107
|
+
`${getDockerImage()}-${getContentHash(state.config.paths.base)}`.replace('/', '-').replace(':', '-'),
|
|
108
|
+
];
|
|
109
|
+
try {
|
|
110
|
+
execFileSync('docker', args, { stdio: 'inherit' });
|
|
111
|
+
} catch (e) {
|
|
112
|
+
console.error('An error occurred while running the application. Please check the logs for more details.');
|
|
113
|
+
process.exit();
|
|
114
|
+
}
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
case 'delete': {
|
|
118
|
+
const args = [
|
|
119
|
+
'rm',
|
|
120
|
+
`${getDockerImage()}-${getContentHash(state.config.paths.base)}`.replace('/', '-').replace(':', '-'),
|
|
121
|
+
];
|
|
122
|
+
try {
|
|
123
|
+
execFileSync('docker', args, { stdio: 'inherit' });
|
|
124
|
+
} catch (e) {
|
|
125
|
+
console.error('An error occurred while running the application. Please check the logs for more details.');
|
|
126
|
+
process.exit();
|
|
127
|
+
}
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
default:
|
|
131
|
+
}
|
|
62
132
|
break;
|
|
63
133
|
}
|
|
64
134
|
case 'config': {
|
|
@@ -75,29 +145,58 @@ switch (program.args[0]) {
|
|
|
75
145
|
case 'list':
|
|
76
146
|
listSystemConfig(commandConfigList.opts().type);
|
|
77
147
|
break;
|
|
148
|
+
case 'keys':
|
|
149
|
+
listSystemKeys();
|
|
150
|
+
break;
|
|
78
151
|
default:
|
|
79
152
|
break;
|
|
80
153
|
}
|
|
81
154
|
break;
|
|
82
155
|
}
|
|
83
|
-
case 'postinstall': {
|
|
84
|
-
postInstall();
|
|
85
|
-
break;
|
|
86
|
-
}
|
|
87
156
|
default:
|
|
88
157
|
break;
|
|
89
158
|
}
|
|
90
159
|
|
|
91
|
-
function
|
|
92
|
-
console.
|
|
160
|
+
function listSystemKeys() {
|
|
161
|
+
console.info('Available configurations:');
|
|
162
|
+
console.table(systemKeys);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function getSystemConfig(systemKey) {
|
|
166
|
+
if (!systemKey) {
|
|
167
|
+
listSystemConfig('system');
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const key = systemKey.toUpperCase();
|
|
171
|
+
const output = {};
|
|
172
|
+
if (key in state.config.system) {
|
|
173
|
+
output[key] = { value: state.config.system[key] || 'undefined', default: systemKeys[key].default };
|
|
174
|
+
}
|
|
175
|
+
Object.keys(systemKeys).filter((k) => k.includes(key)).forEach((k) => {
|
|
176
|
+
if (k in state.config.system) {
|
|
177
|
+
output[k] = { value: state.config.system[k] || 'undefined', default: systemKeys[k].default };
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
console.table(output);
|
|
93
182
|
}
|
|
94
183
|
|
|
95
184
|
function setSystemConfig(key, value) {
|
|
185
|
+
if (!systemKeys[key]) {
|
|
186
|
+
throw new Error(`Configuration ${key} is not available. Please choose from the following available configurations: ${Object.keys(systemKeys).join(', ')}`);
|
|
187
|
+
}
|
|
188
|
+
if (systemKeys[key].options && !systemKeys[key].options.includes(value)) {
|
|
189
|
+
throw new Error(`Value ${value} is not available. Please choose from the following available values: ${systemKeys[key].options.join(', ')}`);
|
|
190
|
+
}
|
|
191
|
+
|
|
96
192
|
state.config.system[key] = value;
|
|
97
193
|
writeJson(state.config.paths.systemConfig, state.config.system);
|
|
98
194
|
}
|
|
99
195
|
|
|
100
196
|
function deleteSystemConfig(key) {
|
|
197
|
+
if (!systemKeys[key]) {
|
|
198
|
+
throw new Error(`Configuration ${key} is not available. Please choose from the following available configurations: ${Object.keys(systemKeys).join(', ')}`);
|
|
199
|
+
}
|
|
101
200
|
delete state.config.system[key];
|
|
102
201
|
writeJson(state.config.paths.systemConfig, state.config.system);
|
|
103
202
|
}
|
|
@@ -106,7 +205,7 @@ function listSystemConfig(type) {
|
|
|
106
205
|
const { system: systemConfig, ...projectConfig } = state.config;
|
|
107
206
|
if (type === 'all' || type === 'system') {
|
|
108
207
|
console.log('System Configuration');
|
|
109
|
-
console.
|
|
208
|
+
console.table(systemConfig);
|
|
110
209
|
}
|
|
111
210
|
|
|
112
211
|
if (type === 'all') {
|
|
@@ -115,38 +214,8 @@ function listSystemConfig(type) {
|
|
|
115
214
|
|
|
116
215
|
if (type === 'all' || type === 'project') {
|
|
117
216
|
console.log('Project Configuration');
|
|
118
|
-
console.
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function postInstall() {
|
|
123
|
-
const projectPath = process.env.PWD;
|
|
124
|
-
const isDarwin = process.platform === 'darwin';
|
|
125
|
-
if (
|
|
126
|
-
!isDarwin
|
|
127
|
-
|| (
|
|
128
|
-
!fs.existsSync(`${projectPath}/cppjs.config.js`)
|
|
129
|
-
&& !fs.existsSync(`${projectPath}/cppjs.config.cjs`)
|
|
130
|
-
&& !fs.existsSync(`${projectPath}/cppjs.config.mjs`)
|
|
131
|
-
)
|
|
132
|
-
) {
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const name = state?.config?.general?.name;
|
|
137
|
-
let dist = state?.config?.paths?.output;
|
|
138
|
-
dist = dist ? upath.relative(projectPath, dist) : null;
|
|
139
|
-
|
|
140
|
-
if (!name || !dist) {
|
|
141
|
-
return;
|
|
217
|
+
console.table(projectConfig);
|
|
142
218
|
}
|
|
143
|
-
|
|
144
|
-
state?.config?.export?.libName?.forEach((fileName) => {
|
|
145
|
-
if (fs.existsSync(`${projectPath}/${fileName}.xcframework`) || !fs.existsSync(`${dist}/prebuilt/${fileName}.xcframework`)) {
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
fs.symlinkSync(`${dist}/prebuilt/${fileName}.xcframework`, `${projectPath}/${fileName}.xcframework`);
|
|
149
|
-
});
|
|
150
219
|
}
|
|
151
220
|
|
|
152
221
|
function run(programName, params) {
|
|
@@ -177,7 +246,7 @@ async function buildExternal(platform) {
|
|
|
177
246
|
});
|
|
178
247
|
}
|
|
179
248
|
|
|
180
|
-
|
|
249
|
+
buildLib(platform);
|
|
181
250
|
}
|
|
182
251
|
|
|
183
252
|
async function build(platform) {
|
|
@@ -187,10 +256,23 @@ async function build(platform) {
|
|
|
187
256
|
}
|
|
188
257
|
}
|
|
189
258
|
|
|
190
|
-
|
|
259
|
+
function buildLib(platform) {
|
|
191
260
|
state.platforms[platform].forEach((p) => {
|
|
192
261
|
if (!fs.existsSync(`${state.config.paths.output}/prebuilt/${p}/lib`)) {
|
|
193
262
|
createLib(p, 'Source', { isProd: true, buildSource: true });
|
|
263
|
+
|
|
264
|
+
const modules = [];
|
|
265
|
+
state.config.paths.module.forEach((modulePath) => {
|
|
266
|
+
modules.push(...glob.sync('**/*.i', { absolute: true, cwd: modulePath }));
|
|
267
|
+
modules.push(...glob.sync('*.i', { absolute: true, cwd: modulePath }));
|
|
268
|
+
});
|
|
269
|
+
if (modules.length > 0) {
|
|
270
|
+
fs.mkdirSync(`${state.config.paths.output}/prebuilt/${p}/swig`, { recursive: true });
|
|
271
|
+
}
|
|
272
|
+
modules.forEach((modulePath) => {
|
|
273
|
+
const fileName = modulePath.split('/').at(-1);
|
|
274
|
+
fs.copyFileSync(modulePath, `${state.config.paths.output}/prebuilt/${p}/swig/${fileName}`);
|
|
275
|
+
});
|
|
194
276
|
} else {
|
|
195
277
|
console.log(`${state.config.general.name} is already compiled to ${p} architecture.`);
|
|
196
278
|
}
|
|
@@ -79,7 +79,7 @@ function getWebScript(env, modulePrefix) {
|
|
|
79
79
|
return `
|
|
80
80
|
export function initCppJs(config = {}) {
|
|
81
81
|
return new Promise((resolve, reject) => {
|
|
82
|
-
import('/cpp.js').then(n => {
|
|
82
|
+
import(/* webpackIgnore: true */ '/cpp.js').then(n => {
|
|
83
83
|
return window.CppJs.initCppJs(${params});
|
|
84
84
|
}).then(m => {
|
|
85
85
|
${modulePrefix}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
1
2
|
import state from '../state/index.js';
|
|
2
3
|
|
|
3
4
|
export default function getDependFilePath(source, platform) {
|
|
@@ -6,13 +7,24 @@ export default function getDependFilePath(source, platform) {
|
|
|
6
7
|
|
|
7
8
|
const dependPackage = state.config.allDependencies.find((d) => source.startsWith(d.package.name));
|
|
8
9
|
if (dependPackage) {
|
|
9
|
-
const
|
|
10
|
+
const depName = dependPackage.package.name;
|
|
11
|
+
const filePath = source.substring(depName.length + 1);
|
|
10
12
|
|
|
11
|
-
let path
|
|
13
|
+
let path;
|
|
12
14
|
if (headerRegex.test(source)) {
|
|
13
|
-
path = `${dependPackage.paths.output}/prebuilt/${platform}/include
|
|
15
|
+
path = `${dependPackage.paths.output}/prebuilt/${platform}/include`;
|
|
14
16
|
} else if (moduleRegex.test(source)) {
|
|
15
|
-
path = `${dependPackage.paths.output}/prebuilt/${platform}/swig
|
|
17
|
+
path = `${dependPackage.paths.output}/prebuilt/${platform}/swig`;
|
|
18
|
+
} else {
|
|
19
|
+
path = `${dependPackage.paths.output}/prebuilt/${platform}`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (fs.existsSync(`${path}/${depName}/${filePath}`)) {
|
|
23
|
+
path = `${path}/${depName}/${filePath}`;
|
|
24
|
+
} else if (fs.existsSync(`${path}/${filePath}`)) {
|
|
25
|
+
path = `${path}/${filePath}`;
|
|
26
|
+
} else {
|
|
27
|
+
throw new Error(`${source} not found in ${depName} package.`);
|
|
16
28
|
}
|
|
17
29
|
|
|
18
30
|
return path;
|
package/src/state/index.js
CHANGED
|
@@ -55,9 +55,9 @@ function setAllDependecyPaths() {
|
|
|
55
55
|
if (basePlatform === 'iOS') {
|
|
56
56
|
let xcRoot;
|
|
57
57
|
if (platform === 'iOS-iphoneos') {
|
|
58
|
-
xcRoot = `${d.paths.
|
|
58
|
+
xcRoot = `${d.paths.project}/${name}.xcframework/ios-arm64_arm64e`;
|
|
59
59
|
} else if (platform === 'iOS-iphonesimulator') {
|
|
60
|
-
xcRoot = `${d.paths.
|
|
60
|
+
xcRoot = `${d.paths.project}/${name}.xcframework/ios-arm64_arm64e_x86_64-simulator`;
|
|
61
61
|
}
|
|
62
62
|
dep.header = `${xcRoot}/Headers`;
|
|
63
63
|
dep.libPath = xcRoot;
|
package/src/state/loadConfig.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import os from 'os';
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import systemKeys from '../utils/systemKeys.js';
|
|
2
3
|
import loadJs from '../utils/loadJs.js';
|
|
3
4
|
import loadJson from '../utils/loadJson.js';
|
|
4
5
|
import getParentPath from '../utils/getParentPath.js';
|
|
@@ -16,6 +17,12 @@ export default async function loadConfig(configDir = process.cwd(), configName =
|
|
|
16
17
|
output.paths.systemConfig = `${os.homedir()}/.cppjs.json`;
|
|
17
18
|
output.system = loadJson(output.paths.systemConfig) || {};
|
|
18
19
|
|
|
20
|
+
Object.entries(systemKeys).forEach(([key, value]) => {
|
|
21
|
+
if (!(key in output.system)) {
|
|
22
|
+
output.system[key] = value.default;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
19
26
|
return output;
|
|
20
27
|
}
|
|
21
28
|
|
package/src/utils/hash.js
CHANGED
package/src/utils/loadJs.js
CHANGED
package/src/utils/loadJson.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { execFileSync } from 'child_process';
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
2
|
|
|
3
3
|
let isDockerImageAvailable = false;
|
|
4
4
|
|
|
5
5
|
export function getDockerImage() {
|
|
6
|
-
return 'bugra9/cpp.js:0.2.
|
|
6
|
+
return 'bugra9/cpp.js:0.2.8';
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export default function pullDockerImage() {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const systemKeys = {
|
|
2
|
+
XCODE_DEVELOPMENT_TEAM: {
|
|
3
|
+
description: 'The unique identifier of the development team used for code signing and app distribution in Xcode.',
|
|
4
|
+
default: '',
|
|
5
|
+
},
|
|
6
|
+
RUNNER: {
|
|
7
|
+
description: 'The execution environment for running the application.',
|
|
8
|
+
options: ['DOCKER_RUN', 'DOCKER_EXEC', 'LOCAL'],
|
|
9
|
+
default: 'DOCKER_RUN',
|
|
10
|
+
},
|
|
11
|
+
LOG_LEVEL: {
|
|
12
|
+
description: 'The verbosity of log output.',
|
|
13
|
+
options: ['DEBUG', 'INFO', 'WARN', 'ERROR'],
|
|
14
|
+
default: 'INFO',
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default systemKeys;
|
package/src/utils/writeJson.js
CHANGED