cpp.js 1.0.0-beta.2 → 1.0.0-beta.20
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 +101 -0
- package/package.json +22 -6
- package/src/{functions/buildJS.js → actions/buildJs.js} +7 -5
- package/src/actions/buildWasm.js +68 -0
- package/src/actions/createInterface.js +127 -0
- package/src/actions/createLib.js +40 -0
- package/src/actions/createXCFramework.js +40 -0
- package/src/actions/getAllBridges.js +8 -0
- package/src/actions/getCmakeParameters.js +48 -0
- package/src/actions/getData.js +28 -0
- package/src/actions/getDependLibs.js +19 -0
- package/src/{functions → actions}/run.js +52 -30
- package/src/assets/CMakeLists.txt +13 -9
- package/src/assets/ios.toolchain.cmake +4 -4
- package/src/bin.js +42 -73
- package/src/index.js +10 -63
- package/src/state/calculateDependencyParameters.js +64 -0
- package/src/state/index.js +44 -0
- package/src/state/loadConfig.js +89 -0
- package/src/utils/fixPackageName.js +7 -0
- package/src/utils/getAbsolutePath.js +14 -0
- package/src/utils/{findCMakeListsFile.js → getCMakeListsFilePath.js} +4 -3
- package/src/utils/getOsUserAndGroupId.js +2 -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 +1 -1
- 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 -71
- 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/getBaseInfo.js +0 -15
- package/src/utils/getCliPath.js +0 -11
- package/src/utils/getConfig.js +0 -170
- package/src/utils/getDirName.js +0 -7
- 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.cpp +0 -0
- package/test/data/sample2.ei +0 -12
- package/test/data/sample2.h +0 -10
|
@@ -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 path;
|
|
9
|
+
}
|
|
10
|
+
if (projectPath) {
|
|
11
|
+
return upath.resolve(upath.join(upath.resolve(projectPath), path));
|
|
12
|
+
}
|
|
13
|
+
return upath.resolve(path);
|
|
14
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import glob from 'glob';
|
|
2
|
-
import
|
|
2
|
+
import getParentPath from './getParentPath.js';
|
|
3
3
|
|
|
4
|
-
export default function
|
|
4
|
+
export default function getCMakeListsFilePath(basePath = process.cwd()) {
|
|
5
5
|
let temp = glob.sync('CMakeLists.txt', { absolute: true, cwd: basePath });
|
|
6
6
|
if (temp.length === 0) {
|
|
7
7
|
temp = glob.sync('*/CMakeLists.txt', { absolute: true, cwd: basePath, ignore: ['node_modules/*', 'dist/*', 'build/*'] });
|
|
@@ -12,5 +12,6 @@ export default function findCMakeListsFile(basePath = process.cwd()) {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export function getCliCMakeListsFile() {
|
|
15
|
-
|
|
15
|
+
const cliPath = getParentPath(getParentPath(import.meta.url));
|
|
16
|
+
return `${cliPath}/assets/CMakeLists.txt`;
|
|
16
17
|
}
|
|
@@ -4,7 +4,8 @@ let osUserAndGroupId;
|
|
|
4
4
|
export default function getOsUserAndGroupId() {
|
|
5
5
|
const userInfo = os.userInfo();
|
|
6
6
|
if (!osUserAndGroupId) {
|
|
7
|
-
|
|
7
|
+
const isInvalid = userInfo.uid === -1 && userInfo.gid === -1;
|
|
8
|
+
osUserAndGroupId = isInvalid ? '0:0' : `${userInfo.uid}:${userInfo.gid}`;
|
|
8
9
|
}
|
|
9
10
|
return osUserAndGroupId;
|
|
10
11
|
}
|
|
@@ -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
|
+
}
|
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,71 +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 = {}, buildAll = false) {
|
|
10
|
-
if (fs.existsSync('/tmp/cppjs/live')) fs.unlinkSync('/tmp/cppjs/live');
|
|
11
|
-
fs.symlinkSync(compiler.config.paths.base, '/tmp/cppjs/live');
|
|
12
|
-
|
|
13
|
-
const output = `/tmp/cppjs/live/${getPathInfo(compiler.config.paths.temp, compiler.config.paths.base).relative}`;
|
|
14
|
-
|
|
15
|
-
let params = getCmakeParams(compiler.config, '/tmp/cppjs/live/', true, false);
|
|
16
|
-
run(compiler, 'emcmake', [
|
|
17
|
-
'cmake', '/tmp/cppjs/cmake',
|
|
18
|
-
'-DCMAKE_BUILD_TYPE=Release', '-DBUILD_TYPE=STATIC',
|
|
19
|
-
`-DCMAKE_INSTALL_PREFIX=${output}`, `-DPROJECT_NAME=${compiler.config.general.name}`,
|
|
20
|
-
...params,
|
|
21
|
-
]);
|
|
22
|
-
run(compiler, 'emmake', ['make', 'install']);
|
|
23
|
-
|
|
24
|
-
params = getCmakeParams(compiler.config, '/tmp/cppjs/live/', false, true);
|
|
25
|
-
run(compiler, 'emcmake', [
|
|
26
|
-
'cmake', '/tmp/cppjs/cmake',
|
|
27
|
-
'-DCMAKE_BUILD_TYPE=Release', '-DBUILD_TYPE=STATIC',
|
|
28
|
-
`-DCMAKE_INSTALL_PREFIX=${output}`, `-DPROJECT_NAME=${compiler.config.general.name}bridge`,
|
|
29
|
-
...params,
|
|
30
|
-
]);
|
|
31
|
-
run(compiler, 'emmake', ['make', 'install']);
|
|
32
|
-
|
|
33
|
-
const libs = getLibs(compiler.config, '/tmp/cppjs/live/');
|
|
34
|
-
const data = Object.entries(getData(compiler.config, 'data', '/tmp/cppjs/live/', 'Emscripten-x86_64', 'browser')).map(([key, value]) => ['--preload-file', `${key.replaceAll('@', '@@')}@${value}`]).flat();
|
|
35
|
-
run(compiler, 'emcc', [
|
|
36
|
-
'-lembind', '-Wl,--whole-archive',
|
|
37
|
-
...libs, ...(options.cc || []),
|
|
38
|
-
'-s', 'WASM=1', '-s', 'MODULARIZE=1', '-s', 'DYNAMIC_EXECUTION=0',
|
|
39
|
-
'-s', 'RESERVED_FUNCTION_POINTERS=200', '-s', 'DISABLE_EXCEPTION_CATCHING=0', '-s', 'FORCE_FILESYSTEM=1',
|
|
40
|
-
'-s', 'ALLOW_MEMORY_GROWTH=1',
|
|
41
|
-
'-s', 'EXPORTED_RUNTIME_METHODS=["FS", "ENV"]',
|
|
42
|
-
'-o', `${output}/${compiler.config.general.name}.js`,
|
|
43
|
-
...data,
|
|
44
|
-
]);
|
|
45
|
-
await buildJS(compiler, `${output}/${compiler.config.general.name}.js`, 'browser');
|
|
46
|
-
run(compiler, 'emcc', [
|
|
47
|
-
'-lembind', '-Wl,--whole-archive', '-lnodefs.js',
|
|
48
|
-
...libs, ...(options.cc || []),
|
|
49
|
-
'-s', 'WASM=1', '-s', 'MODULARIZE=1', '-s', 'DYNAMIC_EXECUTION=0',
|
|
50
|
-
'-s', 'RESERVED_FUNCTION_POINTERS=200', '-s', 'DISABLE_EXCEPTION_CATCHING=0', '-s', 'FORCE_FILESYSTEM=1', '-s', 'NODERAWFS',
|
|
51
|
-
'-s', 'ALLOW_MEMORY_GROWTH=1',
|
|
52
|
-
'-s', 'EXPORTED_RUNTIME_METHODS=["FS", "ENV", "NODEFS"]',
|
|
53
|
-
'-o', `${output}/${compiler.config.general.name}.js`,
|
|
54
|
-
]);
|
|
55
|
-
Object.entries(getData(compiler.config, 'data', null, 'Emscripten-x86_64', 'node')).forEach(([key, value]) => {
|
|
56
|
-
if (fs.existsSync(key)) {
|
|
57
|
-
const dAssetPath = `${output}/data/${value}`;
|
|
58
|
-
if (!fs.existsSync(dAssetPath)) {
|
|
59
|
-
fs.mkdirSync(dAssetPath, { recursive: true });
|
|
60
|
-
fs.cpSync(key, dAssetPath, { recursive: true });
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
await buildJS(compiler, `${output}/${compiler.config.general.name}.js`, 'node');
|
|
65
|
-
// await buildJS(compiler, `${output}/${compiler.config.general.name}.js`);
|
|
66
|
-
if (fs.existsSync(`${compiler.config.paths.temp}/${compiler.config.general.name}.data`)) {
|
|
67
|
-
fs.renameSync(`${compiler.config.paths.temp}/${compiler.config.general.name}.data`, `${compiler.config.paths.temp}/${compiler.config.general.name}.data.txt`);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return compiler.config.paths.temp;
|
|
71
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/* eslint-disable prefer-destructuring */
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import getBaseInfo from '../utils/getBaseInfo.js';
|
|
4
|
-
import getPathInfo from '../utils/getPathInfo.js';
|
|
5
|
-
import { getDependencyParams } from './getCmakeParams.js';
|
|
6
|
-
|
|
7
|
-
export default function findOrCreateInterfaceFile(compiler, filePath) {
|
|
8
|
-
const moduleRegex = new RegExp(`.(${compiler.config.ext.module.join('|')})$`);
|
|
9
|
-
if (moduleRegex.test(filePath) && fs.existsSync(filePath)) {
|
|
10
|
-
const newPath = `${compiler.config.paths.temp}/interface/${filePath.split('/').pop()}`;
|
|
11
|
-
fs.copyFileSync(filePath, newPath);
|
|
12
|
-
compiler.interfaces.push(newPath);
|
|
13
|
-
return filePath;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const input = getPathInfo(filePath, compiler.config.paths.base);
|
|
17
|
-
const output = getPathInfo(`${compiler.config.paths.temp}/interface`, compiler.config.paths.base);
|
|
18
|
-
const base = getBaseInfo(compiler.config.paths.base);
|
|
19
|
-
|
|
20
|
-
const headerPaths = (getDependencyParams(compiler.config)?.pathsOfCmakeDepends?.split(';') || [])
|
|
21
|
-
.filter((d) => d.startsWith(compiler.config.paths.base))
|
|
22
|
-
.map((d) => d.replace(`${compiler.config.paths.base}/`, ''));
|
|
23
|
-
|
|
24
|
-
const temp2 = headerPaths
|
|
25
|
-
.map((p) => input.relative.match(new RegExp(`^${p}/.*?/include/(.*?)$`, 'i')))
|
|
26
|
-
.filter((p) => p && p.length === 2);
|
|
27
|
-
|
|
28
|
-
const temp = input.relative.match(/^(.*)\..+?$/);
|
|
29
|
-
if (temp.length < 2) return null;
|
|
30
|
-
|
|
31
|
-
const filePathWithoutExt = temp[1];
|
|
32
|
-
const interfaceFile = `${compiler.config.paths.base}/${filePathWithoutExt}.i`;
|
|
33
|
-
|
|
34
|
-
if (fs.existsSync(interfaceFile)) {
|
|
35
|
-
compiler.interfaces.push(interfaceFile);
|
|
36
|
-
return interfaceFile;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const fileName = filePathWithoutExt.split('/').at(-1);
|
|
40
|
-
|
|
41
|
-
let headerPath = compiler.config.paths.header.find((path) => filePath.startsWith(path));
|
|
42
|
-
if (headerPath) headerPath = filePath.substr(headerPath.length + 1);
|
|
43
|
-
else if (temp2 && temp2.length > 0) headerPath = temp2[0][1];
|
|
44
|
-
else headerPath = input.relative.split('/').at(-1);
|
|
45
|
-
|
|
46
|
-
const content = `#ifndef _${fileName.toUpperCase()}_I
|
|
47
|
-
#define _${fileName.toUpperCase()}_I
|
|
48
|
-
|
|
49
|
-
%module ${fileName.toUpperCase()}
|
|
50
|
-
|
|
51
|
-
%{
|
|
52
|
-
#include "${headerPath}"
|
|
53
|
-
%}
|
|
54
|
-
|
|
55
|
-
%feature("shared_ptr");
|
|
56
|
-
%feature("polymorphic_shared_ptr");
|
|
57
|
-
|
|
58
|
-
%include "${headerPath}"
|
|
59
|
-
|
|
60
|
-
#endif
|
|
61
|
-
`;
|
|
62
|
-
const outputFilePath = `${base.withSlash + output.relative}/${fileName}.i`;
|
|
63
|
-
fs.writeFileSync(outputFilePath, content);
|
|
64
|
-
|
|
65
|
-
compiler.interfaces.push(outputFilePath);
|
|
66
|
-
|
|
67
|
-
return outputFilePath;
|
|
68
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import { execFileSync } from 'child_process';
|
|
3
|
-
import getPathInfo from '../utils/getPathInfo.js';
|
|
4
|
-
|
|
5
|
-
export default function finishBuild(compiler) {
|
|
6
|
-
const output = getPathInfo(compiler.config.paths.output, compiler.config.paths.base);
|
|
7
|
-
if (
|
|
8
|
-
!fs.existsSync(`${output.absolute}/prebuilt/iOS-iphoneos/lib`)
|
|
9
|
-
|| !fs.existsSync(`${output.absolute}/prebuilt/iOS-iphonesimulator/lib`)
|
|
10
|
-
) return;
|
|
11
|
-
|
|
12
|
-
const options = {
|
|
13
|
-
cwd: `${output.absolute}/prebuilt`,
|
|
14
|
-
stdio: 'inherit',
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
compiler.config.export.libName.forEach((fileName) => {
|
|
18
|
-
if (!fs.existsSync(`${options.cwd}/${fileName}.xcframework`)) {
|
|
19
|
-
const params = [
|
|
20
|
-
'-create-xcframework',
|
|
21
|
-
'-library', `iOS-iphoneos/lib/lib${fileName}.a`,
|
|
22
|
-
'-headers', 'iOS-iphoneos/include',
|
|
23
|
-
'-library', `iOS-iphonesimulator/lib/lib${fileName}.a`,
|
|
24
|
-
'-headers', 'iOS-iphonesimulator/include',
|
|
25
|
-
'-output', `${fileName}.xcframework`,
|
|
26
|
-
];
|
|
27
|
-
execFileSync('xcodebuild', params, options);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (!fs.existsSync(`${options.cwd}/${fileName}.xcframework.zip`)) {
|
|
31
|
-
execFileSync('zip', ['-y', '-r', `./${fileName}.xcframework.zip`, `${fileName}.xcframework`], options);
|
|
32
|
-
}
|
|
33
|
-
if (!fs.existsSync(`${compiler.config.paths.project}/${fileName}.xcframework`)) {
|
|
34
|
-
fs.symlinkSync(`${options.cwd}/${fileName}.xcframework`, `${compiler.config.paths.project}/${fileName}.xcframework`);
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
/* if (fs.existsSync(`${output.absolute}/prebuilt/iOS-iphoneos`)) {
|
|
38
|
-
fs.rmSync(`${output.absolute}/prebuilt/iOS-iphoneos`, { recursive: true, force: true });
|
|
39
|
-
}
|
|
40
|
-
if (fs.existsSync(`${output.absolute}/prebuilt/iOS-iphonesimulator`)) {
|
|
41
|
-
fs.rmSync(`${output.absolute}/prebuilt/iOS-iphonesimulator`, { recursive: true, force: true });
|
|
42
|
-
} */
|
|
43
|
-
}
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import getPathInfo from '../utils/getPathInfo.js';
|
|
2
|
-
import { getCliCMakeListsFile } from '../utils/findCMakeListsFile.js';
|
|
3
|
-
|
|
4
|
-
function setPath(arr, dependency, type, filter = () => {}) {
|
|
5
|
-
if (filter(dependency)) {
|
|
6
|
-
if (type === 'this') {
|
|
7
|
-
arr.push(dependency);
|
|
8
|
-
} else if (Array.isArray(dependency.paths[type])) {
|
|
9
|
-
arr.push(...dependency.paths[type]);
|
|
10
|
-
} else {
|
|
11
|
-
arr.push(dependency.paths[type]);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
dependency.dependencies.forEach((dep) => {
|
|
16
|
-
setPath(arr, dep, type, filter);
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function getParentPath(path) {
|
|
21
|
-
const pathArray = path.split('/');
|
|
22
|
-
pathArray.pop();
|
|
23
|
-
return pathArray.join('/');
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function getPath(config, path, pathPrefix) {
|
|
27
|
-
if (!pathPrefix) {
|
|
28
|
-
return getPathInfo(path, config.paths.base).absolute;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return `${pathPrefix}${getPathInfo(path, config.paths.base).relative}`;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const dependencyParams = {};
|
|
35
|
-
export function getDependencyParams(config, pathPrefix) {
|
|
36
|
-
if (dependencyParams && dependencyParams[pathPrefix || 'empty']) {
|
|
37
|
-
return dependencyParams[pathPrefix || 'empty'];
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const sourceFilter = (d) => d === config || d.export.type === 'source';
|
|
41
|
-
let headerPathWithDepends = [];
|
|
42
|
-
setPath(headerPathWithDepends, config, 'header', sourceFilter);
|
|
43
|
-
headerPathWithDepends = [...new Set(headerPathWithDepends.map((p) => getPath(config, p, pathPrefix)))].join(';');
|
|
44
|
-
|
|
45
|
-
const headerGlob = [];
|
|
46
|
-
headerPathWithDepends.split(';').forEach((h) => {
|
|
47
|
-
config.ext.header.forEach((ext) => {
|
|
48
|
-
headerGlob.push(`${h}/*.${ext}`);
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
let nativePathWithDepends = [];
|
|
53
|
-
setPath(nativePathWithDepends, config, 'native', sourceFilter);
|
|
54
|
-
nativePathWithDepends = [...new Set(nativePathWithDepends.map((p) => getPath(config, p, pathPrefix)))].join(';');
|
|
55
|
-
|
|
56
|
-
const nativeGlob = [];
|
|
57
|
-
nativePathWithDepends.split(';').forEach((h) => {
|
|
58
|
-
config.ext.source.forEach((ext) => {
|
|
59
|
-
nativeGlob.push(`${h}/*.${ext}`);
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
const cliCMakeListsFile = getCliCMakeListsFile();
|
|
64
|
-
const cmakeFilter = (d) => d !== config && d.export.type === 'cmake' && d.paths.cmake !== cliCMakeListsFile;
|
|
65
|
-
let cmakeDepends = [];
|
|
66
|
-
setPath(cmakeDepends, config, 'this', cmakeFilter);
|
|
67
|
-
cmakeDepends = [...new Set(cmakeDepends)];
|
|
68
|
-
|
|
69
|
-
const pathsOfCmakeDepends = [...new Set(cmakeDepends
|
|
70
|
-
.map((d) => getParentPath(d.paths.cmake))
|
|
71
|
-
.map((p) => getPath(config, p, pathPrefix)))].join(';');
|
|
72
|
-
const nameOfCmakeDepends = [...new Set(cmakeDepends.map((d) => d.general.name))].join(';');
|
|
73
|
-
|
|
74
|
-
dependencyParams[pathPrefix || 'empty'] = {
|
|
75
|
-
nativeGlob,
|
|
76
|
-
headerGlob,
|
|
77
|
-
headerPathWithDepends,
|
|
78
|
-
cmakeDepends,
|
|
79
|
-
pathsOfCmakeDepends,
|
|
80
|
-
nameOfCmakeDepends,
|
|
81
|
-
};
|
|
82
|
-
return dependencyParams[pathPrefix || 'empty'];
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export default function getCmakeParams(config, pathPrefix, isBuildSource, isBuildBridge) {
|
|
86
|
-
const params = [];
|
|
87
|
-
if (isBuildSource) params.push('-DBUILD_SOURCE=TRUE');
|
|
88
|
-
if (isBuildBridge) params.push('-DBUILD_BRIDGE=TRUE');
|
|
89
|
-
|
|
90
|
-
const output = getPath(config, config.paths.temp, pathPrefix);
|
|
91
|
-
const projectPath = getPath(config, process.cwd(), pathPrefix);
|
|
92
|
-
|
|
93
|
-
const dependParams = getDependencyParams(config, pathPrefix);
|
|
94
|
-
|
|
95
|
-
params.push(...[
|
|
96
|
-
`-DBASE_DIR=${projectPath}`,
|
|
97
|
-
`-DNATIVE_GLOB=${dependParams.nativeGlob.join(';')}`,
|
|
98
|
-
`-DHEADER_GLOB=${dependParams.headerGlob.join(';')}`,
|
|
99
|
-
`-DHEADER_DIR=${dependParams.headerPathWithDepends}`,
|
|
100
|
-
`-DDEPENDS_CMAKE_PATHS=${dependParams.pathsOfCmakeDepends}`,
|
|
101
|
-
`-DDEPENDS_CMAKE_NAMES=${dependParams.nameOfCmakeDepends}`,
|
|
102
|
-
`-DBRIDGE_DIR=${output}/bridge`,
|
|
103
|
-
]);
|
|
104
|
-
|
|
105
|
-
return params;
|
|
106
|
-
}
|
package/src/functions/getData.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/* eslint-disable default-param-last */
|
|
2
|
-
/* eslint-disable no-param-reassign */
|
|
3
|
-
import getPathInfo from '../utils/getPathInfo.js';
|
|
4
|
-
|
|
5
|
-
function getPath(config, path, pathPrefix) {
|
|
6
|
-
if (!pathPrefix) {
|
|
7
|
-
return getPathInfo(path, config.paths.base).absolute;
|
|
8
|
-
}
|
|
9
|
-
return `${pathPrefix}${getPathInfo(path, config.paths.base).relative}`;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function getRecursiveData(obj, config, dependency, field, pathPrefix, platform, subPlatform) {
|
|
13
|
-
const platformName = subPlatform ? `${platform}-${subPlatform}` : platform;
|
|
14
|
-
if (dependency?.platform?.[platformName]?.[field]) {
|
|
15
|
-
Object.entries(dependency.platform[platformName][field]).forEach(([dKey, value]) => {
|
|
16
|
-
if (field === 'data') {
|
|
17
|
-
const a = `${dependency.paths.project}/dist/prebuilt/${platform}/${dKey}`;
|
|
18
|
-
const key = getPath(config, a, pathPrefix);
|
|
19
|
-
obj[key] = value;
|
|
20
|
-
} else {
|
|
21
|
-
obj[dKey] = value;
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
dependency.dependencies.forEach((dep) => {
|
|
27
|
-
getRecursiveData(obj, config, dep, field, pathPrefix, platform, subPlatform);
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export default function getData(config, field, pathPrefix, platform = 'Emscripten-x86_64', subPlatform) {
|
|
32
|
-
const output = {};
|
|
33
|
-
getRecursiveData(output, config, config, field, pathPrefix, platform, subPlatform);
|
|
34
|
-
|
|
35
|
-
return output;
|
|
36
|
-
}
|
package/src/functions/getLibs.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import glob from 'glob';
|
|
2
|
-
import getPathInfo from '../utils/getPathInfo.js';
|
|
3
|
-
import { getDependencyParams } from './getCmakeParams.js';
|
|
4
|
-
|
|
5
|
-
function getPath(config, path, pathPrefix) {
|
|
6
|
-
if (!pathPrefix) {
|
|
7
|
-
return getPathInfo(path, config.paths.base).absolute;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
return `${pathPrefix}${getPathInfo(path, config.paths.base).relative}`;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export default function getLibs(config, pathPrefix) {
|
|
14
|
-
let dependLibs = [
|
|
15
|
-
...glob.sync(`${config.paths.temp}/dependencies/**/*.a`, { absolute: true, cwd: config.paths.project }),
|
|
16
|
-
];
|
|
17
|
-
getDependencyParams(config, pathPrefix).cmakeDepends.forEach((d) => {
|
|
18
|
-
if (d.export.libName) {
|
|
19
|
-
d.export.libName.forEach((fileName) => {
|
|
20
|
-
if (d.platform['Emscripten-x86_64'].ignoreLibName?.includes(fileName)) return;
|
|
21
|
-
dependLibs.push(...glob.sync(`${d.paths.output}/prebuilt/Emscripten-x86_64/lib/lib${fileName}.a`, { absolute: true, cwd: d.paths.project }));
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
dependLibs = [...new Set(dependLibs)];
|
|
27
|
-
|
|
28
|
-
return [...new Set([
|
|
29
|
-
`${config.paths.temp}/lib${config.general.name}.a`,
|
|
30
|
-
`${config.paths.temp}/lib${config.general.name}bridge.a`,
|
|
31
|
-
...dependLibs,
|
|
32
|
-
].filter((path) => !!path.toString()).map((path) => getPath(config, path, pathPrefix)))];
|
|
33
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { assert } from 'chai';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import p, { dirname } from 'path';
|
|
4
|
-
import * as url from 'node:url';
|
|
5
|
-
import { tmpdir } from 'os';
|
|
6
|
-
import createBridge from './createBridge.js';
|
|
7
|
-
|
|
8
|
-
const __filename = url.fileURLToPath(import.meta.url);
|
|
9
|
-
const temp = __filename.split('/');
|
|
10
|
-
temp.pop();
|
|
11
|
-
temp.pop();
|
|
12
|
-
const __dirname = temp.join('/');
|
|
13
|
-
|
|
14
|
-
export function createTempDir(folder) {
|
|
15
|
-
let path = p.join(tmpdir(), 'cppjs-app-cli-test');
|
|
16
|
-
if (folder) path = p.join(path, folder);
|
|
17
|
-
|
|
18
|
-
if (fs.existsSync(path)) fs.rmSync(path, { recursive: true, force: true });
|
|
19
|
-
fs.mkdirSync(path, { recursive: true });
|
|
20
|
-
|
|
21
|
-
return path;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
describe('createBridge', () => {
|
|
25
|
-
let tempdir;
|
|
26
|
-
before(async () => {
|
|
27
|
-
tempdir = createTempDir();
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('createBridge', async () => {
|
|
31
|
-
const path = `${__dirname}/test/data/sample.i`;
|
|
32
|
-
const bridgeFilePath = createBridge(path, tempdir);
|
|
33
|
-
const bridgeFileData = fs.readFileSync(bridgeFilePath, 'utf8');
|
|
34
|
-
|
|
35
|
-
const startIndex = bridgeFileData.indexOf('#include <emscripten/bind.h>');
|
|
36
|
-
const bridgeFileDataTrim = bridgeFileData.substring(startIndex, bridgeFileData.length).trim();
|
|
37
|
-
|
|
38
|
-
const expectedContent = `#include <emscripten/bind.h>
|
|
39
|
-
|
|
40
|
-
#include "sample.h"
|
|
41
|
-
|
|
42
|
-
EMSCRIPTEN_BINDINGS(Sample) {
|
|
43
|
-
emscripten::class_<Sample>("Sample")
|
|
44
|
-
.constructor<>()
|
|
45
|
-
.function("t", &Sample::t)
|
|
46
|
-
;
|
|
47
|
-
}
|
|
48
|
-
`.trim();
|
|
49
|
-
assert.equal(bridgeFileDataTrim, expectedContent);
|
|
50
|
-
});
|
|
51
|
-
});
|