cpp.js 1.0.0-beta.2 → 1.0.0-beta.21

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.
Files changed (56) hide show
  1. package/README.md +104 -0
  2. package/package.json +25 -6
  3. package/src/{functions/buildJS.js → actions/buildJs.js} +7 -5
  4. package/src/actions/buildWasm.js +68 -0
  5. package/src/actions/createInterface.js +127 -0
  6. package/src/actions/createLib.js +103 -0
  7. package/src/actions/createXCFramework.js +40 -0
  8. package/src/actions/getAllBridges.js +8 -0
  9. package/src/actions/getCmakeParameters.js +50 -0
  10. package/src/actions/getData.js +28 -0
  11. package/src/actions/getDependLibs.js +19 -0
  12. package/src/{functions → actions}/run.js +77 -40
  13. package/src/assets/CMakeLists.txt +13 -9
  14. package/src/assets/ios.toolchain.cmake +4 -4
  15. package/src/bin.js +147 -72
  16. package/src/export/react-native.js +51 -0
  17. package/src/export/web.js +42 -0
  18. package/src/index.js +13 -63
  19. package/src/state/calculateDependencyParameters.js +64 -0
  20. package/src/state/index.js +81 -0
  21. package/src/state/loadConfig.js +96 -0
  22. package/src/utils/downloadAndExtractFile.js +36 -0
  23. package/src/utils/fixPackageName.js +7 -0
  24. package/src/utils/getAbsolutePath.js +14 -0
  25. package/src/utils/{findCMakeListsFile.js → getCMakeListsFilePath.js} +4 -3
  26. package/src/utils/getOsUserAndGroupId.js +2 -1
  27. package/src/utils/getParentPath.js +12 -0
  28. package/src/utils/hash.js +20 -0
  29. package/src/utils/loadJs.js +32 -0
  30. package/src/utils/loadJson.js +16 -0
  31. package/src/utils/writeJson.js +9 -0
  32. package/.mocharc.yaml +0 -3
  33. package/src/functions/createBridge.js +0 -37
  34. package/src/functions/createLib.js +0 -44
  35. package/src/functions/createWasm.js +0 -71
  36. package/src/functions/findOrCreateInterfaceFile.js +0 -68
  37. package/src/functions/finishBuild.js +0 -43
  38. package/src/functions/getCmakeParams.js +0 -106
  39. package/src/functions/getData.js +0 -36
  40. package/src/functions/getLibs.js +0 -33
  41. package/src/functions/specs/createBridge.spec.js +0 -51
  42. package/src/functions/specs/findOrCreateInterfaceFile.spec.js +0 -49
  43. package/src/utils/createTempDir.js +0 -15
  44. package/src/utils/getBaseInfo.js +0 -15
  45. package/src/utils/getCliPath.js +0 -11
  46. package/src/utils/getConfig.js +0 -170
  47. package/src/utils/getDirName.js +0 -7
  48. package/src/utils/getPathInfo.js +0 -10
  49. package/src/utils/specs/findCMakeListsFile.spec.js +0 -34
  50. package/src/utils/specs/utils.spec.js +0 -81
  51. package/test/data/sample.cpp +0 -1
  52. package/test/data/sample.h +0 -10
  53. package/test/data/sample.i +0 -12
  54. package/test/data/sample2.cpp +0 -0
  55. package/test/data/sample2.ei +0 -12
  56. package/test/data/sample2.h +0 -10
@@ -1,9 +1,8 @@
1
- import fs from 'fs';
2
- import { execFileSync } from 'child_process';
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 getBaseInfo from '../utils/getBaseInfo.js';
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';
@@ -66,22 +65,17 @@ const iosParams = [
66
65
  '-e', `LDFLAGS="${IOS_HOST_FLAGS}"`,
67
66
  ]; */
68
67
 
