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
|
@@ -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
|
-
});
|
|
@@ -1,49 +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 findOrCreateInterfaceFile from './findOrCreateInterfaceFile.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('findOrCreateInterfaceFile', () => {
|
|
25
|
-
let tempdir;
|
|
26
|
-
before(async () => {
|
|
27
|
-
tempdir = createTempDir();
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('find interface file', async () => {
|
|
31
|
-
const path = `${__dirname}/test/data/sample.h`;
|
|
32
|
-
const interfaceFile = findOrCreateInterfaceFile(path, tempdir);
|
|
33
|
-
assert.equal(interfaceFile, path.replace('.h', '.i'));
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('create interface file', async () => {
|
|
37
|
-
const path = `${__dirname}/test/data/sample2.h`;
|
|
38
|
-
const interfaceFile = findOrCreateInterfaceFile(path, tempdir);
|
|
39
|
-
const interfaceFileData = fs.readFileSync(interfaceFile, 'utf8');
|
|
40
|
-
|
|
41
|
-
const path2 = `${__dirname}/test/data/sample2.ei`;
|
|
42
|
-
const interfaceFileData2 = fs.readFileSync(path2, 'utf8');
|
|
43
|
-
|
|
44
|
-
assert.equal(
|
|
45
|
-
interfaceFileData.trim().replace(`${__dirname}/test/data/`, ''),
|
|
46
|
-
interfaceFileData2.trim().replace(`${__dirname}/test/data/`, ''),
|
|
47
|
-
);
|
|
48
|
-
});
|
|
49
|
-
});
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import p from 'upath';
|
|
3
|
-
|
|
4
|
-
export default function createTempDir(folder = `a${Math.random()}`, base = process.cwd()) {
|
|
5
|
-
const path = p.join(base, '.cppjs');
|
|
6
|
-
return createDir(folder, path);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function createDir(folder, base = process.cwd()) {
|
|
10
|
-
const path = p.join(base, folder);
|
|
11
|
-
|
|
12
|
-
if (fs.existsSync(path)) fs.rmSync(path, { recursive: true, force: true });
|
|
13
|
-
fs.mkdirSync(path, { recursive: true });
|
|
14
|
-
return p.normalize(path);
|
|
15
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import glob from 'glob';
|
|
2
|
-
import getCliPath from './getCliPath.js';
|
|
3
|
-
|
|
4
|
-
export default function findCMakeListsFile(basePath = process.cwd()) {
|
|
5
|
-
let temp = glob.sync('CMakeLists.txt', { absolute: true, cwd: basePath });
|
|
6
|
-
if (temp.length === 0) {
|
|
7
|
-
temp = glob.sync('*/CMakeLists.txt', { absolute: true, 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
|
-
return `${getCliPath()}/assets/CMakeLists.txt`;
|
|
16
|
-
}
|
package/src/utils/getBaseInfo.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export default function getBaseInfo(base) {
|
|
2
|
-
let basePath = base;
|
|
3
|
-
|
|
4
|
-
const output = {
|
|
5
|
-
withSlash: '/',
|
|
6
|
-
withoutSlash: '/',
|
|
7
|
-
};
|
|
8
|
-
if (basePath && basePath !== '/') {
|
|
9
|
-
if (basePath.at(-1) !== '/') basePath += '/';
|
|
10
|
-
|
|
11
|
-
output.withSlash = basePath;
|
|
12
|
-
output.withoutSlash = basePath.substring(0, basePath.length - 1);
|
|
13
|
-
}
|
|
14
|
-
return output;
|
|
15
|
-
}
|
package/src/utils/getCliPath.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import * as url from 'node:url';
|
|
2
|
-
import upath from 'upath';
|
|
3
|
-
|
|
4
|
-
const filename = upath.normalize(url.fileURLToPath(import.meta.url));
|
|
5
|
-
const temp = filename.split('/');
|
|
6
|
-
temp.pop();
|
|
7
|
-
temp.pop();
|
|
8
|
-
const dirname = temp.join('/');
|
|
9
|
-
|
|
10
|
-
export default function getCliPath() {
|
|
11
|
-
return dirname;
|
|
12
|
-
}
|
package/src/utils/getConfig.js
DELETED
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import nodePath from 'upath';
|
|
3
|
-
import * as url from 'node:url';
|
|
4
|
-
import createTempDir, { createDir } from './createTempDir.js';
|
|
5
|
-
import findCMakeListsFile from './findCMakeListsFile.js';
|
|
6
|
-
|
|
7
|
-
const filename = nodePath.normalize(url.fileURLToPath(import.meta.url));
|
|
8
|
-
const temp = filename.split('/'); temp.pop(); temp.pop();
|
|
9
|
-
const dirname = temp.join('/');
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* @typedef {Object} Config
|
|
13
|
-
* @property {string} general General
|
|
14
|
-
* @property {any[]} dependencies Dependencies
|
|
15
|
-
* @property {ConfigPaths} paths Paths
|
|
16
|
-
* @property {ConfigExtensions} ext Extensions
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @typedef {Object} ConfigPaths
|
|
21
|
-
* @property {string} project Project path.
|
|
22
|
-
* @property {string} base Base path (Use for monorepo structure)
|
|
23
|
-
* @property {string} temp Temp path.
|
|
24
|
-
* @property {string} native Native path (default: ['src/native']).
|
|
25
|
-
* @property {string} module Module path (default: native path)
|
|
26
|
-
* @property {string} header Header path (default: native path)
|
|
27
|
-
* @property {string} bridge Bridge path (default: native and temp path)
|
|
28
|
-
* @property {string} output Output path (default: 'dist')
|
|
29
|
-
* @property {string} cmake CmakeLists.txt path
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* @typedef {Object} ConfigExtensions
|
|
34
|
-
* @property {string} header Header extensions (default: ['h', 'hpp', 'hxx', 'hh'])
|
|
35
|
-
* @property {string} source Source extensions (default: ['c', 'cpp', 'cxx', 'cc'])
|
|
36
|
-
* @property {string} module Module extensions (default: ['i'])
|
|
37
|
-
*/
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* @typedef {Object} ConfigGeneral
|
|
41
|
-
* @property {string} name Project name
|
|
42
|
-
*/
|
|
43
|
-
|
|
44
|
-
let tempConfigDefault = {
|
|
45
|
-
general: {}, dependencies: [], paths: {}, ext: {}, export: {}, platform: {},
|
|
46
|
-
};
|
|
47
|
-
await initDefaultConfigFile();
|
|
48
|
-
|
|
49
|
-
async function initDefaultConfigFile() {
|
|
50
|
-
let filePath;
|
|
51
|
-
['json', 'js', 'mjs', 'cjs', 'ts'].some((e) => {
|
|
52
|
-
filePath = `${process.cwd()}/cppjs.config.${e}`;
|
|
53
|
-
if (!fs.existsSync(filePath)) {
|
|
54
|
-
filePath = null;
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
return true;
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
if (filePath) {
|
|
61
|
-
let file = await import('file:///' + filePath);
|
|
62
|
-
if (file.default) file = file.default;
|
|
63
|
-
|
|
64
|
-
if (typeof file === 'function') tempConfigDefault = file();
|
|
65
|
-
else if (typeof file === 'object') tempConfigDefault = file;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export default function getConfig() {
|
|
70
|
-
return fillConfig(forceToConfigSchema(tempConfigDefault));
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function forceToConfigSchema(tempConfig) {
|
|
74
|
-
const config = {
|
|
75
|
-
general: tempConfig && tempConfig.general ? tempConfig.general : {},
|
|
76
|
-
dependencies: tempConfig && tempConfig.dependencies ? tempConfig.dependencies : [],
|
|
77
|
-
paths: tempConfig && tempConfig.paths ? tempConfig.paths : {},
|
|
78
|
-
ext: tempConfig && tempConfig.ext ? tempConfig.ext : {},
|
|
79
|
-
export: tempConfig && tempConfig.export ? tempConfig.export : {},
|
|
80
|
-
platform: tempConfig && tempConfig.platform ? tempConfig.platform : {},
|
|
81
|
-
};
|
|
82
|
-
return config;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function getAbsolutePath(projectPath, path) {
|
|
86
|
-
if (!path) {
|
|
87
|
-
return null;
|
|
88
|
-
}
|
|
89
|
-
if (nodePath.isAbsolute(path)) {
|
|
90
|
-
return path;
|
|
91
|
-
}
|
|
92
|
-
if (projectPath) {
|
|
93
|
-
return nodePath.resolve(nodePath.join(nodePath.resolve(projectPath), path));
|
|
94
|
-
}
|
|
95
|
-
return nodePath.resolve(path);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function fillConfig(tempConfig, options = {}) {
|
|
99
|
-
const config = {
|
|
100
|
-
general: {},
|
|
101
|
-
dependencies: (tempConfig.dependencies || []).map((d) => fillConfig(forceToConfigSchema(d), { depend: true })),
|
|
102
|
-
paths: {
|
|
103
|
-
project: getAbsolutePath(null, tempConfig.paths.project) || process.cwd(),
|
|
104
|
-
},
|
|
105
|
-
ext: {},
|
|
106
|
-
export: {},
|
|
107
|
-
platform: {},
|
|
108
|
-
package: {},
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
const packageJsonPath = `${config.paths.project}/package.json`;
|
|
112
|
-
if (fs.existsSync(packageJsonPath)) {
|
|
113
|
-
const file = JSON.parse(fs.readFileSync(packageJsonPath));
|
|
114
|
-
if (file && typeof file === 'object' && file.name) {
|
|
115
|
-
config.package = file;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (tempConfig?.general?.name) {
|
|
120
|
-
config.general.name = tempConfig.general.name;
|
|
121
|
-
} else {
|
|
122
|
-
config.general.name = config.package.name || 'cppjssample';
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const getPath = getAbsolutePath.bind(null, config.paths.project);
|
|
126
|
-
|
|
127
|
-
config.paths.base = getPath(tempConfig.paths.base) || config.paths.project;
|
|
128
|
-
config.paths.temp = getPath(tempConfig.paths.temp) || createTempDir(undefined, config.paths.project);
|
|
129
|
-
config.paths.native = (tempConfig.paths.native || ['src/native']).map((p) => getPath(p));
|
|
130
|
-
config.paths.module = (tempConfig.paths.module || config.paths.native).map((p) => getPath(p));
|
|
131
|
-
config.paths.header = (tempConfig.paths.header || config.paths.native).map((p) => getPath(p));
|
|
132
|
-
config.paths.bridge = (tempConfig.paths.bridge || [...config.paths.native, config.paths.temp]).map((p) => getPath(p));
|
|
133
|
-
config.paths.output = getPath(tempConfig.paths.output) || config.paths.temp;
|
|
134
|
-
config.paths.cmake = options.depend ? findCMakeListsFile(config.paths.output) : (
|
|
135
|
-
getPath(tempConfig.paths.cmake || findCMakeListsFile(config.paths.project))
|
|
136
|
-
);
|
|
137
|
-
config.paths.cli = dirname;
|
|
138
|
-
|
|
139
|
-
config.ext.header = tempConfig.ext.header || ['h', 'hpp', 'hxx', 'hh'];
|
|
140
|
-
config.ext.source = tempConfig.ext.source || ['c', 'cpp', 'cxx', 'cc'];
|
|
141
|
-
config.ext.module = tempConfig.ext.module || ['i'];
|
|
142
|
-
|
|
143
|
-
config.export.type = tempConfig.export.type || 'cmake';
|
|
144
|
-
config.export.header = tempConfig.export.header || 'include';
|
|
145
|
-
config.export.libPath = getPath(tempConfig.export.libPath || 'lib');
|
|
146
|
-
config.export.libName = tempConfig.export.libName || [config.general.name];
|
|
147
|
-
config.export.binHeaders = tempConfig.export.binHeaders || [];
|
|
148
|
-
config.export.entry = tempConfig.export.entry;
|
|
149
|
-
|
|
150
|
-
config.platform['Emscripten-x86_64'] = tempConfig.platform['Emscripten-x86_64'] || {};
|
|
151
|
-
config.platform['Emscripten-x86_64-browser'] = tempConfig.platform['Emscripten-x86_64-browser'] || {};
|
|
152
|
-
config.platform['Emscripten-x86_64-node'] = tempConfig.platform['Emscripten-x86_64-node'] || {};
|
|
153
|
-
config.platform['Android-arm64-v8a'] = tempConfig.platform['Android-arm64-v8a'] || {};
|
|
154
|
-
config.platform['iOS-iphoneos'] = tempConfig.platform['iOS-iphoneos'] || {};
|
|
155
|
-
config.platform['iOS-iphonesimulator'] = tempConfig.platform['iOS-iphonesimulator'] || {};
|
|
156
|
-
|
|
157
|
-
createDir('interface', config.paths.temp);
|
|
158
|
-
createDir('bridge', config.paths.temp);
|
|
159
|
-
|
|
160
|
-
// eslint-disable-next-line max-len
|
|
161
|
-
config.getAllDependencies = () => {
|
|
162
|
-
const output = {};
|
|
163
|
-
[...config.dependencies, ...config.dependencies.map((d) => d.getAllDependencies()).flat()].forEach((d) => {
|
|
164
|
-
output[d.paths.project] = d;
|
|
165
|
-
});
|
|
166
|
-
return Object.values(output);
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
return config;
|
|
170
|
-
}
|
package/src/utils/getDirName.js
DELETED
package/src/utils/getPathInfo.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { assert } from 'chai';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import p from 'path';
|
|
4
|
-
import * as url from 'node:url';
|
|
5
|
-
import { tmpdir } from "os";
|
|
6
|
-
import findCMakeListsFile from './findCMakeListsFile.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('findCMakeListsFile', function () {
|
|
25
|
-
let tempdir;
|
|
26
|
-
before(async function () {
|
|
27
|
-
tempdir = createTempDir();
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('find CMakeLists.txt file', async function () {
|
|
31
|
-
const path = findCMakeListsFile(tempdir);
|
|
32
|
-
assert.equal(path, __dirname + '/assets/CMakeLists.txt');
|
|
33
|
-
});
|
|
34
|
-
});
|