cpp.js 1.0.0-beta.6 → 1.0.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.
- package/CHANGELOG.md +13 -0
- package/LICENSE +1 -1
- package/README.md +9 -26
- package/package.json +24 -14
- package/src/{functions/buildJS.js → actions/buildJs.js} +7 -6
- package/src/actions/buildWasm.js +68 -0
- package/src/actions/createInterface.js +128 -0
- package/src/actions/createLib.js +104 -0
- package/src/actions/createXCFramework.js +44 -0
- package/src/actions/getAllBridges.js +8 -0
- package/src/actions/getCmakeParameters.js +56 -0
- package/src/actions/getData.js +28 -0
- package/src/actions/getDependLibs.js +19 -0
- package/src/{functions → actions}/run.js +118 -64
- package/src/assets/CMakeLists.txt +14 -10
- package/src/assets/commonBridges.cpp +16 -0
- package/src/assets/dist.cmake +1 -1
- package/src/assets/ios.toolchain.cmake +4 -4
- package/src/bin.js +255 -96
- package/src/index.js +13 -63
- package/src/integration/getCppJsScript.js +91 -0
- package/src/integration/getDependFilePath.js +34 -0
- package/src/state/calculateDependencyParameters.js +64 -0
- package/src/state/index.js +81 -0
- package/src/state/loadConfig.js +104 -0
- package/src/utils/downloadAndExtractFile.js +36 -0
- package/src/utils/findFiles.js +5 -0
- package/src/utils/fixPackageName.js +7 -0
- package/src/utils/getAbsolutePath.js +14 -0
- package/src/utils/getCMakeListsFilePath.js +17 -0
- package/src/utils/getOsUserAndGroupId.js +1 -1
- package/src/utils/getParentPath.js +12 -0
- package/src/utils/hash.js +20 -0
- package/src/utils/loadJs.js +32 -0
- package/src/utils/loadJson.js +16 -0
- package/src/utils/pullDockerImage.js +2 -2
- package/src/utils/systemKeys.js +18 -0
- package/src/utils/writeJson.js +9 -0
- package/.mocharc.yaml +0 -3
- package/src/functions/createBridge.js +0 -37
- package/src/functions/createLib.js +0 -44
- package/src/functions/createWasm.js +0 -67
- package/src/functions/findOrCreateInterfaceFile.js +0 -68
- package/src/functions/finishBuild.js +0 -43
- package/src/functions/getCmakeParams.js +0 -106
- package/src/functions/getData.js +0 -36
- package/src/functions/getLibs.js +0 -33
- package/src/functions/specs/createBridge.spec.js +0 -51
- package/src/functions/specs/findOrCreateInterfaceFile.spec.js +0 -49
- package/src/utils/createTempDir.js +0 -15
- package/src/utils/findCMakeListsFile.js +0 -16
- package/src/utils/getBaseInfo.js +0 -15
- package/src/utils/getCliPath.js +0 -12
- package/src/utils/getConfig.js +0 -170
- package/src/utils/getDirName.js +0 -8
- package/src/utils/getPathInfo.js +0 -10
- package/src/utils/specs/findCMakeListsFile.spec.js +0 -34
- package/src/utils/specs/utils.spec.js +0 -81
- package/test/data/sample.cpp +0 -1
- package/test/data/sample.h +0 -10
- package/test/data/sample.i +0 -12
- package/test/data/sample2.ei +0 -12
- package/test/data/sample2.h +0 -10
- /package/{test/data/sample2.cpp → src/assets/cppjsEmptySource.cpp} +0 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export default function calculateDependencyParameters(config) {
|
|
2
|
+
const sourceFilter = (d) => d === config || d.export.type === 'source';
|
|
3
|
+
let headerPathWithDepends = [];
|
|
4
|
+
setPath(headerPathWithDepends, config, 'header', sourceFilter);
|
|
5
|
+
headerPathWithDepends = [...new Set(headerPathWithDepends)].join(';');
|
|
6
|
+
|
|
7
|
+
const headerGlob = [];
|
|
8
|
+
headerPathWithDepends.split(';').forEach((h) => {
|
|
9
|
+
config.ext.header.forEach((ext) => {
|
|
10
|
+
headerGlob.push(`${h}/*.${ext}`);
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
let nativePathWithDepends = [];
|
|
15
|
+
setPath(nativePathWithDepends, config, 'native', sourceFilter);
|
|
16
|
+
nativePathWithDepends = [...new Set(nativePathWithDepends)].join(';');
|
|
17
|
+
|
|
18
|
+
const nativeGlob = [];
|
|
19
|
+
nativePathWithDepends.split(';').forEach((h) => {
|
|
20
|
+
config.ext.source.forEach((ext) => {
|
|
21
|
+
nativeGlob.push(`${h}/*.${ext}`);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const cmakeFilter = (d) => d !== config && d.export.type === 'cmake' && d.paths.cmake !== config.paths.cliCMakeListsTxt;
|
|
26
|
+
let cmakeDepends = [];
|
|
27
|
+
setPath(cmakeDepends, config, 'this', cmakeFilter);
|
|
28
|
+
cmakeDepends = [...new Set(cmakeDepends)];
|
|
29
|
+
|
|
30
|
+
const pathsOfCmakeDepends = [...new Set(cmakeDepends
|
|
31
|
+
.map((d) => getParentPath(d.paths.cmake)))].join(';');
|
|
32
|
+
const nameOfCmakeDepends = [...new Set(cmakeDepends.map((d) => d.general.name))].join(';');
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
nativeGlob,
|
|
36
|
+
headerGlob,
|
|
37
|
+
headerPathWithDepends,
|
|
38
|
+
cmakeDepends,
|
|
39
|
+
pathsOfCmakeDepends,
|
|
40
|
+
nameOfCmakeDepends,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function setPath(arr, dependency, type, filter = () => {}) {
|
|
45
|
+
if (filter(dependency)) {
|
|
46
|
+
if (type === 'this') {
|
|
47
|
+
arr.push(dependency);
|
|
48
|
+
} else if (Array.isArray(dependency.paths[type])) {
|
|
49
|
+
arr.push(...dependency.paths[type]);
|
|
50
|
+
} else {
|
|
51
|
+
arr.push(dependency.paths[type]);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
dependency.dependencies.forEach((dep) => {
|
|
56
|
+
setPath(arr, dep, type, filter);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function getParentPath(path) {
|
|
61
|
+
const pathArray = path.split('/');
|
|
62
|
+
pathArray.pop();
|
|
63
|
+
return pathArray.join('/');
|
|
64
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import loadJson from '../utils/loadJson.js';
|
|
2
|
+
import writeJson from '../utils/writeJson.js';
|
|
3
|
+
import loadConfig from './loadConfig.js';
|
|
4
|
+
|
|
5
|
+
const cacheDir = `${process.cwd()}/.cppjs`;
|
|
6
|
+
|
|
7
|
+
const state = {
|
|
8
|
+
platforms: {
|
|
9
|
+
All: ['Emscripten-x86_64', 'Android-arm64-v8a', 'Android-x86_64', 'iOS-iphoneos', 'iOS-iphonesimulator'],
|
|
10
|
+
WebAssembly: ['Emscripten-x86_64'],
|
|
11
|
+
Android: ['Android-arm64-v8a', 'Android-x86_64'],
|
|
12
|
+
iOS: ['iOS-iphoneos', 'iOS-iphonesimulator'],
|
|
13
|
+
},
|
|
14
|
+
config: null,
|
|
15
|
+
cache: {
|
|
16
|
+
hashes: {},
|
|
17
|
+
interfaces: {},
|
|
18
|
+
bridges: {},
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
if (typeof module !== 'undefined' && module.exports) {
|
|
23
|
+
initProcessState();
|
|
24
|
+
} else {
|
|
25
|
+
await initProcessState();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
await initProcessState();
|
|
29
|
+
|
|
30
|
+
async function initProcessState() {
|
|
31
|
+
state.cache = loadCacheState();
|
|
32
|
+
state.config = await loadConfig();
|
|
33
|
+
setAllDependecyPaths();
|
|
34
|
+
if (state.config.build?.setState) {
|
|
35
|
+
state.config.build.setState(state);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function loadCacheState() {
|
|
40
|
+
const stateFilePath = `${cacheDir}/cache.json`;
|
|
41
|
+
return loadJson(stateFilePath) || state.cache;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function setAllDependecyPaths() {
|
|
45
|
+
state.config.allDependencyPaths = {};
|
|
46
|
+
state.platforms.All.forEach((platform) => {
|
|
47
|
+
const basePlatform = platform.split('-', 1)[0];
|
|
48
|
+
state.config.allDependencyPaths[platform] = {};
|
|
49
|
+
state.config.allDependencies.forEach((d) => {
|
|
50
|
+
d.export.libName.forEach((name) => {
|
|
51
|
+
state.config.allDependencyPaths[platform][name] = {
|
|
52
|
+
root: `${d.paths.output}/prebuilt/${platform}`,
|
|
53
|
+
};
|
|
54
|
+
const dep = state.config.allDependencyPaths[platform][name];
|
|
55
|
+
if (basePlatform === 'iOS') {
|
|
56
|
+
let xcRoot;
|
|
57
|
+
if (platform === 'iOS-iphoneos') {
|
|
58
|
+
xcRoot = `${d.paths.project}/${name}.xcframework/ios-arm64_arm64e`;
|
|
59
|
+
} else if (platform === 'iOS-iphonesimulator') {
|
|
60
|
+
xcRoot = `${d.paths.project}/${name}.xcframework/ios-arm64_arm64e_x86_64-simulator`;
|
|
61
|
+
}
|
|
62
|
+
dep.header = `${xcRoot}/Headers`;
|
|
63
|
+
dep.libPath = xcRoot;
|
|
64
|
+
dep.lib = `${dep.libPath}/lib${name}.a`;
|
|
65
|
+
dep.bin = `${dep.root}/bin`;
|
|
66
|
+
} else {
|
|
67
|
+
dep.header = `${dep.root}/include`;
|
|
68
|
+
dep.libPath = `${dep.root}/lib`;
|
|
69
|
+
dep.lib = `${dep.libPath}/lib${name}.${basePlatform === 'Android' ? 'so' : 'a'}`;
|
|
70
|
+
dep.bin = `${dep.root}/bin`;
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function saveCache() {
|
|
78
|
+
writeJson(`${cacheDir}/cache.json`, state.cache);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export default state;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import systemKeys from '../utils/systemKeys.js';
|
|
3
|
+
import loadJs from '../utils/loadJs.js';
|
|
4
|
+
import loadJson from '../utils/loadJson.js';
|
|
5
|
+
import getParentPath from '../utils/getParentPath.js';
|
|
6
|
+
import getAbsolutePath from '../utils/getAbsolutePath.js';
|
|
7
|
+
import fixPackageName from '../utils/fixPackageName.js';
|
|
8
|
+
import getCMakeListsFilePath from '../utils/getCMakeListsFilePath.js';
|
|
9
|
+
import calculateDependencyParameters from './calculateDependencyParameters.js';
|
|
10
|
+
// import getCmakeParameters from './getCmakeParameters.js';
|
|
11
|
+
|
|
12
|
+
export default async function loadConfig(configDir = process.cwd(), configName = 'cppjs.config') {
|
|
13
|
+
const config = await loadJs(configDir, configName) || {};
|
|
14
|
+
const output = getFilledConfig(config);
|
|
15
|
+
output.build = await loadJs(configDir, 'cppjs.build');
|
|
16
|
+
|
|
17
|
+
output.paths.systemConfig = `${os.homedir()}/.cppjs.json`;
|
|
18
|
+
output.system = loadJson(output.paths.systemConfig) || {};
|
|
19
|
+
|
|
20
|
+
Object.entries(systemKeys).forEach(([key, value]) => {
|
|
21
|
+
if (!(key in output.system)) {
|
|
22
|
+
output.system[key] = value.default;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
return output;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function getFilledConfig(config, options = { isDepend: false }) {
|
|
30
|
+
const newConfig = {
|
|
31
|
+
general: config.general || {},
|
|
32
|
+
dependencies: (config.dependencies || []).map((d) => getFilledConfig(d, { isDepend: true })),
|
|
33
|
+
paths: config.paths || {},
|
|
34
|
+
ext: config.ext || {},
|
|
35
|
+
export: config.export || {},
|
|
36
|
+
platform: config.platform || {},
|
|
37
|
+
package: null,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
if (newConfig.paths.config && !newConfig.paths.project) {
|
|
41
|
+
newConfig.paths.project = getParentPath(newConfig.paths.config);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!newConfig.paths.project) {
|
|
45
|
+
newConfig.paths.project = process.cwd();
|
|
46
|
+
} else {
|
|
47
|
+
newConfig.paths.project = getAbsolutePath(null, newConfig.paths.project);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
newConfig.package = loadJson(`${newConfig.paths.project}/package.json`);
|
|
51
|
+
|
|
52
|
+
if (!newConfig?.general?.name) {
|
|
53
|
+
newConfig.general.name = fixPackageName(newConfig.package.name) || 'cppjssample';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const getPath = getAbsolutePath.bind(null, newConfig.paths.project);
|
|
57
|
+
|
|
58
|
+
newConfig.paths.base = getPath(newConfig.paths.base) || newConfig.paths.project;
|
|
59
|
+
newConfig.paths.cache = getPath(newConfig.paths.cache) || getPath('.cppjs');
|
|
60
|
+
newConfig.paths.build = getPath(newConfig.paths.build) || getPath(`${newConfig.paths.cache}/build`);
|
|
61
|
+
newConfig.paths.native = (newConfig.paths.native || ['src/native']).map((p) => getPath(p));
|
|
62
|
+
newConfig.paths.module = (newConfig.paths.module || newConfig.paths.native).map((p) => getPath(p));
|
|
63
|
+
newConfig.paths.header = (newConfig.paths.header || newConfig.paths.native).map((p) => getPath(p));
|
|
64
|
+
newConfig.paths.bridge = (newConfig.paths.bridge || [...newConfig.paths.native, newConfig.paths.build])
|
|
65
|
+
.map((p) => getPath(p));
|
|
66
|
+
newConfig.paths.output = getPath(newConfig.paths.output) || newConfig.paths.build;
|
|
67
|
+
newConfig.paths.cmake = options.isDepend ? getPath(getCMakeListsFilePath(newConfig.paths.output)) : (
|
|
68
|
+
getPath(newConfig.paths.cmake || getCMakeListsFilePath(newConfig.paths.project))
|
|
69
|
+
);
|
|
70
|
+
newConfig.paths.cmakeDir = getParentPath(newConfig.paths.cmake);
|
|
71
|
+
newConfig.paths.cli = getParentPath(getParentPath(import.meta.url));
|
|
72
|
+
newConfig.paths.cliCMakeListsTxt = `${newConfig.paths.cli}/assets/CMakeLists.txt`;
|
|
73
|
+
|
|
74
|
+
newConfig.ext.header = newConfig.ext.header || ['h', 'hpp', 'hxx', 'hh'];
|
|
75
|
+
newConfig.ext.source = newConfig.ext.source || ['c', 'cpp', 'cxx', 'cc'];
|
|
76
|
+
newConfig.ext.module = newConfig.ext.module || ['i'];
|
|
77
|
+
|
|
78
|
+
newConfig.export.type = newConfig.export.type || 'cmake';
|
|
79
|
+
newConfig.export.header = newConfig.export.header || 'include';
|
|
80
|
+
newConfig.export.libPath = getPath(newConfig.export.libPath || 'lib');
|
|
81
|
+
newConfig.export.libName = newConfig.export.libName || [newConfig.general.name];
|
|
82
|
+
newConfig.export.binHeaders = newConfig.export.binHeaders || [];
|
|
83
|
+
|
|
84
|
+
newConfig.platform['Emscripten-x86_64'] = newConfig.platform['Emscripten-x86_64'] || {};
|
|
85
|
+
newConfig.platform['Emscripten-x86_64-browser'] = newConfig.platform['Emscripten-x86_64-browser'] || {};
|
|
86
|
+
newConfig.platform['Emscripten-x86_64-node'] = newConfig.platform['Emscripten-x86_64-node'] || {};
|
|
87
|
+
newConfig.platform['Android-arm64-v8a'] = newConfig.platform['Android-arm64-v8a'] || {};
|
|
88
|
+
newConfig.platform['Android-x86_64'] = newConfig.platform['Android-x86_64'] || {};
|
|
89
|
+
newConfig.platform['iOS-iphoneos'] = newConfig.platform['iOS-iphoneos'] || {};
|
|
90
|
+
newConfig.platform['iOS-iphonesimulator'] = newConfig.platform['iOS-iphonesimulator'] || {};
|
|
91
|
+
|
|
92
|
+
newConfig.allDependencies = (() => {
|
|
93
|
+
const output = {};
|
|
94
|
+
[...newConfig.dependencies, ...newConfig.dependencies.map((d) => d.allDependencies).flat()].forEach((d) => {
|
|
95
|
+
output[d.paths.project] = d;
|
|
96
|
+
});
|
|
97
|
+
return Object.values(output);
|
|
98
|
+
})();
|
|
99
|
+
|
|
100
|
+
newConfig.dependencyParameters = calculateDependencyParameters(newConfig);
|
|
101
|
+
// newConfig.cmakeParameters = getCmakeParameters(newConfig);
|
|
102
|
+
|
|
103
|
+
return newConfig;
|
|
104
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs, { mkdirSync } from 'node:fs';
|
|
3
|
+
import fr from 'follow-redirects';
|
|
4
|
+
import decompress from 'decompress';
|
|
5
|
+
|
|
6
|
+
export default async function downloadAndExtractFile(url, output) {
|
|
7
|
+
if (fs.existsSync(`${output}/source`)) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
const filePath = await downloadFile(url, output);
|
|
11
|
+
const a = await decompress(filePath, output);
|
|
12
|
+
const oldFolder = a[0].path.split('/')[0];
|
|
13
|
+
fs.renameSync(`${output}/${oldFolder}`, `${output}/source`);
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function downloadFile(url, folder) {
|
|
18
|
+
mkdirSync(folder, { recursive: true });
|
|
19
|
+
return new Promise((resolve) => {
|
|
20
|
+
const filename = path.basename(url);
|
|
21
|
+
if (fs.existsSync(`${folder}/${filename}`)) {
|
|
22
|
+
resolve(`${folder}/${filename}`);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
fr.https.get(url, (res) => {
|
|
27
|
+
const fileStream = fs.createWriteStream(`${folder}/${filename}`);
|
|
28
|
+
res.pipe(fileStream);
|
|
29
|
+
|
|
30
|
+
fileStream.on('finish', () => {
|
|
31
|
+
fileStream.close();
|
|
32
|
+
resolve(`${folder}/${filename}`);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import upath from 'upath';
|
|
2
|
+
|
|
3
|
+
export default function getAbsolutePath(projectPath, path) {
|
|
4
|
+
if (!path) {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
if (upath.isAbsolute(path)) {
|
|
8
|
+
return upath.resolve(path);
|
|
9
|
+
}
|
|
10
|
+
if (projectPath) {
|
|
11
|
+
return upath.resolve(upath.join(upath.resolve(projectPath), path));
|
|
12
|
+
}
|
|
13
|
+
return upath.resolve(path);
|
|
14
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import getParentPath from './getParentPath.js';
|
|
2
|
+
import findFiles from './findFiles.js';
|
|
3
|
+
|
|
4
|
+
export default function getCMakeListsFilePath(basePath = process.cwd()) {
|
|
5
|
+
let temp = findFiles('CMakeLists.txt', { cwd: basePath });
|
|
6
|
+
if (temp.length === 0) {
|
|
7
|
+
temp = findFiles('*/CMakeLists.txt', { cwd: basePath, ignore: ['node_modules/*', 'dist/*', 'build/*'] });
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (temp.length > 0) return temp[0];
|
|
11
|
+
return getCliCMakeListsFile();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function getCliCMakeListsFile() {
|
|
15
|
+
const cliPath = getParentPath(getParentPath(import.meta.url));
|
|
16
|
+
return `${cliPath}/assets/CMakeLists.txt`;
|
|
17
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as url from 'node:url';
|
|
2
|
+
import upath from 'upath';
|
|
3
|
+
|
|
4
|
+
export default function getParentPath(importUrl) {
|
|
5
|
+
let input = importUrl;
|
|
6
|
+
try {
|
|
7
|
+
input = url.fileURLToPath(input);
|
|
8
|
+
} catch (e) { /* empty */ }
|
|
9
|
+
const filename = upath.normalize(input);
|
|
10
|
+
const temp = filename.split('/'); temp.pop();
|
|
11
|
+
return temp.join('/');
|
|
12
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
|
|
4
|
+
export function getFileHash(path) {
|
|
5
|
+
const data = fs.readFileSync(path);
|
|
6
|
+
return getContentHash(data);
|
|
7
|
+
/* return new Promise((resolve, reject) => {
|
|
8
|
+
const hash = createHash('sha256');
|
|
9
|
+
const rs = fs.createReadStream(path);
|
|
10
|
+
rs.on('error', reject);
|
|
11
|
+
rs.on('data', (chunk) => hash.update(chunk));
|
|
12
|
+
rs.on('end', () => resolve(hash.digest('hex')));
|
|
13
|
+
}); */
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function getContentHash(content) {
|
|
17
|
+
const hash = createHash('sha256');
|
|
18
|
+
hash.update(content);
|
|
19
|
+
return hash.digest('hex');
|
|
20
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
|
|
3
|
+
export default async function loadJs(path, fileName, fileExt = ['json', 'js', 'mjs', 'cjs', 'ts']) {
|
|
4
|
+
let filePath;
|
|
5
|
+
fileExt.some((e) => {
|
|
6
|
+
filePath = `${path}/${fileName}.${e}`;
|
|
7
|
+
if (!fs.existsSync(filePath)) {
|
|
8
|
+
filePath = null;
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
return true;
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
if (filePath) {
|
|
15
|
+
let file;
|
|
16
|
+
if (typeof module !== 'undefined' && module.exports) {
|
|
17
|
+
file = require(`file:///${filePath}`);
|
|
18
|
+
} else {
|
|
19
|
+
file = await import(`file:///${filePath}`);
|
|
20
|
+
}
|
|
21
|
+
if (file.default) file = file.default;
|
|
22
|
+
|
|
23
|
+
if (typeof file === 'function') {
|
|
24
|
+
return file();
|
|
25
|
+
}
|
|
26
|
+
if (typeof file === 'object') {
|
|
27
|
+
return file;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
|
|
3
|
+
export default function loadJson(filePath) {
|
|
4
|
+
if (!fs.existsSync(filePath)) {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
try {
|
|
9
|
+
const stateContent = fs.readFileSync(filePath, { encoding: 'utf8', flag: 'r' });
|
|
10
|
+
const state = JSON.parse(stateContent);
|
|
11
|
+
return state;
|
|
12
|
+
} catch (e) {
|
|
13
|
+
console.error(e);
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -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/.mocharc.yaml
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import getBaseInfo from '../utils/getBaseInfo.js';
|
|
2
|
-
import getPathInfo from '../utils/getPathInfo.js';
|
|
3
|
-
import { getDependencyParams } from './getCmakeParams.js';
|
|
4
|
-
import run from './run.js';
|
|
5
|
-
|
|
6
|
-
const platform = 'Emscripten-x86_64';
|
|
7
|
-
|
|
8
|
-
export default function createBridge(compiler) {
|
|
9
|
-
const bridges = [];
|
|
10
|
-
|
|
11
|
-
const allHeaders = getDependencyParams(compiler.config).headerPathWithDepends.split(';');
|
|
12
|
-
|
|
13
|
-
let includePath = [
|
|
14
|
-
...compiler.config.getAllDependencies().map((d) => `${d.paths.output}/prebuilt/${platform}/include`),
|
|
15
|
-
...compiler.config.getAllDependencies().map((d) => `${d.paths.output}/prebuilt/${platform}/swig`),
|
|
16
|
-
...compiler.config.paths.header,
|
|
17
|
-
...allHeaders,
|
|
18
|
-
].filter((path) => !!path.toString()).map((path) => `-I/tmp/cppjs/live/${getPathInfo(path, compiler.config.paths.base).relative}`);
|
|
19
|
-
includePath = [...new Set(includePath)];
|
|
20
|
-
|
|
21
|
-
compiler.interfaces.forEach((filePath) => {
|
|
22
|
-
const input = getPathInfo(filePath, compiler.config.paths.base);
|
|
23
|
-
const output = getPathInfo(`${compiler.config.paths.temp}/bridge`, compiler.config.paths.base);
|
|
24
|
-
const base = getBaseInfo(compiler.config.paths.base);
|
|
25
|
-
|
|
26
|
-
run(compiler, 'swig', [
|
|
27
|
-
'-c++',
|
|
28
|
-
'-embind',
|
|
29
|
-
'-o', `/tmp/cppjs/live/${output.relative}/${filePath.split('/').at(-1)}.cpp`,
|
|
30
|
-
...includePath,
|
|
31
|
-
`/tmp/cppjs/live/${input.relative}`,
|
|
32
|
-
]);
|
|
33
|
-
|
|
34
|
-
bridges.push(`${base.withSlash}${output.relative}/${filePath.split('/').at(-1)}.cpp`);
|
|
35
|
-
});
|
|
36
|
-
return bridges;
|
|
37
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import os from 'os';
|
|
3
|
-
import getCmakeParams from './getCmakeParams.js';
|
|
4
|
-
import getPathInfo from '../utils/getPathInfo.js';
|
|
5
|
-
|
|
6
|
-
const cpuCount = os.cpus().length - 1;
|
|
7
|
-
|
|
8
|
-
export default function createLib(compiler) {
|
|
9
|
-
if (!compiler.platform) return;
|
|
10
|
-
|
|
11
|
-
let platformParams = [];
|
|
12
|
-
switch (compiler.platform) {
|
|
13
|
-
case 'Emscripten-x86_64':
|
|
14
|
-
platformParams = ['-DBUILD_TYPE=STATIC'];
|
|
15
|
-
break;
|
|
16
|
-
case 'Android-arm64-v8a':
|
|
17
|
-
platformParams = ['-DBUILD_TYPE=SHARED'];
|
|
18
|
-
break;
|
|
19
|
-
case 'iOS-iphoneos':
|
|
20
|
-
platformParams = ['-DBUILD_TYPE=STATIC'];
|
|
21
|
-
break;
|
|
22
|
-
case 'iOS-iphonesimulator':
|
|
23
|
-
platformParams = ['-DBUILD_TYPE=STATIC'];
|
|
24
|
-
break;
|
|
25
|
-
default:
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const libdir = `${getPathInfo(compiler.config.paths.output, compiler.config.paths.base).relative}/prebuilt/${compiler.platform}`;
|
|
29
|
-
const basePlatform = compiler.platform.split('-', 1)[0];
|
|
30
|
-
const params = getCmakeParams(compiler.config, '/tmp/cppjs/live/', true, false);
|
|
31
|
-
compiler.run(null, [
|
|
32
|
-
basePlatform === 'iOS' ? 'ios-cmake' : 'cmake', '/tmp/cppjs/cmake',
|
|
33
|
-
'-DCMAKE_BUILD_TYPE=Release', ...platformParams,
|
|
34
|
-
`-DCMAKE_INSTALL_PREFIX=/tmp/cppjs/live/${libdir}`, `-DPROJECT_NAME=${compiler.config.general.name}`,
|
|
35
|
-
...params,
|
|
36
|
-
]);
|
|
37
|
-
if (basePlatform === 'iOS') {
|
|
38
|
-
compiler.run(null, ['ios-cmake', '--build', '.', '--config', 'Release', '--target', 'install']);
|
|
39
|
-
} else {
|
|
40
|
-
compiler.run(null, ['make', `-j${cpuCount}`, 'install']);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
fs.rmSync(compiler.config.paths.temp, { recursive: true, force: true });
|
|
44
|
-
}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import buildJS from './buildJS.js';
|
|
3
|
-
import run from './run.js';
|
|
4
|
-
import getCmakeParams from './getCmakeParams.js';
|
|
5
|
-
import getLibs from './getLibs.js';
|
|
6
|
-
import getData from './getData.js';
|
|
7
|
-
import getPathInfo from '../utils/getPathInfo.js';
|
|
8
|
-
|
|
9
|
-
export default async function createWasm(compiler, options = {}) {
|
|
10
|
-
const output = `/tmp/cppjs/live/${getPathInfo(compiler.config.paths.temp, compiler.config.paths.base).relative}`;
|
|
11
|
-
|
|
12
|
-
let params = getCmakeParams(compiler.config, '/tmp/cppjs/live/', true, false);
|
|
13
|
-
run(compiler, 'emcmake', [
|
|
14
|
-
'cmake', '/tmp/cppjs/cmake',
|
|
15
|
-
'-DCMAKE_BUILD_TYPE=Release', '-DBUILD_TYPE=STATIC',
|
|
16
|
-
`-DCMAKE_INSTALL_PREFIX=${output}`, `-DPROJECT_NAME=${compiler.config.general.name}`,
|
|
17
|
-
...params,
|
|
18
|
-
]);
|
|
19
|
-
run(compiler, 'emmake', ['make', 'install']);
|
|
20
|
-
|
|
21
|
-
params = getCmakeParams(compiler.config, '/tmp/cppjs/live/', false, true);
|
|
22
|
-
run(compiler, 'emcmake', [
|
|
23
|
-
'cmake', '/tmp/cppjs/cmake',
|
|
24
|
-
'-DCMAKE_BUILD_TYPE=Release', '-DBUILD_TYPE=STATIC',
|
|
25
|
-
`-DCMAKE_INSTALL_PREFIX=${output}`, `-DPROJECT_NAME=${compiler.config.general.name}bridge`,
|
|
26
|
-
...params,
|
|
27
|
-
]);
|
|
28
|
-
run(compiler, 'emmake', ['make', 'install']);
|
|
29
|
-
|
|
30
|
-
const libs = getLibs(compiler.config, '/tmp/cppjs/live/');
|
|
31
|
-
const data = Object.entries(getData(compiler.config, 'data', '/tmp/cppjs/live/', 'Emscripten-x86_64', 'browser')).map(([key, value]) => ['--preload-file', `${key.replaceAll('@', '@@')}@${value}`]).flat();
|
|
32
|
-
run(compiler, 'emcc', [
|
|
33
|
-
'-lembind', '-Wl,--whole-archive',
|
|
34
|
-
...libs, ...(options.cc || []),
|
|
35
|
-
'-s', 'WASM=1', '-s', 'MODULARIZE=1', '-s', 'DYNAMIC_EXECUTION=0',
|
|
36
|
-
'-s', 'RESERVED_FUNCTION_POINTERS=200', '-s', 'DISABLE_EXCEPTION_CATCHING=0', '-s', 'FORCE_FILESYSTEM=1',
|
|
37
|
-
'-s', 'ALLOW_MEMORY_GROWTH=1',
|
|
38
|
-
'-s', 'EXPORTED_RUNTIME_METHODS=["FS", "ENV"]',
|
|
39
|
-
'-o', `${output}/${compiler.config.general.name}.js`,
|
|
40
|
-
...data,
|
|
41
|
-
]);
|
|
42
|
-
await buildJS(compiler, `${compiler.config.paths.temp}/${compiler.config.general.name}.js`, 'browser');
|
|
43
|
-
run(compiler, 'emcc', [
|
|
44
|
-
'-lembind', '-Wl,--whole-archive', '-lnodefs.js',
|
|
45
|
-
...libs, ...(options.cc || []),
|
|
46
|
-
'-s', 'WASM=1', '-s', 'MODULARIZE=1', '-s', 'DYNAMIC_EXECUTION=0',
|
|
47
|
-
'-s', 'RESERVED_FUNCTION_POINTERS=200', '-s', 'DISABLE_EXCEPTION_CATCHING=0', '-s', 'FORCE_FILESYSTEM=1', '-s', 'NODERAWFS',
|
|
48
|
-
'-s', 'ALLOW_MEMORY_GROWTH=1',
|
|
49
|
-
'-s', 'EXPORTED_RUNTIME_METHODS=["FS", "ENV", "NODEFS"]',
|
|
50
|
-
'-o', `${output}/${compiler.config.general.name}.js`,
|
|
51
|
-
]);
|
|
52
|
-
Object.entries(getData(compiler.config, 'data', null, 'Emscripten-x86_64', 'node')).forEach(([key, value]) => {
|
|
53
|
-
if (fs.existsSync(key)) {
|
|
54
|
-
const dAssetPath = `${compiler.config.paths.temp}/data/${value}`;
|
|
55
|
-
if (!fs.existsSync(dAssetPath)) {
|
|
56
|
-
fs.mkdirSync(dAssetPath, { recursive: true });
|
|
57
|
-
fs.cpSync(key, dAssetPath, { recursive: true });
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
await buildJS(compiler, `${compiler.config.paths.temp}/${compiler.config.general.name}.js`, 'node');
|
|
62
|
-
if (fs.existsSync(`${compiler.config.paths.temp}/${compiler.config.general.name}.data`)) {
|
|
63
|
-
fs.renameSync(`${compiler.config.paths.temp}/${compiler.config.general.name}.data`, `${compiler.config.paths.temp}/${compiler.config.general.name}.data.txt`);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return compiler.config.paths.temp;
|
|
67
|
-
}
|