69
- function getParentPath(path) {
70
- const pathArray = path.split('/');
71
- pathArray.pop();
72
- return pathArray.join('/');
73
- }
68
+ export default function run(program, params = [], platformPrefix = null, platform = null, dockerOptions = {}) {
69
+ const buildPath = platformPrefix ? `${state.config.paths.build}/${platformPrefix}/${platform}` : state.config.paths.build;
70
+ if (!fs.existsSync(buildPath)) {
71
+ fs.mkdirSync(buildPath, { recursive: true });
72
+ }
74
73
 
75
- export default function run(compiler, program, params = [], dockerOptions = {}) {
76
- const [basePlatform, ...arch] = (compiler.platform || 'unknown-unknown').split('-'); // Emscripten-x86_64, Android-arm64-v8a, iOS-iphoneos, iOS-iphonesimulator
74
+ const [basePlatform, ...arch] = (platform || 'unknown-unknown').split('-'); // Emscripten-x86_64, Android-arm64-v8a, iOS-iphoneos, iOS-iphonesimulator
77
75
  if (basePlatform !== 'iOS' || program !== null) {
78
76
  pullDockerImage();
79
77
  }
80
78
 
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
79
  let dProgram = program;
86
80
  let dParams = params;
87
81
  let platformParams = [];
@@ -118,14 +112,14 @@ export default function run(compiler, program, params = [], dockerOptions = {})
118
112
  '-DFRAMEWORK=TRUE',
119
113
  '-DCMAKE_OSX_DEPLOYMENT_TARGET=13.0',
120
114
  '-DCMAKE_SYSTEM_NAME=iOS',
121
- `-DMACOSX_FRAMEWORK_IDENTIFIER=org.js.cpp.${compiler.config.general.name}`,
122
- `-DCMAKE_XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER=org.js.cpp.${compiler.config.general.name}`,
115
+ `-DMACOSX_FRAMEWORK_IDENTIFIER=org.js.cpp.${state.config.general.name}`,
116
+ `-DCMAKE_XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER=org.js.cpp.${state.config.general.name}`,
123
117
  `-DCMAKE_OSX_SYSROOT='${arch[0] === 'iphoneos' ? iosSdkPath : iosSimSdkPath}'`,
124
118
  `-DCMAKE_OSX_ARCHITECTURES=${arch[0] === 'iphoneos' ? 'arm64;arm64e' : 'arm64;arm64e;x86_64'}`,
125
119
  `-DCMAKE_C_FLAGS=${arch[0] === 'iphoneos' ? '-fembed-bitcode' : '-fembed-bitcode-marker'}`,
126
120
  `-DCMAKE_CXX_FLAGS=${arch[0] === 'iphoneos' ? '-fembed-bitcode' : '-fembed-bitcode-marker'}`,
127
121
  '-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY=\'iPhone Developer\'',
128
- '-DCMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM=7ZZLDWBUVT',
122
+ `-DCMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM=${state.config.system.XCODE_DEVELOPMENT_TEAM}`,
129
123
  ];
130
124
  }
131
125
  } else if (dProgram === 'ios-cmake') {
@@ -134,7 +128,7 @@ export default function run(compiler, program, params = [], dockerOptions = {})
134
128
  if (dParams[0] !== '--build' && dParams[0] !== '--install') {
135
129
  dParams = [
136
130
  ...dParams,
137
- `-DCMAKE_TOOLCHAIN_FILE='${compiler.config.paths.cli}/assets/ios.toolchain.cmake'`,
131
+ `-DCMAKE_TOOLCHAIN_FILE='${state.config.paths.cli}/assets/ios.toolchain.cmake'`,
138
132
  `-DPLATFORM=${arch[0] === 'iphoneos' ? 'OS64' : 'SIMULATORARM64'}`,
139
133
  `-DARCHS=${arch[0] === 'iphoneos' ? 'arm64;arm64e' : 'arm64;arm64e;x86_64'}`,
140
134
  '-DENABLE_BITCODE=TRUE',
@@ -142,14 +136,14 @@ export default function run(compiler, program, params = [], dockerOptions = {})
142
136
  '-DFRAMEWORK=TRUE',
143
137
  '-DCMAKE_OSX_DEPLOYMENT_TARGET=13.0',
144
138
  '-DCMAKE_SYSTEM_NAME=iOS',
145
- `-DMACOSX_FRAMEWORK_IDENTIFIER=org.js.cpp.${compiler.config.general.name}`,
146
- `-DCMAKE_XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER=org.js.cpp.${compiler.config.general.name}`,
139
+ `-DMACOSX_FRAMEWORK_IDENTIFIER=org.js.cpp.${state.config.general.name}`,
140
+ `-DCMAKE_XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER=org.js.cpp.${state.config.general.name}`,
147
141
  `-DCMAKE_OSX_SYSROOT='${arch[0] === 'iphoneos' ? iosSdkPath : iosSimSdkPath}'`,
148
142
  `-DCMAKE_OSX_ARCHITECTURES=${arch[0] === 'iphoneos' ? 'arm64;arm64e' : 'arm64;arm64e;x86_64'}`,
149
143
  `-DCMAKE_C_FLAGS=${arch[0] === 'iphoneos' ? '-fembed-bitcode' : '-fembed-bitcode-marker'}`,
150
144
  `-DCMAKE_CXX_FLAGS=${arch[0] === 'iphoneos' ? '-fembed-bitcode' : '-fembed-bitcode-marker'}`,
151
145
  '-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY=\'iPhone Developer\'',
152
- '-DCMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM=7ZZLDWBUVT',
146
+ `-DCMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM=${state.config.system.XCODE_DEVELOPMENT_TEAM}`,
153
147
  ];
154
148
  }
155
149
  }
