cpp.js 0.3.2 → 0.4.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cpp.js",
3
- "version": "0.3.2",
3
+ "version": "0.4.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "bin": {
@@ -12,8 +12,7 @@
12
12
  "glob": "^8.0.3"
13
13
  },
14
14
  "devDependencies": {
15
- "mocha": "^10.2.0",
16
- "cppjs-lib-sample-web": "^0.1.0"
15
+ "mocha": "^10.2.0"
17
16
  },
18
17
  "scripts": {
19
18
  "test": "mocha"
@@ -1,23 +1,37 @@
1
- cmake_minimum_required(VERSION 3.1)
1
+ cmake_minimum_required(VERSION 3.25)
2
2
  project("${PROJECT_NAME}")
3
3
 
4
4
  option(BUILD_BRIDGE "Build Bridge" OFF)
5
5
  option(BUILD_SOURCE "Build Source" OFF)
6
6
 
7
7
  if(BUILD_SOURCE)
8
- file(GLOB BUILD_SRC_FILES "${BASE_DIR}/native/**/*.cpp" "${BASE_DIR}/native/*.cpp" "${BASE_DIR}/src/native/**/*.cpp" "${BASE_DIR}/src/native/*.cpp")
8
+ file(GLOB_RECURSE BUILD_SRC_FILES ${NATIVE_GLOB})
9
9
  endif(BUILD_SOURCE)
10
- unset(BUILD_SOURCE CACHE)
11
-
12
- message("aa", BUILD_SRC_FILES)
13
10
 
14
11
  if(BUILD_BRIDGE)
15
12
  file(GLOB BRIDGE_SRC_FILES "${BRIDGE_DIR}/*.i.cpp")
16
13
  endif(BUILD_BRIDGE)
17
- unset(BUILD_BRIDGE CACHE)
18
14
 
19
15
  set(SRC_FILES "${BUILD_SRC_FILES}" "${BRIDGE_SRC_FILES}")
20
16
  add_library("${PROJECT_NAME}" STATIC ${SRC_FILES})
21
17
 
22
- file(GLOB HEADERS "${BASE_DIR}/node_modules/cppjs-lib-*/include")
23
- include_directories("${HEADERS};${BASE_DIR}/native;${BASE_DIR}/src/native")
18
+ file(GLOB LIB_HEADERS_DIR "${BASE_DIR}/node_modules/cppjs-lib-*/include" "${BASE_DIR}/node_modules/cppjs-lib-*/node_modules/cppjs-lib-*/include")
19
+ file(GLOB_RECURSE HEADER_FILES ${HEADER_GLOB})
20
+ target_include_directories("${PROJECT_NAME}" PUBLIC "${LIB_HEADERS_DIR}" "${HEADER_DIR}")
21
+
22
+ if(BUILD_SOURCE)
23
+ target_sources("${PROJECT_NAME}"
24
+ PUBLIC FILE_SET HEADERS
25
+ BASE_DIRS "${HEADER_DIR}"
26
+ FILES "${HEADER_FILES}")
27
+
28
+ string(REPLACE "-" ";" HEADER_FOLDER ${PROJECT_NAME})
29
+ list(GET HEADER_FOLDER 2 HEADER_FOLDER)
30
+ install(TARGETS "${PROJECT_NAME}" FILE_SET HEADERS DESTINATION "include/cppjs-lib-${HEADER_FOLDER}")
31
+ endif(BUILD_SOURCE)
32
+ unset(BUILD_SOURCE CACHE)
33
+
34
+ if(BUILD_BRIDGE)
35
+ install(TARGETS "${PROJECT_NAME}")
36
+ endif(BUILD_BRIDGE)
37
+ unset(BUILD_BRIDGE CACHE)
package/src/bin.js CHANGED
@@ -45,19 +45,21 @@ function generateLib(platform, output, base) {
45
45
 
46
46
  const compiler = new CppjsCompiler();
47
47
  compiler.config.paths.header.forEach(headerPath => {
48
- headers.push(glob.sync("*.h", { absolute: true, cwd: headerPath }));
48
+ headers.push(glob.sync("**/*.h", { absolute: true, cwd: headerPath }));
49
49
  });
50
50
  headers = headers.filter(path => !!path.toString()).flat();
51
51
 
52
52
  headers.forEach(header => {
53
53
  compiler.findOrCreateInterfaceFile(header);
54
- compiler.createBridge();
55
- compiler.createWasm({ cc: ['-O3'] });
56
- createDir('lib', compiler.config.paths.output);
57
- fs.copyFileSync(`${compiler.config.paths.temp}/${compiler.config.general.name}.js`, `${compiler.config.paths.output}/${compiler.config.general.name}.js`);
58
- fs.copyFileSync(`${compiler.config.paths.temp}/${compiler.config.general.name}.wasm`, `${compiler.config.paths.output}/${compiler.config.general.name}.wasm`);
59
- fs.copyFileSync(`${compiler.config.paths.temp}/lib${compiler.config.general.name}.a`, `${compiler.config.paths.output}/lib/lib${compiler.config.general.name}.a`);
60
- fs.rmSync(compiler.config.paths.temp, { recursive: true, force: true });
61
54
  });
62
55
 
56
+ compiler.createBridge();
57
+ compiler.createWasm({ cc: ['-O3'] });
58
+ createDir('lib', compiler.config.paths.output);
59
+ fs.copyFileSync(`${compiler.config.paths.temp}/${compiler.config.general.name}.js`, `${compiler.config.paths.output}/${compiler.config.general.name}.js`);
60
+ fs.copyFileSync(`${compiler.config.paths.temp}/${compiler.config.general.name}.wasm`, `${compiler.config.paths.output}/${compiler.config.general.name}.wasm`);
61
+ fs.copyFileSync(`${compiler.config.paths.temp}/lib${compiler.config.general.name}.a`, `${compiler.config.paths.output}/lib/lib${compiler.config.general.name}.a`);
62
+ fs.rmSync(`${compiler.config.paths.output}/include`, { recursive: true, force: true });
63
+ fs.renameSync(`${compiler.config.paths.temp}/include`, `${compiler.config.paths.output}/include`);
64
+ fs.rmSync(compiler.config.paths.temp, { recursive: true, force: true });
63
65
  }
@@ -1,6 +1,6 @@
1
1
  import glob from 'glob';
2
2
  import { execFileSync } from 'child_process';
3
- import pullDockerImage from '../utils/pullDockerImage.js';
3
+ import pullDockerImage, { getDockerImage } from '../utils/pullDockerImage.js';
4
4
  import getBaseInfo from '../utils/getBaseInfo.js';
5
5
  import getPathInfo from '../utils/getPathInfo.js';
6
6
  import getOsUserAndGroupId from '../utils/getOsUserAndGroupId.js';
@@ -16,14 +16,14 @@ export default function createBridge(compiler) {
16
16
  const base = getBaseInfo(compiler.config.paths.base);
17
17
 
18
18
  const includePath = [
19
- glob.sync("node_modules/cppjs-lib-*-web/include", { absolute: false }),
20
- glob.sync("native", { absolute: false }),
21
- glob.sync("src/native", { absolute: false }),
22
- ].filter(path => !!path.toString()).map(path => `-I/live/${projectPath.relative}/${path}`);
19
+ ...glob.sync("node_modules/cppjs-lib-*/include", { absolute: true, cwd: compiler.config.paths.project }),
20
+ ...glob.sync("node_modules/cppjs-lib-*/node_modules/cppjs-lib-*/include", { absolute: true, cwd: compiler.config.paths.project }),
21
+ ...compiler.config.paths.header,
22
+ ].filter(path => !!path.toString()).map(path => `-I/live/${getPathInfo(path, compiler.config.paths.base).relative}`);
23
23
 
24
24
  const options = { cwd: output.absolute, stdio : 'pipe' };
25
25
  const args = [
26
- "run", "--user", getOsUserAndGroupId(), "-v", `${base.withoutSlash}:/live`, "bugra9/cpp.js",
26
+ "run", "--user", getOsUserAndGroupId(), "-v", `${base.withoutSlash}:/live`, getDockerImage(),
27
27
  "swig", "-c++", '-emscripten', '-o', `/live/${output.relative}/${filePath.split('/').at(-1)}.cpp`, ...includePath, `/live/${input.relative}`
28
28
  ];
29
29
  execFileSync("docker", args, options);
@@ -1,45 +1,42 @@
1
1
  import { execFileSync } from 'child_process';
2
- import pullDockerImage from '../utils/pullDockerImage.js';
2
+ import glob from 'glob';
3
+ import pullDockerImage, { getDockerImage } from '../utils/pullDockerImage.js';
3
4
  import getBaseInfo from '../utils/getBaseInfo.js';
4
5
  import getPathInfo from '../utils/getPathInfo.js';
5
6
  import getOsUserAndGroupId from '../utils/getOsUserAndGroupId.js';
6
7
 
7
8
  export default function createWasm(compiler, options = {}) {
8
9
  const compiler2 = new CppjsCompiler(
9
- compiler.config.paths.cmake,
10
- compiler.config.paths.output,
11
- compiler.config.paths.temp,
12
- compiler.config.paths.cli,
13
- compiler.config.general.name,
10
+ compiler.config,
14
11
  options,
15
- compiler.config.paths.base
16
12
  );
17
13
  return compiler2.compile();
18
14
  }
19
15
 
20
16
  class CppjsCompiler {
21
- constructor(cMakeFilePath, outputPath, tempPath, cliPath, name, options = {}, basePath = process.cwd()) {
22
- this.cMakeFilePath = cMakeFilePath;
23
- this.outputPath = tempPath;
24
- this.tempPath = tempPath;
25
- this.cliPath = cliPath;
17
+ constructor(config, options) {
18
+ this.config = config;
26
19
  this.options = options;
27
- this.basePath = basePath;
28
- this.name = name;
29
20
  }
30
21
 
31
22
  compile() {
32
23
  pullDockerImage();
33
24
 
34
- this.cmake(this.name, true, false);
25
+ this.cmake(this.config.general.name, true, false);
35
26
  this.make();
36
- this.cmake(this.name+'bridge', false, true);
27
+ this.cmake(this.config.general.name+'bridge', false, true);
37
28
  this.make();
38
- this.libs = [`lib${this.name}.a`, `lib${this.name}bridge.a`];
29
+
30
+ this.libs = [
31
+ `${this.config.paths.temp}/lib${this.config.general.name}.a`,
32
+ `${this.config.paths.temp}/lib${this.config.general.name}bridge.a`,
33
+ ...glob.sync("node_modules/cppjs-lib-*-wasm/lib/lib*.a", { absolute: true, cwd: this.config.paths.project }),
34
+ ...glob.sync("node_modules/cppjs-lib-*-wasm/node_modules/cppjs-lib-*-wasm/lib/lib*.a", { absolute: true, cwd: this.config.paths.project }),
35
+ ].filter(path => !!path.toString()).map(path => `/live/${getPathInfo(path, this.config.paths.base).relative}`);
39
36
 
40
37
  this.cc();
41
38
 
42
- return this.outputPath;
39
+ return this.config.paths.temp;
43
40
  }
44
41
 
45
42
  cmake(name, isBuildSource, isBuildBridge) {
@@ -47,49 +44,55 @@ class CppjsCompiler {
47
44
  if (isBuildSource) params.push('-DBUILD_SOURCE=TRUE');
48
45
  if (isBuildBridge) params.push('-DBUILD_BRIDGE=TRUE');
49
46
 
50
- const output = getPathInfo(this.outputPath, this.basePath);
51
- const projectPath = getPathInfo(process.cwd(), this.basePath);
52
- const base = getBaseInfo(this.basePath);
47
+ const output = getPathInfo(this.config.paths.temp, this.config.paths.base);
48
+ const projectPath = getPathInfo(process.cwd(), this.config.paths.base);
49
+ const native = this.config.paths.native.map(p => `/live/${getPathInfo(p, this.config.paths.base).relative}`).join(';');
50
+ const header = this.config.paths.header.map(p => `/live/${getPathInfo(p, this.config.paths.base).relative}`).join(';');
51
+ const base = getBaseInfo(this.config.paths.base);
53
52
 
54
- let cMakeParentPath = this.cMakeFilePath.split('/');
53
+ let cMakeParentPath = this.config.paths.cmake.split('/');
55
54
  cMakeParentPath.pop();
56
55
  cMakeParentPath = cMakeParentPath.join('/');
57
56
  const args = [
58
- "run", "--user", getOsUserAndGroupId(), "-v", `${base.withoutSlash}:/live`, "-v", `${cMakeParentPath}:/cmake`, "--workdir", `/live/${output.relative}`, "bugra9/cpp.js",
59
- "emcmake", "cmake", "/cmake", `-DBASE_DIR=/live/${projectPath.relative}`,
57
+ "run", "--user", getOsUserAndGroupId(), "-v", `${base.withoutSlash}:/live`, "-v", `${cMakeParentPath}:/cmake`, "--workdir", `/live/${output.relative}`, getDockerImage(),
58
+ "emcmake", "cmake", "/cmake", '-DCMAKE_BUILD_TYPE=Release',
59
+ `-DBASE_DIR=/live/${projectPath.relative}`,
60
+ `-DNATIVE_GLOB=${this.config.ext.source.map(ext => `${native}/*.${ext}`).join(';')}`,
61
+ `-DHEADER_GLOB=${this.config.ext.header.map(ext => `${header}/*.${ext}`).join(';')}`,
62
+ `-DHEADER_DIR=${header}`,
60
63
  `-DCMAKE_INSTALL_PREFIX=/live/${output.relative}`, `-DBRIDGE_DIR=/live/${output.relative}/bridge`, `-DPROJECT_NAME=${name}`, ...params,
61
64
  ];
62
- const options = { cwd: this.outputPath, stdio : 'pipe' };
65
+ const options = { cwd: this.config.paths.temp, stdio : 'pipe' };
63
66
  execFileSync("docker", args, options);
64
- return this.outputPath;
67
+ return this.config.paths.temp;
65
68
  }
66
69
 
67
70
  make() {
68
- const output = getPathInfo(this.outputPath, this.basePath);
69
- const base = getBaseInfo(this.basePath);
71
+ const output = getPathInfo(this.config.paths.temp, this.config.paths.base);
72
+ const base = getBaseInfo(this.config.paths.base);
70
73
 
71
- let cMakeParentPath = this.cMakeFilePath.split('/');
74
+ let cMakeParentPath = this.config.paths.cmake.split('/');
72
75
  cMakeParentPath.pop();
73
76
  cMakeParentPath = cMakeParentPath.join('/');
74
77
  const args = [
75
- "run", "--user", getOsUserAndGroupId(), "-v", `${base.withoutSlash}:/live`, "-v", `${cMakeParentPath}:/cmake`, "--workdir", `/live/${output.relative}`, "bugra9/cpp.js",
76
- "emmake", "make"
78
+ "run", "--user", getOsUserAndGroupId(), "-v", `${base.withoutSlash}:/live`, "-v", `${cMakeParentPath}:/cmake`, "--workdir", `/live/${output.relative}`, getDockerImage(),
79
+ "emmake", "make", "install"
77
80
  ];
78
- const options = { cwd: this.outputPath, stdio : 'pipe' };
81
+ const options = { cwd: this.config.paths.temp, stdio : 'pipe' };
79
82
  execFileSync("docker", args, options);
80
- return this.outputPath;
83
+ return this.config.paths.temp;
81
84
  }
82
85
 
83
86
  cc() {
84
- const input = getPathInfo(this.tempPath, this.basePath);
85
- const output = getPathInfo(this.outputPath, this.basePath);
86
- const base = getBaseInfo(this.basePath);
87
+ const input = getPathInfo(this.config.paths.temp, this.config.paths.base);
88
+ const output = getPathInfo(this.config.paths.temp, this.config.paths.base);
89
+ const base = getBaseInfo(this.config.paths.base);
87
90
  const args = [
88
- "run", "--user", getOsUserAndGroupId(), "-v", `${base.withoutSlash}:/live`, "-v", `${this.cliPath}:/cli`, "bugra9/cpp.js",
89
- "emcc", "-lembind", "-Wl,--whole-archive", ...this.libs.map(lib => `/live/${input.relative}/${lib}`), ...(this.options.cc || []), "-s", "WASM=1", "-s", "MODULARIZE=1", '-o', `/live/${output.relative}/${this.name}.js`, '--extern-post-js', '/cli/assets/extern-post.js'
91
+ "run", "--user", getOsUserAndGroupId(), "-v", `${base.withoutSlash}:/live`, "-v", `${this.config.paths.cli}:/cli`, getDockerImage(),
92
+ "emcc", "-lembind", "-Wl,--whole-archive", ...this.libs, ...(this.options.cc || []), "-s", "WASM=1", "-s", "MODULARIZE=1", '-o', `/live/${output.relative}/${this.config.general.name}.js`, '--extern-post-js', '/cli/assets/extern-post.js'
90
93
  ];
91
- const options = { cwd: this.tempPath, stdio : 'pipe' };
94
+ const options = { cwd: this.config.paths.temp, stdio : 'pipe' };
92
95
  execFileSync("docker", args, options);
93
- return this.outputPath;
96
+ return this.config.paths.temp;
94
97
  }
95
98
  }
@@ -16,7 +16,10 @@ export default function findOrCreateInterfaceFile(compiler, filePath) {
16
16
  if (fs.existsSync(interfaceFile)) return interfaceFile;
17
17
 
18
18
  const fileName = filePathWithoutExt.split('/').at(-1);
19
- const fileNameWithExt = input.relative.split('/').at(-1);
19
+
20
+ let headerPath = compiler.config.paths.header.find(path => filePath.startsWith(path));
21
+ if (headerPath) headerPath = filePath.substr(headerPath.length+1);
22
+ else headerPath = input.relative.split('/').at(-1);
20
23
 
21
24
  const content =
22
25
  `#ifndef _${fileName.toUpperCase()}_I
@@ -25,10 +28,10 @@ export default function findOrCreateInterfaceFile(compiler, filePath) {
25
28
  %module ${fileName.toUpperCase()}
26
29
 
27
30
  %{
28
- #include "${fileNameWithExt}"
31
+ #include "${headerPath}"
29
32
  %}
30
33
 
31
- %include "${fileNameWithExt}"
34
+ %include "${headerPath}"
32
35
 
33
36
  #endif
34
37
  `;
@@ -14,7 +14,7 @@ const require = createRequire(import.meta.url);
14
14
  * @typedef {Object} Config
15
15
  * @property {string} general General
16
16
  * @property {ConfigPaths} paths Paths
17
- * @property {ConfigExtensions} extensions Extensions
17
+ * @property {ConfigExtensions} ext Extensions
18
18
  */
19
19
 
20
20
  /**
@@ -22,7 +22,7 @@ const require = createRequire(import.meta.url);
22
22
  * @property {string} project Project path.
23
23
  * @property {string} base Base path (Use for monorepo structure)
24
24
  * @property {string} temp Temp path.
25
- * @property {string} native Native path (default: ['native', 'src/native']).
25
+ * @property {string} native Native path (default: ['src/native']).
26
26
  * @property {string} module Module path (default: native path)
27
27
  * @property {string} header Header path (default: native path)
28
28
  * @property {string} bridge Bridge path (default: native and temp path)
@@ -43,7 +43,7 @@ const require = createRequire(import.meta.url);
43
43
  */
44
44
 
45
45
  export default function getConfig(param) {
46
- let tempConfig = { general: {}, paths: {}, extensions: {} };
46
+ let tempConfig = { general: {}, paths: {}, ext: {} };
47
47
 
48
48
  if (!param || (typeof param === 'string' || param instanceof String)) {
49
49
  const ext = (param || '').split('.').at(-1)
@@ -79,7 +79,7 @@ function forceToConfigSchema(tempConfig) {
79
79
  const config = {
80
80
  general: tempConfig && tempConfig.general ? tempConfig.general : {},
81
81
  paths: tempConfig && tempConfig.paths ? tempConfig.paths : {},
82
- extensions: tempConfig && tempConfig.extensions ? tempConfig.extensions : {},
82
+ ext: tempConfig && tempConfig.ext ? tempConfig.ext : {},
83
83
  };
84
84
  return config;
85
85
  }
@@ -103,7 +103,7 @@ function fillConfig(tempConfig) {
103
103
  paths: {
104
104
  project: getAbsolutePath(null, tempConfig.paths.project) || process.cwd(),
105
105
  },
106
- extensions: {},
106
+ ext: {},
107
107
  };
108
108
 
109
109
  if (!config.general.name) {
@@ -121,7 +121,7 @@ function fillConfig(tempConfig) {
121
121
 
122
122
  config.paths.base = getPath(tempConfig.paths.base) || config.paths.project;
123
123
  config.paths.temp = getPath(tempConfig.paths.temp) || createTempDir(undefined, config.paths.project)
124
- config.paths.native = (tempConfig.paths.native || ['native', 'src/native']).map(p => getPath(p));
124
+ config.paths.native = (tempConfig.paths.native || ['src/native']).map(p => getPath(p));
125
125
  config.paths.module = (tempConfig.paths.module || config.paths.native).map(p => getPath(p));
126
126
  config.paths.header = (tempConfig.paths.header || config.paths.native).map(p => getPath(p));
127
127
  config.paths.bridge = (tempConfig.paths.bridge || [...config.paths.native, config.paths.temp]).map(p => getPath(p));
@@ -129,9 +129,9 @@ function fillConfig(tempConfig) {
129
129
  config.paths.cmake = getPath(tempConfig.paths.cmake || findCMakeListsFile(config.paths.project));
130
130
  config.paths.cli = __dirname;
131
131
 
132
- config.extensions.header = tempConfig.extensions.header || ['h', 'hpp', 'hxx', 'hh'];
133
- config.extensions.source = tempConfig.extensions.source || ['c', 'cpp', 'cxx', 'cc'];
134
- config.extensions.module = tempConfig.extensions.module || ['i'];
132
+ config.ext.header = tempConfig.ext.header || ['h', 'hpp', 'hxx', 'hh'];
133
+ config.ext.source = tempConfig.ext.source || ['c', 'cpp', 'cxx', 'cc'];
134
+ config.ext.module = tempConfig.ext.module || ['i'];
135
135
 
136
136
  createDir('interface', config.paths.temp);
137
137
  createDir('bridge', config.paths.temp);
@@ -1,7 +1,7 @@
1
1
  import { execFileSync } from 'child_process';
2
2
 
3
3
  export default function pullDockerImage() {
4
- const isImageExist = execFileSync("docker", ["images", "-q", "bugra9/cpp.js"], {encoding: 'utf-8'}).trim() !== '';
4
+ const isImageExist = execFileSync("docker", ["images", "-q", getDockerImage()], {encoding: 'utf-8'}).trim() !== '';
5
5
 
6
6
  if (!isImageExist) {
7
7
  console.log('');
@@ -9,9 +9,13 @@ export default function pullDockerImage() {
9
9
  console.log('============= Downloading the docker image... =============');
10
10
  console.log('===========================================================');
11
11
  console.log('');
12
- execFileSync("docker", ["pull", "bugra9/cpp.js"], {stdio: 'inherit'});
12
+ execFileSync("docker", ["pull", getDockerImage], {stdio: 'inherit'});
13
13
  console.log('');
14
14
  console.log('===========================================================');
15
15
  console.log('');
16
16
  }
17
17
  }
18
+
19
+ export function getDockerImage() {
20
+ return "bugra9/cpp.js:0.2.0";
21
+ }