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
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
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
|
|
6
|
-
import getPathInfo from '../utils/getPathInfo.js';
|
|
5
|
+
import state from '../state/index.js';
|
|
7
6
|
|
|
8
7
|
const CROSSCOMPILER = 'aarch64-linux-android33';
|
|
9
8
|
const ANDROID_NDK = '/opt/android-sdk/ndk/25.2.9519653';
|
|
@@ -72,16 +71,17 @@ function getParentPath(path) {
|
|
|
72
71
|
return pathArray.join('/');
|
|
73
72
|
}
|
|
74
73
|
|
|
75
|
-
export default function run(
|
|
76
|
-
const
|
|
74
|
+
export default function run(program, params = [], platformPrefix = null, platform = null, dockerOptions = {}) {
|
|
75
|
+
const buildPath = platformPrefix ? `${state.config.paths.build}/${platformPrefix}/${platform}` : state.config.paths.build;
|
|
76
|
+
if (!fs.existsSync(buildPath)) {
|
|
77
|
+
fs.mkdirSync(buildPath, { recursive: true });
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const [basePlatform, ...arch] = (platform || 'unknown-unknown').split('-'); // Emscripten-x86_64, Android-arm64-v8a, iOS-iphoneos, iOS-iphonesimulator
|
|
77
81
|
if (basePlatform !== 'iOS' || program !== null) {
|
|
78
82
|
pullDockerImage();
|
|
79
83
|
}
|
|
80
84
|
|
|
81
|
-
const base = getBaseInfo(compiler.config.paths.base);
|
|
82
|
-
const temp = getPathInfo(compiler.config.paths.temp, compiler.config.paths.base);
|
|
83
|
-
|
|
84
|
-
const cMakeParentPath = getParentPath(compiler.config.paths.cmake);
|
|
85
85
|
let dProgram = program;
|
|
86
86
|
let dParams = params;
|
|
87
87
|
let platformParams = [];
|
|
@@ -118,8 +118,8 @@ export default function run(compiler, program, params = [], dockerOptions = {})
|
|
|
118
118
|
'-DFRAMEWORK=TRUE',
|
|
119
119
|
'-DCMAKE_OSX_DEPLOYMENT_TARGET=13.0',
|
|
120
120
|
'-DCMAKE_SYSTEM_NAME=iOS',
|
|
121
|
-
`-DMACOSX_FRAMEWORK_IDENTIFIER=org.js.cpp.${
|
|
122
|
-
`-DCMAKE_XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER=org.js.cpp.${
|
|
121
|
+
`-DMACOSX_FRAMEWORK_IDENTIFIER=org.js.cpp.${state.config.general.name}`,
|
|
122
|
+
`-DCMAKE_XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER=org.js.cpp.${state.config.general.name}`,
|
|
123
123
|
`-DCMAKE_OSX_SYSROOT='${arch[0] === 'iphoneos' ? iosSdkPath : iosSimSdkPath}'`,
|
|
124
124
|
`-DCMAKE_OSX_ARCHITECTURES=${arch[0] === 'iphoneos' ? 'arm64;arm64e' : 'arm64;arm64e;x86_64'}`,
|
|
125
125
|
`-DCMAKE_C_FLAGS=${arch[0] === 'iphoneos' ? '-fembed-bitcode' : '-fembed-bitcode-marker'}`,
|
|
@@ -134,7 +134,7 @@ export default function run(compiler, program, params = [], dockerOptions = {})
|
|
|
134
134
|
if (dParams[0] !== '--build' && dParams[0] !== '--install') {
|
|
135
135
|
dParams = [
|
|
136
136
|
...dParams,
|
|
137
|
-
`-DCMAKE_TOOLCHAIN_FILE='${
|
|
137
|
+
`-DCMAKE_TOOLCHAIN_FILE='${state.config.paths.cli}/assets/ios.toolchain.cmake'`,
|
|
138
138
|
`-DPLATFORM=${arch[0] === 'iphoneos' ? 'OS64' : 'SIMULATORARM64'}`,
|
|
139
139
|
`-DARCHS=${arch[0] === 'iphoneos' ? 'arm64;arm64e' : 'arm64;arm64e;x86_64'}`,
|
|
140
140
|
'-DENABLE_BITCODE=TRUE',
|
|
@@ -142,8 +142,8 @@ export default function run(compiler, program, params = [], dockerOptions = {})
|
|
|
142
142
|
'-DFRAMEWORK=TRUE',
|
|
143
143
|
'-DCMAKE_OSX_DEPLOYMENT_TARGET=13.0',
|
|
144
144
|
'-DCMAKE_SYSTEM_NAME=iOS',
|
|
145
|
-
`-DMACOSX_FRAMEWORK_IDENTIFIER=org.js.cpp.${
|
|
146
|
-
`-DCMAKE_XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER=org.js.cpp.${
|
|
145
|
+
`-DMACOSX_FRAMEWORK_IDENTIFIER=org.js.cpp.${state.config.general.name}`,
|
|
146
|
+
`-DCMAKE_XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER=org.js.cpp.${state.config.general.name}`,
|
|
147
147
|
`-DCMAKE_OSX_SYSROOT='${arch[0] === 'iphoneos' ? iosSdkPath : iosSimSdkPath}'`,
|
|
148
148
|
`-DCMAKE_OSX_ARCHITECTURES=${arch[0] === 'iphoneos' ? 'arm64;arm64e' : 'arm64;arm64e;x86_64'}`,
|
|
149
149
|
`-DCMAKE_C_FLAGS=${arch[0] === 'iphoneos' ? '-fembed-bitcode' : '-fembed-bitcode-marker'}`,
|
|
@@ -189,32 +189,54 @@ export default function run(compiler, program, params = [], dockerOptions = {})
|
|
|
189
189
|
env.PATH = `/opt/homebrew/bin:${env.PATH}`;
|
|
190
190
|
|
|
191
191
|
const options = {
|
|
192
|
-
cwd: dockerOptions.workdir ||
|
|
192
|
+
cwd: dockerOptions.workdir || buildPath,
|
|
193
193
|
stdio: dockerOptions.console ? 'inherit' : 'pipe',
|
|
194
194
|
env,
|
|
195
195
|
};
|
|
196
196
|
|
|
197
|
-
if (!fs.existsSync('/tmp/cppjs')) fs.mkdirSync('/tmp/cppjs');
|
|
198
|
-
if (fs.existsSync('/tmp/cppjs/live')) fs.unlinkSync('/tmp/cppjs/live');
|
|
199
|
-
fs.symlinkSync(base.withoutSlash, '/tmp/cppjs/live');
|
|
200
|
-
if (!fs.existsSync('/tmp/cppjs/cli')) fs.symlinkSync(compiler.config.paths.cli, '/tmp/cppjs/cli');
|
|
201
|
-
if (!fs.existsSync('/tmp/cppjs/cmake')) fs.symlinkSync(cMakeParentPath, '/tmp/cppjs/cmake');
|
|
202
|
-
|
|
203
197
|
execFileSync(dProgram, dParams, options);
|
|
198
|
+
} else if (false) {
|
|
199
|
+
const options = { cwd: buildPath, stdio: dockerOptions.console ? 'inherit' : 'pipe' };
|
|
200
|
+
const args = [
|
|
201
|
+
'exec',
|
|
202
|
+
'--user', getOsUserAndGroupId(),
|
|
203
|
+
'--workdir', dockerOptions.workdir || replaceBasePathForDocker(buildPath),
|
|
204
|
+
'cppjs-builder',
|
|
205
|
+
dProgram,
|
|
206
|
+
...replaceBasePathForDocker(dParams),
|
|
207
|
+
];
|
|
208
|
+
execFileSync('docker', args, options);
|
|
204
209
|
} else {
|
|
205
|
-
const options = { cwd:
|
|
210
|
+
const options = { cwd: buildPath, stdio: dockerOptions.console ? 'inherit' : 'pipe' };
|
|
206
211
|
const args = [
|
|
207
212
|
'run',
|
|
213
|
+
'--rm',
|
|
208
214
|
'--user', getOsUserAndGroupId(),
|
|
209
|
-
'-v', `${base
|
|
210
|
-
'
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
...(dockerOptions.params || []),
|
|
215
|
+
'-v', `${state.config.paths.base}:/tmp/cppjs/live`,
|
|
216
|
+
'--workdir', dockerOptions.workdir || replaceBasePathForDocker(buildPath),
|
|
217
|
+
...replaceBasePathForDocker(platformParams),
|
|
218
|
+
...replaceBasePathForDocker(dockerOptions.params || []),
|
|
219
|
+
// '-e', replaceBasePathForDocker(`CCACHE_DIR=${state.config.paths.build}/ccache`),
|
|
215
220
|
getDockerImage(),
|
|
216
|
-
dProgram,
|
|
221
|
+
dProgram,
|
|
222
|
+
...replaceBasePathForDocker(dParams),
|
|
217
223
|
];
|
|
218
224
|
execFileSync('docker', args, options);
|
|
219
225
|
}
|
|
220
226
|
}
|
|
227
|
+
|
|
228
|
+
function replaceBasePathForDocker(data) {
|
|
229
|
+
if (typeof data === 'string' || data instanceof String) {
|
|
230
|
+
return data.replaceAll(state.config.paths.base, '/tmp/cppjs/live');
|
|
231
|
+
}
|
|
232
|
+
if (Array.isArray(data)) {
|
|
233
|
+
return data.map((d) => replaceBasePathForDocker(d));
|
|
234
|
+
}
|
|
235
|
+
if (typeof value === 'object' && data !== null) {
|
|
236
|
+
const newData = {};
|
|
237
|
+
Object.entries(data).forEach(([key, value]) => {
|
|
238
|
+
newData[key] = replaceBasePathForDocker(value);
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
return data;
|
|
242
|
+
}
|
|
@@ -29,7 +29,9 @@ if (BUILD_BRIDGE)
|
|
|
29
29
|
file(GLOB BRIDGE_SRC_FILES "${BRIDGE_DIR}/*.i.cpp")
|
|
30
30
|
endif(BUILD_BRIDGE)
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
file(GLOB_RECURSE EXTERNAL_SRC_FILES ${EXTERNAL_NATIVE_GLOB})
|
|
33
|
+
|
|
34
|
+
set(SRC_FILES "${BUILD_SRC_FILES}" "${BRIDGE_SRC_FILES}" "${EXTERNAL_SRC_FILES}")
|
|
33
35
|
add_library("${PROJECT_NAME}" "${BUILD_TYPE}" ${SRC_FILES})
|
|
34
36
|
|
|
35
37
|
set(EXTRA_LINK_LIBRARIES "")
|
|
@@ -44,15 +46,17 @@ endif()
|
|
|
44
46
|
file(GLOB_RECURSE HEADER_FILES ${HEADER_GLOB})
|
|
45
47
|
target_include_directories("${PROJECT_NAME}" PUBLIC "${HEADER_DIR}")
|
|
46
48
|
|
|
49
|
+
install(TARGETS "${PROJECT_NAME}" DESTINATION "lib")
|
|
50
|
+
if(NOT "${HEADER_FILES}" STREQUAL "")
|
|
51
|
+
target_sources("${PROJECT_NAME}"
|
|
52
|
+
PUBLIC FILE_SET HEADERS
|
|
53
|
+
BASE_DIRS "${HEADER_DIR}"
|
|
54
|
+
FILES "${HEADER_FILES}")
|
|
55
|
+
install(TARGETS "${PROJECT_NAME}" FILE_SET HEADERS DESTINATION "include")
|
|
56
|
+
endif()
|
|
57
|
+
|
|
47
58
|
if (BUILD_SOURCE)
|
|
48
|
-
|
|
49
|
-
if(NOT "${HEADER_FILES}" STREQUAL "")
|
|
50
|
-
target_sources("${PROJECT_NAME}"
|
|
51
|
-
PUBLIC FILE_SET HEADERS
|
|
52
|
-
BASE_DIRS "${HEADER_DIR}"
|
|
53
|
-
FILES "${HEADER_FILES}")
|
|
54
|
-
install(TARGETS "${PROJECT_NAME}" FILE_SET HEADERS DESTINATION "include")
|
|
55
|
-
endif()
|
|
59
|
+
|
|
56
60
|
endif(BUILD_SOURCE)
|
|
57
61
|
unset(BUILD_SOURCE CACHE)
|
|
58
62
|
|
|
@@ -168,7 +168,7 @@ list(APPEND _supported_platforms
|
|
|
168
168
|
"TVOS" "TVOSCOMBINED" "SIMULATOR_TVOS" "SIMULATORARM64_TVOS"
|
|
169
169
|
"WATCHOS" "WATCHOSCOMBINED" "SIMULATOR_WATCHOS" "SIMULATORARM64_WATCHOS"
|
|
170
170
|
"MAC" "MAC_ARM64" "MAC_UNIVERSAL"
|
|
171
|
-
"VISIONOS" "SIMULATOR_VISIONOS" "VISIONOSCOMBINED"
|
|
171
|
+
"VISIONOS" "SIMULATOR_VISIONOS" "VISIONOSCOMBINED"
|
|
172
172
|
"MAC_CATALYST" "MAC_CATALYST_ARM64" "MAC_CATALYST_UNIVERSAL")
|
|
173
173
|
|
|
174
174
|
# Cache what generator is used
|
|
@@ -316,7 +316,7 @@ if(PLATFORM_INT STREQUAL "OS")
|
|
|
316
316
|
set(ARCHS armv7 armv7s arm64)
|
|
317
317
|
set(APPLE_TARGET_TRIPLE_INT arm-apple-ios${DEPLOYMENT_TARGET})
|
|
318
318
|
else()
|
|
319
|
-
set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET})
|
|
319
|
+
set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET})
|
|
320
320
|
endif()
|
|
321
321
|
elseif(PLATFORM_INT STREQUAL "OS64")
|
|
322
322
|
set(SDK_NAME iphoneos)
|
|
@@ -1049,7 +1049,7 @@ set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
|
|
|
1049
1049
|
)
|
|
1050
1050
|
|
|
1051
1051
|
if(NAMED_LANGUAGE_SUPPORT_INT)
|
|
1052
|
-
list(APPEND CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
|
|
1052
|
+
list(APPEND CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
|
|
1053
1053
|
CMAKE_OBJC_FLAGS
|
|
1054
1054
|
CMAKE_OBJC_DEBUG
|
|
1055
1055
|
CMAKE_OBJC_MINSIZEREL
|
|
@@ -1087,7 +1087,7 @@ IF(NOT DEFINED CMAKE_FIND_FRAMEWORK)
|
|
|
1087
1087
|
ENDIF(NOT DEFINED CMAKE_FIND_FRAMEWORK)
|
|
1088
1088
|
|
|
1089
1089
|
# Set up the default search directories for frameworks.
|
|
1090
|
-
if(PLATFORM_INT MATCHES "^MAC_CATALYST")
|
|
1090
|
+
if(PLATFORM_INT MATCHES "^MAC_CATALYST")
|
|
1091
1091
|
set(CMAKE_FRAMEWORK_PATH
|
|
1092
1092
|
${CMAKE_DEVELOPER_ROOT}/Library/PrivateFrameworks
|
|
1093
1093
|
${CMAKE_OSX_SYSROOT_INT}/System/Library/Frameworks
|
package/src/bin.js
CHANGED
|
@@ -3,24 +3,28 @@
|
|
|
3
3
|
import { Command, Option } from 'commander';
|
|
4
4
|
import fs from 'fs';
|
|
5
5
|
import glob from 'glob';
|
|
6
|
-
import
|
|
7
|
-
import getPathInfo from './utils/getPathInfo.js';
|
|
6
|
+
import upath from 'upath';
|
|
8
7
|
|
|
9
|
-
import
|
|
8
|
+
import { state } from './index.js';
|
|
9
|
+
import createBridgeFile from './actions/createInterface.js';
|
|
10
|
+
import createLib from './actions/createLib.js';
|
|
11
|
+
import buildWasm from './actions/buildWasm.js';
|
|
12
|
+
import createXCFramework from './actions/createXCFramework.js';
|
|
13
|
+
import runCppjsApp from './actions/run.js';
|
|
10
14
|
|
|
11
15
|
const packageJSON = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url)));
|
|
12
16
|
|
|
13
17
|
const program = new Command();
|
|
14
18
|
|
|
15
19
|
program
|
|
16
|
-
.name('
|
|
20
|
+
.name('cppjs')
|
|
17
21
|
.description('Compile C++ files to WebAssembly and native platforms.')
|
|
18
22
|
.version(packageJSON.version)
|
|
19
23
|
.showHelpAfterError();
|
|
20
24
|
|
|
21
25
|
const commandBuild = program.command('build')
|
|
22
26
|
.description('compile the project that was set up using Cpp.js')
|
|
23
|
-
.addOption(new Option('-p, --platform <platform>', 'target platform').default('
|
|
27
|
+
.addOption(new Option('-p, --platform <platform>', 'target platform').default('All').choices(['All', 'WebAssembly', 'Android', 'iOS']));
|
|
24
28
|
|
|
25
29
|
const commandRun = program.command('run')
|
|
26
30
|
.description('run docker application');
|
|
@@ -63,16 +67,15 @@ function postInstall() {
|
|
|
63
67
|
return;
|
|
64
68
|
}
|
|
65
69
|
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
dist = dist ? getPathInfo(dist, projectPath).relative : null;
|
|
70
|
+
const name = state?.config?.general?.name;
|
|
71
|
+
let dist = state?.config?.paths?.output;
|
|
72
|
+
dist = dist ? upath.relative(projectPath, dist) : null;
|
|
70
73
|
|
|
71
74
|
if (!name || !dist) {
|
|
72
75
|
return;
|
|
73
76
|
}
|
|
74
77
|
|
|
75
|
-
|
|
78
|
+
state?.config?.export?.libName?.forEach((fileName) => {
|
|
76
79
|
if (fs.existsSync(`${projectPath}/${fileName}.xcframework`) || !fs.existsSync(`${dist}/prebuilt/${fileName}.xcframework`)) {
|
|
77
80
|
return;
|
|
78
81
|
}
|
|
@@ -81,87 +84,53 @@ function postInstall() {
|
|
|
81
84
|
}
|
|
82
85
|
|
|
83
86
|
function run(programName, params) {
|
|
84
|
-
|
|
85
|
-
compiler.run(programName, params, { console: true });
|
|
87
|
+
runCppjsApp(programName, params, null, null, { console: true });
|
|
86
88
|
}
|
|
87
89
|
|
|
88
|
-
function build(platform) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const modules = [];
|
|
92
|
-
compiler2.config.paths.module.forEach((modulePath) => {
|
|
93
|
-
modules.push(...glob.sync('**/*.i', { absolute: true, cwd: modulePath }));
|
|
94
|
-
modules.push(...glob.sync('*.i', { absolute: true, cwd: modulePath }));
|
|
90
|
+
async function build(platform) {
|
|
91
|
+
state.platforms[platform].forEach((p) => {
|
|
92
|
+
createLib(p, 'Source', { isProd: true, buildSource: true });
|
|
95
93
|
});
|
|
96
94
|
|
|
97
|
-
|
|
98
|
-
if (!fs.existsSync(`${compiler2.config.paths.output}/prebuilt/Emscripten-x86_64`)) {
|
|
99
|
-
buildWasm();
|
|
100
|
-
modules.forEach((modulePath) => {
|
|
101
|
-
const fileName = modulePath.split('/').at(-1);
|
|
102
|
-
createDir('prebuilt/Emscripten-x86_64/swig', compiler2.config.paths.output);
|
|
103
|
-
fs.copyFileSync(modulePath, `${compiler2.config.paths.output}/prebuilt/Emscripten-x86_64/swig/${fileName}`);
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
}
|
|
95
|
+
fs.cpSync(`${state.config.paths.build}/Source-Release/prebuilt`, `${state.config.paths.output}/prebuilt`, { recursive: true });
|
|
107
96
|
|
|
108
|
-
|
|
109
|
-
const platforms = {
|
|
110
|
-
all: ['Android-arm64-v8a', 'iOS-iphoneos', 'iOS-iphonesimulator'],
|
|
111
|
-
android: ['Android-arm64-v8a'],
|
|
112
|
-
ios: ['iOS-iphoneos', 'iOS-iphonesimulator'],
|
|
113
|
-
};
|
|
114
|
-
platforms[platform].forEach((p) => {
|
|
115
|
-
if (!fs.existsSync(`${compiler2.config.paths.output}/prebuilt/${p}`)) {
|
|
116
|
-
const compiler = new CppjsCompiler(p);
|
|
117
|
-
compiler.createLib();
|
|
118
|
-
modules.forEach((modulePath) => {
|
|
119
|
-
const fileName = modulePath.split('/').at(-1);
|
|
120
|
-
createDir(`prebuilt/${p}/swig`, compiler2.config.paths.output);
|
|
121
|
-
fs.copyFileSync(modulePath, `${compiler2.config.paths.output}/prebuilt/${p}/swig/${fileName}`);
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
if (platform === 'all' || platform === 'ios') {
|
|
126
|
-
compiler2.finishBuild();
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const distCmakeContent = fs.readFileSync(`${compiler2.config.paths.cli}/assets/dist.cmake`, { encoding: 'utf8', flag: 'r' })
|
|
130
|
-
.replace('___PROJECT_NAME___', compiler2.config.general.name).replace('___PROJECT_LIBS___', compiler2.config.export.libName.join(';'));
|
|
131
|
-
fs.writeFileSync(`${compiler2.config.paths.output}/prebuilt/CMakeLists.txt`, distCmakeContent);
|
|
132
|
-
}
|
|
97
|
+
createXCFramework();
|
|
133
98
|
|
|
134
|
-
async function buildWasm() {
|
|
135
99
|
let headers = [];
|
|
136
|
-
|
|
137
|
-
const compiler = new CppjsCompiler();
|
|
138
|
-
compiler.config.paths.header.forEach((headerPath) => {
|
|
100
|
+
state.config.paths.header.forEach((headerPath) => {
|
|
139
101
|
headers.push(glob.sync('**/*.h', { absolute: true, cwd: headerPath }));
|
|
140
102
|
});
|
|
141
103
|
headers = headers.filter((path) => !!path.toString()).flat();
|
|
142
104
|
|
|
105
|
+
const bridges = [];
|
|
143
106
|
headers.forEach((header) => {
|
|
144
|
-
|
|
107
|
+
const bridgePath = createBridgeFile(header);
|
|
108
|
+
bridges.push(bridgePath);
|
|
145
109
|
});
|
|
146
110
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
111
|
+
const opt = {
|
|
112
|
+
isProd: true,
|
|
113
|
+
buildSource: false,
|
|
114
|
+
nativeGlob: bridges,
|
|
115
|
+
};
|
|
116
|
+
createLib('Emscripten-x86_64', 'Bridge', opt);
|
|
150
117
|
|
|
151
|
-
|
|
152
|
-
|
|
118
|
+
await buildWasm('browser', true);
|
|
119
|
+
await buildWasm('node', true);
|
|
153
120
|
|
|
154
|
-
fs.rmSync(`${
|
|
155
|
-
if (fs.existsSync(`${
|
|
156
|
-
fs.renameSync(`${
|
|
121
|
+
fs.rmSync(`${state.config.paths.output}/data`, { recursive: true, force: true });
|
|
122
|
+
if (fs.existsSync(`${state.config.paths.build}/data`)) {
|
|
123
|
+
fs.renameSync(`${state.config.paths.build}/data`, `${state.config.paths.output}/data`);
|
|
157
124
|
}
|
|
158
125
|
|
|
159
|
-
fs.copyFileSync(`${
|
|
160
|
-
fs.copyFileSync(`${
|
|
161
|
-
fs.copyFileSync(`${
|
|
162
|
-
if (fs.existsSync(`${
|
|
163
|
-
fs.copyFileSync(`${
|
|
126
|
+
fs.copyFileSync(`${state.config.paths.build}/${state.config.general.name}.node.js`, `${state.config.paths.output}/${state.config.general.name}.node.js`);
|
|
127
|
+
fs.copyFileSync(`${state.config.paths.build}/${state.config.general.name}.browser.js`, `${state.config.paths.output}/${state.config.general.name}.browser.js`);
|
|
128
|
+
fs.copyFileSync(`${state.config.paths.build}/${state.config.general.name}.wasm`, `${state.config.paths.output}/${state.config.general.name}.wasm`);
|
|
129
|
+
if (fs.existsSync(`${state.config.paths.build}/${state.config.general.name}.data.txt`)) {
|
|
130
|
+
fs.copyFileSync(`${state.config.paths.build}/${state.config.general.name}.data.txt`, `${state.config.paths.output}/${state.config.general.name}.data.txt`);
|
|
164
131
|
}
|
|
165
132
|
|
|
166
|
-
fs.
|
|
133
|
+
const distCmakeContent = fs.readFileSync(`${state.config.paths.cli}/assets/dist.cmake`, { encoding: 'utf8', flag: 'r' })
|
|
134
|
+
.replace('___PROJECT_NAME___', state.config.general.name).replace('___PROJECT_LIBS___', state.config.export.libName.join(';'));
|
|
135
|
+
fs.writeFileSync(`${state.config.paths.output}/prebuilt/CMakeLists.txt`, distCmakeContent);
|
|
167
136
|
}
|
package/src/index.js
CHANGED
|
@@ -1,63 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const platforms = ['Emscripten-x86_64', 'Android-arm64-v8a', 'iOS-iphoneos', 'iOS-iphonesimulator'];
|
|
12
|
-
export default class CppjsCompiler {
|
|
13
|
-
constructor(platform) {
|
|
14
|
-
this.config = getConfig();
|
|
15
|
-
this.interfaces = [];
|
|
16
|
-
this.platform = platform;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
findOrCreateInterfaceFile(path) {
|
|
20
|
-
return findOrCreateInterfaceFile(this, path);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
createBridge() {
|
|
24
|
-
return createBridge(this);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
createWasm(options) {
|
|
28
|
-
return createWasm(this, options);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
createLib() {
|
|
32
|
-
return createLib(this);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
getCmakeParams() {
|
|
36
|
-
return getCmakeParams(this.config, null, true, true);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
getData(field, prefixPath, subPlatform) {
|
|
40
|
-
return getData(this.config, field, prefixPath, this.platform, subPlatform);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
run(program, params, dockerOptions) {
|
|
44
|
-
run(this, program, params, dockerOptions);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
finishBuild() {
|
|
48
|
-
finishBuild(this);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// eslint-disable-next-line class-methods-use-this
|
|
52
|
-
getAllPlatforms() {
|
|
53
|
-
return platforms;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function initCppJs() {
|
|
58
|
-
return new Promise((resolve) => {
|
|
59
|
-
resolve();
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export const Native = {};
|
|
1
|
+
// eslint-disable-next-line import/prefer-default-export
|
|
2
|
+
export { default as state } from './state/index.js';
|
|
3
|
+
export { default as getParentPath } from './utils/getParentPath.js';
|
|
4
|
+
export { default as createLib } from './actions/createLib.js';
|
|
5
|
+
export { default as createBridgeFile } from './actions/createInterface.js';
|
|
6
|
+
export { default as buildWasm } from './actions/buildWasm.js';
|
|
7
|
+
export { default as getData } from './actions/getData.js';
|
|
8
|
+
export { default as getCmakeParameters } from './actions/getCmakeParameters.js';
|
|
9
|
+
export { default as createXCFramework } from './actions/createXCFramework.js';
|
|
10
|
+
export { default as getAllBridges } from './actions/getAllBridges.js';
|
|
@@ -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,44 @@
|
|
|
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', 'iOS-iphoneos', 'iOS-iphonesimulator'],
|
|
10
|
+
WebAssembly: ['Emscripten-x86_64'],
|
|
11
|
+
Android: ['Android-arm64-v8a'],
|
|
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
|
+
}
|
|
34
|
+
|
|
35
|
+
function loadCacheState() {
|
|
36
|
+
const stateFilePath = `${cacheDir}/cache.json`;
|
|
37
|
+
return loadJson(stateFilePath) || state.cache;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function saveCache() {
|
|
41
|
+
writeJson(`${cacheDir}/cache.json`, state.cache);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default state;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import loadJs from '../utils/loadJs.js';
|
|
2
|
+
import loadJson from '../utils/loadJson.js';
|
|
3
|
+
import getParentPath from '../utils/getParentPath.js';
|
|
4
|
+
import getAbsolutePath from '../utils/getAbsolutePath.js';
|
|
5
|
+
import fixPackageName from '../utils/fixPackageName.js';
|
|
6
|
+
import getCMakeListsFilePath from '../utils/getCMakeListsFilePath.js';
|
|
7
|
+
import calculateDependencyParameters from './calculateDependencyParameters.js';
|
|
8
|
+
// import getCmakeParameters from './getCmakeParameters.js';
|
|
9
|
+
|
|
10
|
+
export default async function loadConfig(configDir = process.cwd(), configName = 'cppjs.config') {
|
|
11
|
+
const config = await loadJs(configDir, configName) || {};
|
|
12
|
+
return getFilledConfig(config);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function getFilledConfig(config, options = { isDepend: false }) {
|
|
16
|
+
const newConfig = {
|
|
17
|
+
general: config.general || {},
|
|
18
|
+
dependencies: (config.dependencies || []).map((d) => getFilledConfig(d, { isDepend: true })),
|
|
19
|
+
paths: config.paths || {},
|
|
20
|
+
ext: config.ext || {},
|
|
21
|
+
export: config.export || {},
|
|
22
|
+
platform: config.platform || {},
|
|
23
|
+
package: null,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
if (newConfig.paths.config && !newConfig.paths.project) {
|
|
27
|
+
newConfig.paths.project = getParentPath(newConfig.paths.config);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!newConfig.paths.project) {
|
|
31
|
+
newConfig.paths.project = process.cwd();
|
|
32
|
+
} else {
|
|
33
|
+
newConfig.paths.project = getAbsolutePath(null, newConfig.paths.project);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
newConfig.package = loadJson(`${newConfig.paths.project}/package.json`);
|
|
37
|
+
|
|
38
|
+
if (!newConfig?.general?.name) {
|
|
39
|
+
newConfig.general.name = fixPackageName(newConfig.package.name) || 'cppjssample';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const getPath = getAbsolutePath.bind(null, newConfig.paths.project);
|
|
43
|
+
|
|
44
|
+
newConfig.paths.base = getPath(newConfig.paths.base) || newConfig.paths.project;
|
|
45
|
+
newConfig.paths.cache = getPath(newConfig.paths.cache) || getPath('.cppjs');
|
|
46
|
+
newConfig.paths.build = getPath(newConfig.paths.build) || getPath(`${newConfig.paths.cache}/build`);
|
|
47
|
+
newConfig.paths.native = (newConfig.paths.native || ['src/native']).map((p) => getPath(p));
|
|
48
|
+
newConfig.paths.module = (newConfig.paths.module || newConfig.paths.native).map((p) => getPath(p));
|
|
49
|
+
newConfig.paths.header = (newConfig.paths.header || newConfig.paths.native).map((p) => getPath(p));
|
|
50
|
+
newConfig.paths.bridge = (newConfig.paths.bridge || [...newConfig.paths.native, newConfig.paths.build])
|
|
51
|
+
.map((p) => getPath(p));
|
|
52
|
+
newConfig.paths.output = getPath(newConfig.paths.output) || newConfig.paths.build;
|
|
53
|
+
newConfig.paths.cmake = options.isDepend ? getCMakeListsFilePath(newConfig.paths.output) : (
|
|
54
|
+
getPath(newConfig.paths.cmake || getCMakeListsFilePath(newConfig.paths.project))
|
|
55
|
+
);
|
|
56
|
+
newConfig.paths.cmakeDir = getParentPath(newConfig.paths.cmake);
|
|
57
|
+
newConfig.paths.cli = getParentPath(getParentPath(import.meta.url));
|
|
58
|
+
newConfig.paths.cliCMakeListsTxt = `${newConfig.paths.cli}/assets/CMakeLists.txt`;
|
|
59
|
+
|
|
60
|
+
newConfig.ext.header = newConfig.ext.header || ['h', 'hpp', 'hxx', 'hh'];
|
|
61
|
+
newConfig.ext.source = newConfig.ext.source || ['c', 'cpp', 'cxx', 'cc'];
|
|
62
|
+
newConfig.ext.module = newConfig.ext.module || ['i'];
|
|
63
|
+
|
|
64
|
+
newConfig.export.type = newConfig.export.type || 'cmake';
|
|
65
|
+
newConfig.export.header = newConfig.export.header || 'include';
|
|
66
|
+
newConfig.export.libPath = getPath(newConfig.export.libPath || 'lib');
|
|
67
|
+
newConfig.export.libName = newConfig.export.libName || [newConfig.general.name];
|
|
68
|
+
newConfig.export.binHeaders = newConfig.export.binHeaders || [];
|
|
69
|
+
|
|
70
|
+
newConfig.platform['Emscripten-x86_64'] = newConfig.platform['Emscripten-x86_64'] || {};
|
|
71
|
+
newConfig.platform['Emscripten-x86_64-browser'] = newConfig.platform['Emscripten-x86_64-browser'] || {};
|
|
72
|
+
newConfig.platform['Emscripten-x86_64-node'] = newConfig.platform['Emscripten-x86_64-node'] || {};
|
|
73
|
+
newConfig.platform['Android-arm64-v8a'] = newConfig.platform['Android-arm64-v8a'] || {};
|
|
74
|
+
newConfig.platform['iOS-iphoneos'] = newConfig.platform['iOS-iphoneos'] || {};
|
|
75
|
+
newConfig.platform['iOS-iphonesimulator'] = newConfig.platform['iOS-iphonesimulator'] || {};
|
|
76
|
+
|
|
77
|
+
newConfig.allDependencies = (() => {
|
|
78
|
+
const output = {};
|
|
79
|
+
[...newConfig.dependencies, ...newConfig.dependencies.map((d) => d.allDependencies).flat()].forEach((d) => {
|
|
80
|
+
output[d.paths.project] = d;
|
|
81
|
+
});
|
|
82
|
+
return Object.values(output);
|
|
83
|
+
})();
|
|
84
|
+
|
|
85
|
+
newConfig.dependencyParameters = calculateDependencyParameters(newConfig);
|
|
86
|
+
// newConfig.cmakeParameters = getCmakeParameters(newConfig);
|
|
87
|
+
|
|
88
|
+
return newConfig;
|
|
89
|
+
}
|