@@ -173,7 +167,7 @@ export default function run(compiler, program, params = [], dockerOptions = {})
173
167
  if (pParams[i] === '-e') {
174
168
  const [key, ...rest] = pParams[i + 1].split('=');
175
169
  const value = rest.join('=');
176
- if (['CFLAGS', 'CXXFLAGS', 'LDFLAGS'].includes(key)) {
170
+ if (['CFLAGS', 'CXXFLAGS', 'CPPFLAGS', 'LDFLAGS'].includes(key)) {
177
171
  let v = value;
178
172
  if (v.startsWith('\'') || v.startsWith('"')) {
179
173
  v = v.substring(1, v.length - 1);
@@ -189,32 +183,75 @@ export default function run(compiler, program, params = [], dockerOptions = {})
189
183
  env.PATH = `/opt/homebrew/bin:${env.PATH}`;
190
184
 
191
185
  const options = {
192
- cwd: dockerOptions.workdir || `/tmp/cppjs/live/${temp.relative}`,
193
- stdio: dockerOptions.console ? 'inherit' : 'pipe',
186
+ cwd: dockerOptions.workdir || buildPath,
187
+ stdio: dockerOptions.console ? 'inherit' : 'ignore',
194
188
  env,
195
189
  };
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
190
  execFileSync(dProgram, dParams, options);
191
+ } else if (false) {
192
+ const options = { cwd: buildPath, stdio: dockerOptions.console ? 'inherit' : 'ignore' };
193
+ const args = [
194
+ 'exec',
195
+ '--user', getOsUserAndGroupId(),
196
+ '--workdir', dockerOptions.workdir || replaceBasePathForDocker(buildPath),
197
+ 'cppjs-builder',
198
+ dProgram,
199
+ ...replaceBasePathForDocker(dParams),
200
+ ];
201
+ execFileSync('docker', args, options);
204
202
  } else {
205
- const options = { cwd: temp.absolute, stdio: dockerOptions.console ? 'inherit' : 'pipe' };
203
+ const env = {};
204
+ const pParams = [...platformParams, ...(dockerOptions.params || [])];
205
+ for (let i = 0; i < pParams.length; i += 2) {
206
+ if (pParams[i] === '-e') {
207
+ const [key, ...rest] = pParams[i + 1].split('=');
208
+ const value = rest.join('=');
209
+ if (['CFLAGS', 'CXXFLAGS', 'CPPFLAGS', 'LDFLAGS'].includes(key)) {
210
+ let v = value;
211
+ if (v.startsWith('\'') || v.startsWith('"')) {
212
+ v = v.substring(1, v.length - 1);
213
+ }
214
+ if (env[key]) env[key] += ` ${v}`;
215
+ else env[key] = v;
216
+ } else {
217
+ env[key] = value;
218
+ }
219
+ }
220
+ }
221
+
222
+ const dockerEnv = [];
223
+ Object.entries(env).forEach(([key, value]) => {
224
+ dockerEnv.push('-e', `${key}=${value}`);
225
+ });
226
+ const options = { cwd: buildPath, stdio: dockerOptions.console ? 'inherit' : 'ignore' };
206
227
  const args = [
207
228
  'run',
229
+ '--rm',
208
230
  '--user', getOsUserAndGroupId(),
209
- '-v', `${base.withoutSlash}:/tmp/cppjs/live`,
210
- '-v', `${compiler.config.paths.cli}:/tmp/cppjs/cli`,
211
- '-v', `${cMakeParentPath}:/tmp/cppjs/cmake`,
212
- '--workdir', dockerOptions.workdir || `/tmp/cppjs/live/${temp.relative}`,
213
- ...platformParams,
214
- ...(dockerOptions.params || []),
231
+ '-v', `${state.config.paths.base}:/tmp/cppjs/live`,
232
+ '--workdir', replaceBasePathForDocker(dockerOptions.workdir || buildPath),
233
+ ...replaceBasePathForDocker(dockerEnv),
234
+ // '-e', replaceBasePathForDocker(`CCACHE_DIR=${state.config.paths.build}/ccache`),
215
235
  getDockerImage(),
216
- dProgram, ...dParams,
236
+ replaceBasePathForDocker(dProgram),
237
+ ...replaceBasePathForDocker(dParams),
217
238
  ];
218
239
  execFileSync('docker', args, options);
219
240
  }
220
241
  }
242
+
243
+ function replaceBasePathForDocker(data) {
244
+ if (typeof data === 'string' || data instanceof String) {
245
+ return data.replaceAll(state.config.paths.base, '/tmp/cppjs/live');
246
+ }
247
+ if (Array.isArray(data)) {
248
+ return data.map((d) => replaceBasePathForDocker(d));
249
+ }
250
+ if (typeof value === 'object' && data !== null) {
251
+ const newData = {};
252
+ Object.entries(data).forEach(([key, value]) => {
253
+ newData[key] = replaceBasePathForDocker(value);
254
+ });
255
+ }
256
+ return data;
257
+ }
@@ -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
- set(SRC_FILES "${BUILD_SRC_FILES}" "${BRIDGE_SRC_FILES}")
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
- install(TARGETS "${PROJECT_NAME}" DESTINATION "lib")
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
@@ -1,30 +1,46 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ import fs, { mkdirSync } from 'node:fs';
3
4
  import { Command, Option } from 'commander';
4
- import fs from 'fs';
5
5
  import glob from 'glob';
6
- import { createDir } from './utils/createTempDir.js';
7
- import getPathInfo from './utils/getPathInfo.js';
8
-
9
- import CppjsCompiler from './index.js';
6
+ import upath from 'upath';
7
+ import replace from 'replace';
8
+
9
+ import { state } from './index.js';
10
+ import createBridgeFile from './actions/createInterface.js';
11
+ import createLib from './actions/createLib.js';
12
+ import buildWasm from './actions/buildWasm.js';
13
+ import createXCFramework from './actions/createXCFramework.js';
14
+ import runCppjsApp from './actions/run.js';
15
+ import downloadAndExtractFile from './utils/downloadAndExtractFile.js';
16
+ import writeJson from './utils/writeJson.js';
10
17
 
11
18
  const packageJSON = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url)));
12
19
 
13
20
  const program = new Command();
14
21
 
15
22
  program
16
- .name('cpp.js')
23
+ .name('cppjs')
17
24
  .description('Compile C++ files to WebAssembly and native platforms.')
18
25
  .version(packageJSON.version)
19
26
  .showHelpAfterError();
20
27
 
21
28
  const commandBuild = program.command('build')
22
29
  .description('compile the project that was set up using Cpp.js')
23
- .addOption(new Option('-p, --platform <platform>', 'target platform').default('all').choices(['all', 'wasm', 'android', 'ios']));
30
+ .addOption(new Option('-p, --platform <platform>', 'target platform').default('All').choices(['All', 'WebAssembly', 'Android', 'iOS']));
24
31
 
25
32
  const commandRun = program.command('run')
26
33
  .description('run docker application');
27
34
 
35
+ const commandConfig = program.command('config')
36
+ .description('Manage the cpp.js configuration files');
37
+
38
+ commandConfig.command('get').description('get cpp.js system configuration');
39
+ commandConfig.command('set').description('set cpp.js system configuration');
40
+ commandConfig.command('delete').description('delete cpp.js system configuration');
41
+ const commandConfigList = commandConfig.command('list').description('list cpp.js configuration')
42
+ .addOption(new Option('-t, --type <type>', 'config type').default('all').choices(['all', 'system', 'project']));
43
+
28
44
  const commandPostInstall = program.command('postinstall')
29
45
  .description('prepare the required packages for Cpp.js after installation');
30
46
 
@@ -33,7 +49,11 @@ program.parse(process.argv);
33
49
  switch (program.args[0]) {
34
50
  case 'build': {
35
51
  const { platform } = commandBuild.opts();
36
- build(platform);
52
+ if (state.config.build) {
53
+ buildExternal(platform);
54
+ } else {
55
+ build(platform);
56
+ }
37
57
  break;
38
58
  }
39
59
  case 'run': {
@@ -41,6 +61,25 @@ switch (program.args[0]) {
41
61
  run(programName, params);
42
62
  break;
43
63
  }
64
+ case 'config': {
65
+ switch (program.args[1]) {
66
+ case 'get':
67
+ getSystemConfig(program.args[2]);
68
+ break;
69
+ case 'set':
70
+ setSystemConfig(program.args[2], program.args[3]);
71
+ break;
72
+ case 'delete':
73
+ deleteSystemConfig(program.args[2]);
74
+ break;
75
+ case 'list':
76
+ listSystemConfig(commandConfigList.opts().type);
77
+ break;
78
+ default:
79
+ break;
80
+ }
81
+ break;
82
+ }
44
83
  case 'postinstall': {
45
84
  postInstall();
46
85
  break;
@@ -49,6 +88,37 @@ switch (program.args[0]) {
49
88
  break;
50
89
  }
51
90
 
91
+ function getSystemConfig(key) {
92
+ console.log(state.config.system[key]);
93
+ }
94
+
95
+ function setSystemConfig(key, value) {
96
+ state.config.system[key] = value;
97
+ writeJson(state.config.paths.systemConfig, state.config.system);
98
+ }
99
+
100
+ function deleteSystemConfig(key) {
101
+ delete state.config.system[key];
102
+ writeJson(state.config.paths.systemConfig, state.config.system);
103
+ }
104
+
105
+ function listSystemConfig(type) {
106
+ const { system: systemConfig, ...projectConfig } = state.config;
107
+ if (type === 'all' || type === 'system') {
108
+ console.log('System Configuration');
109
+ console.log(JSON.stringify(systemConfig, null, 2));
110
+ }
111
+
112
+ if (type === 'all') {
113
+ console.log('');
114
+ }
115
+
116
+ if (type === 'all' || type === 'project') {
117
+ console.log('Project Configuration');
118
+ console.log(JSON.stringify(projectConfig, null, 2));
119
+ }
120
+ }
121
+
52
122
  function postInstall() {
53
123
  const projectPath = process.env.PWD;
54
124
  const isDarwin = process.platform === 'darwin';
@@ -63,16 +133,15 @@ function postInstall() {
63
133
  return;
64
134
  }
65
135
 
66
- const cppjs = new CppjsCompiler();
67
- const name = cppjs?.config?.general?.name;
68
- let dist = cppjs?.config?.paths?.output;
69
- dist = dist ? getPathInfo(dist, projectPath).relative : null;
136
+ const name = state?.config?.general?.name;
137
+ let dist = state?.config?.paths?.output;
138
+ dist = dist ? upath.relative(projectPath, dist) : null;
70
139
 
71
140
  if (!name || !dist) {
72
141
  return;
73
142
  }
74
143
 
75
- cppjs?.config?.export?.libName?.forEach((fileName) => {
144
+ state?.config?.export?.libName?.forEach((fileName) => {
76
145
  if (fs.existsSync(`${projectPath}/${fileName}.xcframework`) || !fs.existsSync(`${dist}/prebuilt/${fileName}.xcframework`)) {
77
146
  return;
78
147
  }
@@ -81,87 +150,93 @@ function postInstall() {
81
150
  }
82
151
 
83
152
  function run(programName, params) {
84
- const compiler = new CppjsCompiler();
85
- compiler.run(programName, params, { console: true });
153
+ runCppjsApp(programName, params, null, null, { console: true });
86
154
  }
87
155
 
88
- function build(platform) {
89
- const compiler2 = new CppjsCompiler();
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 }));
95
- });
156
+ async function buildExternal(platform) {
157
+ const version = state.config.package.nativeVersion;
158
+ if (!version) {
159
+ console.error('no version found!');
160
+ return;
161
+ }
96
162
 
97
- if (platform === 'all' || platform === 'wasm') {
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}`);
163
+ const { getURL, replaceList, copyToSource } = state.config.build;
164
+ const isNewlyCreated = await downloadAndExtractFile(getURL(version), state.config.paths.build);
165
+ const sourcePath = `${state.config.paths.build}/source`;
166
+ if (isNewlyCreated && replaceList) {
167
+ replaceList.forEach(({ regex, replacement, paths }) => {
168
+ replace({
169
+ regex, replacement, paths: paths.map((p) => `${sourcePath}/${p}`), recursive: false, silent: true,
104
170
  });
105
- }
171
+ });
106
172
  }
107
173
 
108
- if (platform === 'wasm') return;
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
- });
174
+ if (isNewlyCreated && copyToSource) {
175
+ Object.entries(copyToSource).forEach(([key, value]) => {
176
+ fs.copyFileSync(`${state.config.paths.project}/${key}`, `${sourcePath}/${value}`);
177
+ });
178
+ }
179
+
180
+ await buildLib(platform);
181
+ }
182
+
183
+ async function build(platform) {
184
+ buildLib(platform);
185
+ if (platform === 'WebAssembly' || platform === 'All') {
186
+ createWasmJs();
187
+ }
188
+ }
189
+
190
+ async function buildLib(platform) {
191
+ state.platforms[platform].forEach((p) => {
192
+ if (!fs.existsSync(`${state.config.paths.output}/prebuilt/${p}/lib`)) {
193
+ createLib(p, 'Source', { isProd: true, buildSource: true });
194
+ } else {
195
+ console.log(`${state.config.general.name} is already compiled to ${p} architecture.`);
123
196
  }
124
197
  });
125
- if (platform === 'all' || platform === 'ios') {
126
- compiler2.finishBuild();
127
- }
128
198
 
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);
199
+ fs.cpSync(`${state.config.paths.build}/Source-Release/prebuilt`, `${state.config.paths.output}/prebuilt`, { recursive: true, dereference: true });
200
+
201
+ createXCFramework();
202
+
203
+ const distCmakeContent = fs.readFileSync(`${state.config.paths.cli}/assets/dist.cmake`, { encoding: 'utf8', flag: 'r' })
204
+ .replace('___PROJECT_NAME___', state.config.general.name).replace('___PROJECT_LIBS___', state.config.export.libName.join(';'));
205
+ fs.writeFileSync(`${state.config.paths.output}/prebuilt/CMakeLists.txt`, distCmakeContent);
132
206
  }
133
207
 
134
- async function buildWasm() {
208
+ async function createWasmJs() {
135
209
  let headers = [];
136
-
137
- const compiler = new CppjsCompiler();
138
- compiler.config.paths.header.forEach((headerPath) => {
210
+ state.config.paths.header.forEach((headerPath) => {
139
211
  headers.push(glob.sync('**/*.h', { absolute: true, cwd: headerPath }));
140
212
  });
141
213
  headers = headers.filter((path) => !!path.toString()).flat();
142
214
 
215
+ const bridges = [];
143
216
  headers.forEach((header) => {
144
- compiler.findOrCreateInterfaceFile(header);
217
+ const bridgePath = createBridgeFile(header);
218
+ bridges.push(bridgePath);
145
219
  });
146
220
 
147
- compiler.createBridge();
148
- await compiler.createWasm({ cc: ['-O3'] });
149
- createDir('prebuilt/Emscripten-x86_64/lib', compiler.config.paths.output);
221
+ const opt = {
222
+ isProd: true,
223
+ buildSource: false,
224
+ nativeGlob: bridges,
225
+ };
226
+ createLib('Emscripten-x86_64', 'Bridge', opt);
150
227
 
151
- fs.renameSync(`${compiler.config.paths.temp}/lib/lib${compiler.config.general.name}.a`, `${compiler.config.paths.output}/prebuilt/Emscripten-x86_64/lib/lib${compiler.config.general.name}.a`);
152
- fs.renameSync(`${compiler.config.paths.temp}/include/`, `${compiler.config.paths.output}/prebuilt/Emscripten-x86_64/include`);
228
+ await buildWasm('browser', true);
229
+ await buildWasm('node', true);
153
230
 
154
- fs.rmSync(`${compiler.config.paths.output}/data`, { recursive: true, force: true });
155
- if (fs.existsSync(`${compiler.config.paths.temp}/data`)) {
156
- fs.renameSync(`${compiler.config.paths.temp}/data`, `${compiler.config.paths.output}/data`);
231
+ fs.rmSync(`${state.config.paths.output}/data`, { recursive: true, force: true });
232
+ if (fs.existsSync(`${state.config.paths.build}/data`)) {
233
+ fs.renameSync(`${state.config.paths.build}/data`, `${state.config.paths.output}/data`);
157
234
  }
158
235
 
159
- fs.copyFileSync(`${compiler.config.paths.temp}/${compiler.config.general.name}.node.js`, `${compiler.config.paths.output}/${compiler.config.general.name}.node.js`);
160
- fs.copyFileSync(`${compiler.config.paths.temp}/${compiler.config.general.name}.browser.js`, `${compiler.config.paths.output}/${compiler.config.general.name}.browser.js`);
161
- fs.copyFileSync(`${compiler.config.paths.temp}/${compiler.config.general.name}.wasm`, `${compiler.config.paths.output}/${compiler.config.general.name}.wasm`);
162
- if (fs.existsSync(`${compiler.config.paths.temp}/${compiler.config.general.name}.data.txt`)) {
163
- fs.copyFileSync(`${compiler.config.paths.temp}/${compiler.config.general.name}.data.txt`, `${compiler.config.paths.output}/${compiler.config.general.name}.data.txt`);
236
+ fs.copyFileSync(`${state.config.paths.build}/${state.config.general.name}.node.js`, `${state.config.paths.output}/${state.config.general.name}.node.js`);
237
+ fs.copyFileSync(`${state.config.paths.build}/${state.config.general.name}.browser.js`, `${state.config.paths.output}/${state.config.general.name}.browser.js`);
238
+ fs.copyFileSync(`${state.config.paths.build}/${state.config.general.name}.wasm`, `${state.config.paths.output}/${state.config.general.name}.wasm`);
239
+ if (fs.existsSync(`${state.config.paths.build}/${state.config.general.name}.data.txt`)) {
240
+ fs.copyFileSync(`${state.config.paths.build}/${state.config.general.name}.data.txt`, `${state.config.paths.output}/${state.config.general.name}.data.txt`);
164
241
  }
165
-
166
- fs.rmSync(compiler.config.paths.temp, { recursive: true, force: true });
167
242
  }
@@ -0,0 +1,51 @@
1
+ import getData from '../actions/getData.js';
2
+ import loadJson from '../utils/loadJson.js';
3
+
4
+ export default function exportReactNative(platform, bridgePath = null) {
5
+ const env = JSON.stringify(getData('env', platform));
6
+
7
+ const bridgeExportFile = `${bridgePath}.exports.json`;
8
+ let symbols = null;
9
+ if (bridgePath) {
10
+ symbols = loadJson(bridgeExportFile);
11
+ }
12
+
13
+ let symbolExportDefineString = '';
14
+ let symbolExportAssignString = '';
15
+ if (symbols && Array.isArray(symbols)) {
16
+ symbolExportDefineString = symbols.map((s) => `export let ${s} = null;`).join('\n');
17
+ symbolExportAssignString = symbols.map((s) => `${s} = Module.${s};`).join('\n');
18
+ }
19
+
20
+ return `
21
+ import { NativeModules } from 'react-native';
22
+ import Module from '@cpp.js/core-embind-jsi';
23
+
24
+ const { RNJsiLib } = NativeModules;
25
+
26
+ function setEnv() {
27
+ const env = JSON.parse('${env}');
28
+ const CPPJS_DATA_PATH = Module.CppJS.getEnv('CPPJS_DATA_PATH');
29
+
30
+ Object.entries(env).forEach(([key, value]) => {
31
+ Module.CppJS.setEnv(key, value.replace('_CPPJS_DATA_PATH_', CPPJS_DATA_PATH), true);
32
+ });
33
+ }
34
+
35
+ export let AllSymbols = {};
36
+ ${symbolExportDefineString}
37
+ export function initCppJs(config = {}) {
38
+ return new Promise((resolve, reject) => {
39
+ if (RNJsiLib && RNJsiLib.start) {
40
+ RNJsiLib.start();
41
+ setEnv();
42
+ AllSymbols = Module;
43
+ ${symbolExportAssignString}
44
+ resolve(Module);
45
+ } else {
46
+ reject('Module failed to initialise.');
47
+ }
48
+ });
49
+ }
50
+ `;
51
+ }