koffi 2.3.4 → 2.3.6-beta.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/CHANGELOG.md +25 -2
- package/doc/changelog.md +4 -0
- package/doc/index.rst +1 -2
- package/doc/types.md +3 -3
- package/package.json +5 -5
- package/src/cnoke/cnoke.js +40 -834
- package/src/cnoke/package.json +1 -0
- package/src/cnoke/src/builder.js +447 -0
- package/src/cnoke/src/index.js +20 -0
- package/src/cnoke/src/tools.js +401 -0
- package/src/core/libcc/libcc.cc +2 -2
- package/src/koffi/build/2.3.6-beta.1/koffi_darwin_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_darwin_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_freebsd_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_freebsd_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_freebsd_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_linux_arm32hf/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_linux_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_linux_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_linux_riscv64hf64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_linux_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_openbsd_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_openbsd_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_arm64/koffi.exp +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_arm64/koffi.lib +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_arm64/koffi.pdb +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_ia32/koffi.exp +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_ia32/koffi.lib +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_ia32/koffi.pdb +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_x64/koffi.exp +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_x64/koffi.lib +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_x64/koffi.pdb +0 -0
- package/src/koffi/src/abi_arm32.cc +43 -14
- package/src/koffi/src/abi_arm64.cc +95 -21
- package/src/koffi/src/abi_riscv64.cc +125 -64
- package/src/koffi/src/abi_x64_sysv.cc +38 -20
- package/src/koffi/src/abi_x64_win.cc +11 -5
- package/src/koffi/src/abi_x86.cc +14 -7
- package/src/koffi/src/call.cc +114 -44
- package/src/koffi/src/call.hh +6 -4
- package/src/koffi/src/ffi.cc +172 -147
- package/src/koffi/src/ffi.hh +18 -10
- package/src/koffi/src/index.d.ts +28 -7
- package/src/koffi/src/index.js +23 -4
- package/src/koffi/src/util.cc +261 -69
- package/src/koffi/src/util.hh +34 -8
- package/vendor/node-addon-api/CHANGELOG.md +122 -9
- package/vendor/node-addon-api/CONTRIBUTING.md +10 -10
- package/vendor/node-addon-api/README.md +36 -12
- package/vendor/node-addon-api/benchmark/function_args.cc +95 -62
- package/vendor/node-addon-api/benchmark/function_args.js +6 -6
- package/vendor/node-addon-api/benchmark/index.js +1 -1
- package/vendor/node-addon-api/benchmark/property_descriptor.cc +27 -34
- package/vendor/node-addon-api/benchmark/property_descriptor.js +5 -4
- package/vendor/node-addon-api/doc/async_operations.md +1 -1
- package/vendor/node-addon-api/doc/async_worker_variants.md +23 -2
- package/vendor/node-addon-api/doc/cmake-js.md +1 -1
- package/vendor/node-addon-api/doc/error_handling.md +3 -3
- package/vendor/node-addon-api/doc/external.md +7 -0
- package/vendor/node-addon-api/doc/handle_scope.md +14 -0
- package/vendor/node-addon-api/doc/hierarchy.md +1 -1
- package/vendor/node-addon-api/doc/object.md +27 -0
- package/vendor/node-addon-api/index.js +3 -3
- package/vendor/node-addon-api/napi-inl.deprecated.h +121 -127
- package/vendor/node-addon-api/napi-inl.h +1178 -1144
- package/vendor/node-addon-api/napi.h +2786 -2675
- package/vendor/node-addon-api/package.json +42 -1
- package/vendor/node-addon-api/test/addon.cc +8 -6
- package/vendor/node-addon-api/test/addon_build/index.js +9 -9
- package/vendor/node-addon-api/test/addon_build/tpl/addon.cc +2 -1
- package/vendor/node-addon-api/test/addon_build/tpl/index.js +4 -4
- package/vendor/node-addon-api/test/addon_data.cc +12 -13
- package/vendor/node-addon-api/test/array_buffer.js +3 -2
- package/vendor/node-addon-api/test/async_progress_queue_worker.cc +13 -3
- package/vendor/node-addon-api/test/async_progress_queue_worker.js +5 -5
- package/vendor/node-addon-api/test/async_progress_worker.cc +65 -9
- package/vendor/node-addon-api/test/async_progress_worker.js +14 -9
- package/vendor/node-addon-api/test/async_worker.cc +236 -3
- package/vendor/node-addon-api/test/async_worker.js +122 -37
- package/vendor/node-addon-api/test/async_worker_nocallback.js +9 -3
- package/vendor/node-addon-api/test/async_worker_persistent.js +2 -2
- package/vendor/node-addon-api/test/basic_types/array.js +3 -4
- package/vendor/node-addon-api/test/basic_types/boolean.cc +4 -2
- package/vendor/node-addon-api/test/basic_types/boolean.js +1 -2
- package/vendor/node-addon-api/test/basic_types/number.cc +12 -6
- package/vendor/node-addon-api/test/basic_types/number.js +19 -18
- package/vendor/node-addon-api/test/basic_types/value.cc +52 -1
- package/vendor/node-addon-api/test/basic_types/value.js +44 -21
- package/vendor/node-addon-api/test/bigint.cc +2 -1
- package/vendor/node-addon-api/test/binding.cc +11 -5
- package/vendor/node-addon-api/test/binding.gyp +3 -1
- package/vendor/node-addon-api/test/buffer.cc +46 -38
- package/vendor/node-addon-api/test/buffer.js +12 -12
- package/vendor/node-addon-api/test/callbackInfo.cc +27 -0
- package/vendor/node-addon-api/test/callbackInfo.js +9 -0
- package/vendor/node-addon-api/test/callbackscope.cc +19 -2
- package/vendor/node-addon-api/test/callbackscope.js +20 -20
- package/vendor/node-addon-api/test/common/index.js +37 -4
- package/vendor/node-addon-api/test/dataview/dataview.js +5 -5
- package/vendor/node-addon-api/test/dataview/dataview_read_write.js +14 -12
- package/vendor/node-addon-api/test/date.cc +2 -1
- package/vendor/node-addon-api/test/date.js +2 -2
- package/vendor/node-addon-api/test/env_cleanup.cc +12 -0
- package/vendor/node-addon-api/test/env_cleanup.js +38 -39
- package/vendor/node-addon-api/test/error.cc +6 -5
- package/vendor/node-addon-api/test/error_terminating_environment.js +64 -60
- package/vendor/node-addon-api/test/external.cc +36 -32
- package/vendor/node-addon-api/test/external.js +43 -46
- package/vendor/node-addon-api/test/function.cc +58 -44
- package/vendor/node-addon-api/test/function.js +4 -0
- package/vendor/node-addon-api/test/function_reference.cc +15 -13
- package/vendor/node-addon-api/test/globalObject/global_object_delete_property.js +50 -53
- package/vendor/node-addon-api/test/globalObject/global_object_get_property.js +33 -34
- package/vendor/node-addon-api/test/globalObject/global_object_has_own_property.js +38 -40
- package/vendor/node-addon-api/test/globalObject/global_object_set_property.js +47 -49
- package/vendor/node-addon-api/test/handlescope.cc +29 -3
- package/vendor/node-addon-api/test/handlescope.js +5 -3
- package/vendor/node-addon-api/test/index.js +1 -5
- package/vendor/node-addon-api/test/maybe/check.cc +49 -3
- package/vendor/node-addon-api/test/maybe/index.js +19 -7
- package/vendor/node-addon-api/test/memory_management.cc +9 -8
- package/vendor/node-addon-api/test/memory_management.js +2 -2
- package/vendor/node-addon-api/test/movable_callbacks.js +2 -2
- package/vendor/node-addon-api/test/name.js +3 -3
- package/vendor/node-addon-api/test/napi_child.js +2 -2
- package/vendor/node-addon-api/test/object/delete_property.js +7 -7
- package/vendor/node-addon-api/test/object/finalizer.cc +13 -12
- package/vendor/node-addon-api/test/object/finalizer.js +2 -2
- package/vendor/node-addon-api/test/object/get_property.js +6 -6
- package/vendor/node-addon-api/test/object/has_own_property.js +3 -3
- package/vendor/node-addon-api/test/object/has_property.js +4 -4
- package/vendor/node-addon-api/test/object/object.cc +191 -111
- package/vendor/node-addon-api/test/object/object.js +53 -52
- package/vendor/node-addon-api/test/object/object_deprecated.cc +24 -20
- package/vendor/node-addon-api/test/object/object_deprecated.js +3 -8
- package/vendor/node-addon-api/test/object/object_freeze_seal.js +54 -54
- package/vendor/node-addon-api/test/object/object_type_tag.cc +39 -0
- package/vendor/node-addon-api/test/object/object_type_tag.js +55 -0
- package/vendor/node-addon-api/test/object/subscript_operator.js +2 -2
- package/vendor/node-addon-api/test/object_reference.js +100 -100
- package/vendor/node-addon-api/test/objectwrap.cc +41 -34
- package/vendor/node-addon-api/test/objectwrap.js +23 -19
- package/vendor/node-addon-api/test/objectwrap_constructor_exception.cc +5 -5
- package/vendor/node-addon-api/test/objectwrap_constructor_exception.js +1 -1
- package/vendor/node-addon-api/test/objectwrap_multiple_inheritance.cc +7 -7
- package/vendor/node-addon-api/test/objectwrap_multiple_inheritance.js +1 -1
- package/vendor/node-addon-api/test/objectwrap_removewrap.js +24 -32
- package/vendor/node-addon-api/test/objectwrap_worker_thread.js +5 -4
- package/vendor/node-addon-api/test/promise.cc +7 -0
- package/vendor/node-addon-api/test/promise.js +3 -1
- package/vendor/node-addon-api/test/reference.cc +1 -1
- package/vendor/node-addon-api/test/reference.js +2 -2
- package/vendor/node-addon-api/test/run_script.cc +1 -1
- package/vendor/node-addon-api/test/symbol.js +59 -66
- package/vendor/node-addon-api/test/testUtil.js +6 -6
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function.cc +64 -29
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function.js +71 -34
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ctx.cc +111 -19
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ctx.js +2 -1
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_existing_tsfn.cc +36 -26
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_existing_tsfn.js +5 -5
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ptr.cc +3 -2
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ptr.js +1 -1
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_sum.cc +47 -32
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_sum.js +3 -3
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_unref.cc +22 -9
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_unref.js +76 -31
- package/vendor/node-addon-api/test/thunking_manual.cc +61 -74
- package/vendor/node-addon-api/test/thunking_manual.js +6 -7
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function.cc +20 -20
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function.js +19 -19
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ctx.cc +57 -5
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ctx.js +2 -0
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_existing_tsfn.js +5 -5
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ptr.cc +5 -1
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ptr.js +4 -3
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_sum.js +3 -3
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_unref.cc +14 -0
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_unref.js +76 -31
- package/vendor/node-addon-api/test/typedarray-bigint.js +2 -2
- package/vendor/node-addon-api/test/typedarray.cc +263 -70
- package/vendor/node-addon-api/test/typedarray.js +44 -10
- package/vendor/node-addon-api/test/version_management.cc +16 -15
- package/vendor/node-addon-api/test/version_management.js +18 -20
- package/vendor/node-addon-api/tools/check-napi.js +13 -14
- package/vendor/node-addon-api/tools/conversion.js +161 -169
- package/vendor/node-addon-api/tools/eslint-format.js +9 -1
- package/vendor/node-addon-api/unit-test/README.md +4 -4
- package/src/koffi/build/2.3.4/koffi_darwin_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_darwin_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_freebsd_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_freebsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_freebsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_linux_arm32hf.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_linux_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_linux_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_linux_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_openbsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_openbsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_win32_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_win32_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_win32_x64.tar.gz +0 -0
package/src/cnoke/cnoke.js
CHANGED
|
@@ -15,56 +15,31 @@
|
|
|
15
15
|
|
|
16
16
|
'use strict';
|
|
17
17
|
|
|
18
|
-
const crypto = require('crypto');
|
|
19
18
|
const fs = require('fs');
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const zlib = require('zlib');
|
|
25
|
-
const { spawnSync } = require('child_process');
|
|
26
|
-
const { Buffer } = require('buffer');
|
|
27
|
-
|
|
28
|
-
// Globals
|
|
29
|
-
|
|
30
|
-
const default_mode = 'RelWithDebInfo';
|
|
31
|
-
|
|
32
|
-
let app_dir = null;
|
|
33
|
-
let project_dir = null;
|
|
34
|
-
let package_dir = null;
|
|
35
|
-
let cache_dir = null;
|
|
36
|
-
let build_dir = null;
|
|
37
|
-
let work_dir = null;
|
|
38
|
-
|
|
39
|
-
let runtime_version = null;
|
|
40
|
-
let arch = null;
|
|
41
|
-
let toolset = null;
|
|
42
|
-
let prefer_clang = false;
|
|
43
|
-
let mode = default_mode;
|
|
44
|
-
let targets = [];
|
|
45
|
-
let verbose = false;
|
|
46
|
-
let prebuild = false;
|
|
47
|
-
let prebuild_url = null;
|
|
48
|
-
let prebuild_req = null;
|
|
49
|
-
|
|
50
|
-
let cmake_bin = null;
|
|
51
|
-
|
|
52
|
-
// Main
|
|
19
|
+
const { Builder } = require('./src/index.js');
|
|
20
|
+
|
|
21
|
+
const VALID_COMMANDS = ['build', 'configure', 'clean'];
|
|
22
|
+
const DEFAULT_MODE = 'RelWithDebInfo';
|
|
53
23
|
|
|
54
24
|
main();
|
|
55
25
|
|
|
56
26
|
async function main() {
|
|
57
|
-
let
|
|
27
|
+
let config = {};
|
|
28
|
+
let command = 'build';
|
|
29
|
+
|
|
30
|
+
// Default options
|
|
31
|
+
config.mode = DEFAULT_MODE;
|
|
58
32
|
|
|
59
33
|
// Parse options
|
|
60
34
|
{
|
|
61
35
|
let i = 2;
|
|
62
36
|
|
|
63
37
|
if (process.argv.length >= 3 && process.argv[2][0] != '-') {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
38
|
+
let cmd = process.argv[2];
|
|
39
|
+
|
|
40
|
+
if (VALID_COMMANDS.includes(cmd)) {
|
|
41
|
+
command = cmd;
|
|
42
|
+
i++;
|
|
68
43
|
}
|
|
69
44
|
}
|
|
70
45
|
|
|
@@ -97,56 +72,50 @@ async function main() {
|
|
|
97
72
|
if (value == null)
|
|
98
73
|
throw new Error(`Missing value for ${arg}`);
|
|
99
74
|
|
|
100
|
-
project_dir = fs.realpathSync(value);
|
|
101
|
-
} else if ((command == build || command == configure) && (arg == '-v' || arg == '--runtime-version')) {
|
|
75
|
+
config.project_dir = fs.realpathSync(value);
|
|
76
|
+
} else if ((command == 'build' || command == 'configure') && (arg == '-v' || arg == '--runtime-version')) {
|
|
102
77
|
if (value == null)
|
|
103
78
|
throw new Error(`Missing value for ${arg}`);
|
|
104
79
|
if (!value.match(/^[0-9]+\.[0-9]+\.[0-9]+$/))
|
|
105
80
|
throw new Error(`Malformed runtime version '${value}'`);
|
|
106
81
|
|
|
107
|
-
runtime_version = value;
|
|
108
|
-
} else if ((command == build || command == configure) && (arg == '-a' || arg == '--arch')) {
|
|
82
|
+
config.runtime_version = value;
|
|
83
|
+
} else if ((command == 'build' || command == 'configure') && (arg == '-a' || arg == '--arch')) {
|
|
109
84
|
if (value == null)
|
|
110
85
|
throw new Error(`Missing value for ${arg}`);
|
|
111
86
|
|
|
112
|
-
arch = value;
|
|
113
|
-
} else if ((command == build || command == configure) && (arg == '-t' || arg == '--toolset')) {
|
|
87
|
+
config.arch = value;
|
|
88
|
+
} else if ((command == 'build' || command == 'configure') && (arg == '-t' || arg == '--toolset')) {
|
|
114
89
|
if (value == null)
|
|
115
90
|
throw new Error(`Missing value for ${arg}`);
|
|
116
91
|
|
|
117
|
-
toolset = value;
|
|
118
|
-
} else if ((command == build || command == configure) && (arg == '-C' || arg == '--prefer-clang')) {
|
|
119
|
-
prefer_clang = true;
|
|
120
|
-
} else if ((command == build || command == configure) && (arg == '-B' || arg == '--config')) {
|
|
92
|
+
config.toolset = value;
|
|
93
|
+
} else if ((command == 'build' || command == 'configure') && (arg == '-C' || arg == '--prefer-clang')) {
|
|
94
|
+
config.prefer_clang = true;
|
|
95
|
+
} else if ((command == 'build' || command == 'configure') && (arg == '-B' || arg == '--config')) {
|
|
121
96
|
if (value == null)
|
|
122
97
|
throw new Error(`Missing value for ${arg}`);
|
|
123
98
|
|
|
124
99
|
switch (value.toLowerCase()) {
|
|
125
|
-
case 'relwithdebinfo': { mode = 'RelWithDebInfo'; } break;
|
|
126
|
-
case 'debug': { mode = 'Debug'; } break;
|
|
127
|
-
case 'release': { mode = 'Release'; } break;
|
|
100
|
+
case 'relwithdebinfo': { config.mode = 'RelWithDebInfo'; } break;
|
|
101
|
+
case 'debug': { config.mode = 'Debug'; } break;
|
|
102
|
+
case 'release': { config.mode = 'Release'; } break;
|
|
128
103
|
|
|
129
104
|
default: {
|
|
130
105
|
throw new Error(`Unknown value '${value}' for ${arg}`);
|
|
131
106
|
} break;
|
|
132
107
|
}
|
|
133
|
-
} else if ((command == build || command == configure) && (arg == '-D' || arg == '--debug')) {
|
|
134
|
-
mode = 'Debug';
|
|
135
|
-
} else if (command == build && arg == '--verbose') {
|
|
136
|
-
verbose = true;
|
|
137
|
-
} else if (command == build && arg == '--prebuild') {
|
|
138
|
-
prebuild = true;
|
|
139
|
-
|
|
140
|
-
} else if (command == build && arg == '--require') {
|
|
108
|
+
} else if ((command == 'build' || command == 'configure') && (arg == '-D' || arg == '--debug')) {
|
|
109
|
+
config.mode = 'Debug';
|
|
110
|
+
} else if (command == 'build' && arg == '--verbose') {
|
|
111
|
+
config.verbose = true;
|
|
112
|
+
} else if (command == 'build' && arg == '--prebuild') {
|
|
113
|
+
config.prebuild = true;
|
|
114
|
+
} else if (command == 'build' && (arg == '-T' || arg == '--target')) {
|
|
141
115
|
if (value == null)
|
|
142
116
|
throw new Error(`Missing value for ${arg}`);
|
|
143
117
|
|
|
144
|
-
|
|
145
|
-
} else if (command == build && (arg == '-T' || arg == '--target')) {
|
|
146
|
-
if (value == null)
|
|
147
|
-
throw new Error(`Missing value for ${arg}`);
|
|
148
|
-
|
|
149
|
-
targets = [value];
|
|
118
|
+
config.targets = [value];
|
|
150
119
|
} else {
|
|
151
120
|
if (arg[0] == '-') {
|
|
152
121
|
throw new Error(`Unexpected argument '${arg}'`);
|
|
@@ -157,24 +126,9 @@ async function main() {
|
|
|
157
126
|
}
|
|
158
127
|
}
|
|
159
128
|
|
|
160
|
-
if (runtime_version == null)
|
|
161
|
-
runtime_version = process.version;
|
|
162
|
-
if (runtime_version.startsWith('v'))
|
|
163
|
-
runtime_version = runtime_version.substr(1);
|
|
164
|
-
if (arch == null)
|
|
165
|
-
arch = determine_arch();
|
|
166
|
-
|
|
167
|
-
app_dir = __dirname.replace(/\\/g, '/');
|
|
168
|
-
if (project_dir == null)
|
|
169
|
-
project_dir = process.cwd();
|
|
170
|
-
project_dir = project_dir.replace(/\\/g, '/');
|
|
171
|
-
package_dir = find_parent_directory(project_dir, 'package.json');
|
|
172
|
-
cache_dir = get_cache_directory();
|
|
173
|
-
build_dir = project_dir + '/build';
|
|
174
|
-
work_dir = build_dir + `/v${runtime_version}_${arch}`;
|
|
175
|
-
|
|
176
129
|
try {
|
|
177
|
-
|
|
130
|
+
let builder = new Builder(config);
|
|
131
|
+
await builder[command]();
|
|
178
132
|
} catch (err) {
|
|
179
133
|
console.error(err);
|
|
180
134
|
process.exit(1);
|
|
@@ -194,14 +148,13 @@ Options:
|
|
|
194
148
|
(default: current working directory)
|
|
195
149
|
|
|
196
150
|
-B, --config <CONFIG> Change build type: RelWithDebInfo, Debug, Release
|
|
197
|
-
(default: ${
|
|
151
|
+
(default: ${DEFAULT_MODE})
|
|
198
152
|
-D, --debug Shortcut for --config Debug
|
|
199
153
|
|
|
200
|
-
--prebuild
|
|
201
|
-
--require <PATH> Require specified module, drop prebuild if it fails
|
|
154
|
+
--prebuild Use prebuilt binari if available
|
|
202
155
|
|
|
203
156
|
-a, --arch <ARCH> Change architecture and ABI
|
|
204
|
-
(default: ${determine_arch()})
|
|
157
|
+
(default: ${cnoke.determine_arch()})
|
|
205
158
|
-v, --runtime-version <VERSION> Change node version
|
|
206
159
|
(default: ${process.version})
|
|
207
160
|
-t, --toolset <TOOLSET> Change default CMake toolset
|
|
@@ -219,750 +172,3 @@ The ARCH value is similar to process.arch, with the following differences:
|
|
|
219
172
|
|
|
220
173
|
console.log(help);
|
|
221
174
|
}
|
|
222
|
-
|
|
223
|
-
// Commands
|
|
224
|
-
|
|
225
|
-
async function configure(retry = true) {
|
|
226
|
-
let args = [project_dir];
|
|
227
|
-
|
|
228
|
-
check_cmake();
|
|
229
|
-
check_compatibility();
|
|
230
|
-
|
|
231
|
-
console.log(`>> Node: ${runtime_version}`);
|
|
232
|
-
console.log(`>> Target: ${process.platform}_${arch}`);
|
|
233
|
-
|
|
234
|
-
// Prepare build directory
|
|
235
|
-
fs.mkdirSync(cache_dir, { recursive: true, mode: 0o755 });
|
|
236
|
-
fs.mkdirSync(build_dir, { recursive: true, mode: 0o755 });
|
|
237
|
-
fs.mkdirSync(work_dir, { recursive: true, mode: 0o755 });
|
|
238
|
-
|
|
239
|
-
retry &= fs.existsSync(work_dir + '/CMakeCache.txt');
|
|
240
|
-
|
|
241
|
-
// Download Node headers
|
|
242
|
-
{
|
|
243
|
-
let basename = `node-v${runtime_version}-headers.tar.gz`;
|
|
244
|
-
let urls = [
|
|
245
|
-
`https://nodejs.org/dist/v${runtime_version}/${basename}`,
|
|
246
|
-
`https://unofficial-builds.nodejs.org/download/release/v${runtime_version}/${basename}`
|
|
247
|
-
];
|
|
248
|
-
let destname = `${cache_dir}/${basename}`;
|
|
249
|
-
|
|
250
|
-
if (!fs.existsSync(destname))
|
|
251
|
-
await download(urls, destname);
|
|
252
|
-
await extract_targz(destname, work_dir + '/headers', 1);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
// Download Node import library (Windows)
|
|
256
|
-
if (process.platform === 'win32') {
|
|
257
|
-
let dirname;
|
|
258
|
-
switch (arch) {
|
|
259
|
-
case 'ia32': { dirname = 'win-x86'; } break;
|
|
260
|
-
case 'x64': { dirname = 'win-x64'; } break;
|
|
261
|
-
case 'arm64': { dirname = 'win-arm64'; } break;
|
|
262
|
-
|
|
263
|
-
default: {
|
|
264
|
-
throw new Error(`Unsupported architecture '${arch}' for Node on Windows`);
|
|
265
|
-
} break;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
let destname = `${cache_dir}/node_v${runtime_version}_${arch}.lib`;
|
|
269
|
-
|
|
270
|
-
if (!fs.existsSync(destname)) {
|
|
271
|
-
let urls = [
|
|
272
|
-
`https://nodejs.org/dist/v${runtime_version}/${dirname}/node.lib`,
|
|
273
|
-
`https://unofficial-builds.nodejs.org/download/release/v${runtime_version}/${dirname}/node.lib`
|
|
274
|
-
];
|
|
275
|
-
await download(urls, destname);
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
fs.copyFileSync(destname, work_dir + '/node.lib');
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
args.push(`-DCMAKE_MODULE_PATH=${app_dir}/assets`);
|
|
282
|
-
|
|
283
|
-
args.push(`-DNODE_JS_INCLUDE_DIRS=${work_dir}/headers/include/node`);
|
|
284
|
-
|
|
285
|
-
// Set platform flags
|
|
286
|
-
switch (process.platform) {
|
|
287
|
-
case 'win32': {
|
|
288
|
-
fs.copyFileSync(`${app_dir}/assets/win_delay_hook.c`, work_dir + '/win_delay_hook.c');
|
|
289
|
-
|
|
290
|
-
args.push(`-DNODE_JS_SOURCES=${work_dir}/win_delay_hook.c`);
|
|
291
|
-
args.push(`-DNODE_JS_LIBRARIES=${work_dir}/node.lib`);
|
|
292
|
-
|
|
293
|
-
switch (arch) {
|
|
294
|
-
case 'ia32': {
|
|
295
|
-
args.push('-DNODE_JS_LINK_FLAGS=/DELAYLOAD:node.exe;/SAFESEH:NO');
|
|
296
|
-
args.push('-A', 'Win32');
|
|
297
|
-
} break;
|
|
298
|
-
case 'arm64': {
|
|
299
|
-
args.push('-DNODE_JS_LINK_FLAGS=/DELAYLOAD:node.exe;/SAFESEH:NO');
|
|
300
|
-
args.push('-A', 'ARM64');
|
|
301
|
-
} break;
|
|
302
|
-
case 'x64': {
|
|
303
|
-
args.push('-DNODE_JS_LINK_FLAGS=/DELAYLOAD:node.exe');
|
|
304
|
-
args.push('-A', 'x64');
|
|
305
|
-
} break;
|
|
306
|
-
}
|
|
307
|
-
} break;
|
|
308
|
-
|
|
309
|
-
case 'darwin': {
|
|
310
|
-
args.push('-DNODE_JS_LINK_FLAGS=-undefined;dynamic_lookup');
|
|
311
|
-
|
|
312
|
-
switch (arch) {
|
|
313
|
-
case 'arm64': { args.push('-DCMAKE_OSX_ARCHITECTURES=arm64'); } break;
|
|
314
|
-
case 'x64': { args.push('-DCMAKE_OSX_ARCHITECTURES=x86_64'); } break;
|
|
315
|
-
}
|
|
316
|
-
} break;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
if (process.platform != 'win32') {
|
|
320
|
-
// Prefer Ninja if available
|
|
321
|
-
if (spawnSync('ninja', ['--version']).status === 0)
|
|
322
|
-
args.push('-G', 'Ninja');
|
|
323
|
-
|
|
324
|
-
// Use CCache if available
|
|
325
|
-
if (spawnSync('ccache', ['--version']).status === 0) {
|
|
326
|
-
args.push('-DCMAKE_C_COMPILER_LAUNCHER=ccache');
|
|
327
|
-
args.push('-DCMAKE_CXX_COMPILER_LAUNCHER=ccache');
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
if (prefer_clang) {
|
|
332
|
-
if (process.platform == 'win32') {
|
|
333
|
-
args.push('-T', 'ClangCL');
|
|
334
|
-
} else {
|
|
335
|
-
args.push('-DCMAKE_C_COMPILER=clang');
|
|
336
|
-
args.push('-DCMAKE_CXX_COMPILER=clang++');
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
if (toolset != null)
|
|
340
|
-
args.push('-T', toolset);
|
|
341
|
-
|
|
342
|
-
args.push(`-DCMAKE_BUILD_TYPE=${mode}`);
|
|
343
|
-
for (let type of ['ARCHIVE', 'RUNTIME', 'LIBRARY']) {
|
|
344
|
-
for (let suffix of ['', '_DEBUG', '_RELEASE', '_RELWITHDEBINFO'])
|
|
345
|
-
args.push(`-DCMAKE_${type}_OUTPUT_DIRECTORY${suffix}=${build_dir}`);
|
|
346
|
-
}
|
|
347
|
-
args.push('--no-warn-unused-cli');
|
|
348
|
-
|
|
349
|
-
console.log('>> Running configuration');
|
|
350
|
-
|
|
351
|
-
let proc = spawnSync(cmake_bin, args, { cwd: work_dir, stdio: 'inherit' });
|
|
352
|
-
if (proc.status !== 0) {
|
|
353
|
-
unlink_recursive(work_dir);
|
|
354
|
-
if (retry)
|
|
355
|
-
return configure(false);
|
|
356
|
-
|
|
357
|
-
throw new Error('Failed to run configure step');
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
async function build() {
|
|
362
|
-
check_compatibility();
|
|
363
|
-
|
|
364
|
-
if (prebuild) {
|
|
365
|
-
let pkg = read_package_json();
|
|
366
|
-
|
|
367
|
-
if (prebuild_url == null) {
|
|
368
|
-
if (pkg.cnoke.prebuild == null)
|
|
369
|
-
throw new Error('Missing prebuild URL');
|
|
370
|
-
|
|
371
|
-
prebuild_url = pkg.cnoke.prebuild;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
fs.mkdirSync(build_dir, { recursive: true, mode: 0o755 });
|
|
375
|
-
|
|
376
|
-
let url = prebuild_url.replace(/{{([a-zA-Z_][a-zA-Z_0-9]*)}}/g, (match, p1) => {
|
|
377
|
-
switch (p1) {
|
|
378
|
-
case 'version': {
|
|
379
|
-
let pkg = read_package_json();
|
|
380
|
-
return pkg.version || '';
|
|
381
|
-
} break;
|
|
382
|
-
case 'platform': return process.platform;
|
|
383
|
-
case 'arch': return arch;
|
|
384
|
-
|
|
385
|
-
default: return match;
|
|
386
|
-
}
|
|
387
|
-
});
|
|
388
|
-
let basename = path.basename(url);
|
|
389
|
-
|
|
390
|
-
try {
|
|
391
|
-
let archive_filename = null;
|
|
392
|
-
|
|
393
|
-
if (url.startsWith('file:/')) {
|
|
394
|
-
if (url.startsWith('file://localhost/')) {
|
|
395
|
-
url = url.substr(16);
|
|
396
|
-
} else {
|
|
397
|
-
let offset = 6;
|
|
398
|
-
while (offset < 9 && url[offset] == '/')
|
|
399
|
-
offset++;
|
|
400
|
-
url = url.substr(offset - 1);
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
if (process.platform == 'win32' && url.match(/^\/[a-zA-Z]+:[\\\/]/))
|
|
404
|
-
url = url.substr(1);
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
if (url.match(/^[a-z]+:\/\//)) {
|
|
408
|
-
archive_filename = build_dir + '/' + basename;
|
|
409
|
-
await download(url, archive_filename);
|
|
410
|
-
} else {
|
|
411
|
-
if (path_is_absolute(url)) {
|
|
412
|
-
archive_filename = url;
|
|
413
|
-
} else if (package_dir != null) {
|
|
414
|
-
archive_filename = package_dir + '/' + url;
|
|
415
|
-
} else {
|
|
416
|
-
archive_filename = project_dir + '/' + url;
|
|
417
|
-
}
|
|
418
|
-
if (!fs.existsSync(archive_filename))
|
|
419
|
-
throw new Error('Cannot find local prebuilt archive');
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
console.log('>> Extracting prebuilt binaries...');
|
|
423
|
-
await extract_targz(archive_filename, build_dir, 1);
|
|
424
|
-
|
|
425
|
-
// Make sure the binary works
|
|
426
|
-
if (prebuild_req == null)
|
|
427
|
-
prebuild_req = pkg.cnoke.require;
|
|
428
|
-
if (prebuild_req != null) {
|
|
429
|
-
let proc = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', prebuild_req]);
|
|
430
|
-
if (proc.status === 0)
|
|
431
|
-
return;
|
|
432
|
-
} else {
|
|
433
|
-
return;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
// Clean it up if it does not, before source build. Only delete files, it is safer and it is enough!
|
|
437
|
-
let entries = fs.readdirSync(build_dir, { withFileTypes: true });
|
|
438
|
-
for (let entry of entries) {
|
|
439
|
-
if (!entry.isDirectory()) {
|
|
440
|
-
let filename = path.join(build_dir, entry.name);
|
|
441
|
-
fs.unlinkSync(filename);
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
console.error('Failed to load prebuilt binary, rebuilding from source');
|
|
446
|
-
} catch (err) {
|
|
447
|
-
console.error('Failed to find prebuilt binary for your platform, building manually');
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
check_cmake();
|
|
452
|
-
|
|
453
|
-
if (!fs.existsSync(work_dir + '/CMakeCache.txt'))
|
|
454
|
-
await configure();
|
|
455
|
-
|
|
456
|
-
// In case Make gets used
|
|
457
|
-
if (process.env.MAKEFLAGS == null)
|
|
458
|
-
process.env.MAKEFLAGS = '-j' + os.cpus().length;
|
|
459
|
-
|
|
460
|
-
let args = [
|
|
461
|
-
'--build', work_dir,
|
|
462
|
-
'--config', mode
|
|
463
|
-
];
|
|
464
|
-
|
|
465
|
-
if (verbose)
|
|
466
|
-
args.push('--verbose');
|
|
467
|
-
for (let target of targets)
|
|
468
|
-
args.push('--target', target);
|
|
469
|
-
|
|
470
|
-
console.log('>> Running build');
|
|
471
|
-
|
|
472
|
-
let proc = spawnSync(cmake_bin, args, { stdio: 'inherit' });
|
|
473
|
-
if (proc.status !== 0)
|
|
474
|
-
throw new Error('Failed to run build step');
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
async function clean() {
|
|
478
|
-
unlink_recursive(build_dir);
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
// Utility
|
|
482
|
-
|
|
483
|
-
function get_cache_directory() {
|
|
484
|
-
if (process.platform == 'win32') {
|
|
485
|
-
let cache_dir = process.env['APPDATA'];
|
|
486
|
-
if (cache_dir == null)
|
|
487
|
-
throw new Error('Missing APPDATA environment variable');
|
|
488
|
-
|
|
489
|
-
cache_dir = path.join(cache_dir, 'cnoke');
|
|
490
|
-
return cache_dir;
|
|
491
|
-
} else {
|
|
492
|
-
let cache_dir = process.env['XDG_CACHE_HOME'];
|
|
493
|
-
|
|
494
|
-
if (cache_dir == null) {
|
|
495
|
-
let home = process.env['HOME'];
|
|
496
|
-
if (home == null)
|
|
497
|
-
throw new Error('Missing HOME environment variable');
|
|
498
|
-
|
|
499
|
-
cache_dir = path.join(home, '.cache');
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
cache_dir = path.join(cache_dir, 'cnoke');
|
|
503
|
-
return cache_dir;
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
function check_cmake() {
|
|
508
|
-
if (cmake_bin != null)
|
|
509
|
-
return;
|
|
510
|
-
|
|
511
|
-
// Check for CMakeLists.txt
|
|
512
|
-
if (!fs.existsSync(project_dir + '/CMakeLists.txt'))
|
|
513
|
-
throw new Error('This directory does not appear to have a CMakeLists.txt file');
|
|
514
|
-
|
|
515
|
-
// Check for CMake
|
|
516
|
-
{
|
|
517
|
-
let proc = spawnSync('cmake', ['--version']);
|
|
518
|
-
|
|
519
|
-
if (proc.status === 0) {
|
|
520
|
-
cmake_bin = 'cmake';
|
|
521
|
-
} else {
|
|
522
|
-
if (process.platform == 'win32') {
|
|
523
|
-
// I really don't want to depend on anything in CNoke, and Node.js does not provide
|
|
524
|
-
// anything to read from the registry. This is okay, REG.exe exists since Windows XP.
|
|
525
|
-
let proc = spawnSync('reg', ['query', 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Kitware\\CMake', '/v', 'InstallDir']);
|
|
526
|
-
|
|
527
|
-
if (proc.status === 0) {
|
|
528
|
-
let matches = proc.stdout.toString('utf-8').match(/InstallDir[ \t]+REG_[A-Z_]+[ \t]+(.*)+/);
|
|
529
|
-
|
|
530
|
-
if (matches != null) {
|
|
531
|
-
let bin = path.join(matches[1].trim(), 'bin\\cmake.exe');
|
|
532
|
-
|
|
533
|
-
if (fs.existsSync(bin))
|
|
534
|
-
cmake_bin = bin;
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
if (cmake_bin == null)
|
|
540
|
-
throw new Error('CMake does not seem to be available');
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
console.log(`>> Using CMake binary: ${cmake_bin}`);
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
function check_compatibility() {
|
|
548
|
-
let pkg = read_package_json();
|
|
549
|
-
|
|
550
|
-
if (pkg.cnoke.node != null && cmp_version(runtime_version, pkg.cnoke.node) < 0)
|
|
551
|
-
throw new Error(`Project ${pkg.name} requires Node.js >= ${pkg.cnoke.node}`);
|
|
552
|
-
|
|
553
|
-
if (pkg.cnoke.napi != null) {
|
|
554
|
-
let major = parseInt(runtime_version, 10);
|
|
555
|
-
let required = get_napi_version(pkg.cnoke.napi, major);
|
|
556
|
-
|
|
557
|
-
if (required == null)
|
|
558
|
-
throw new Error(`Project ${pkg.name} does not support the Node ${major}.x branch (old or missing N-API)`);
|
|
559
|
-
if (cmp_version(runtime_version, required) < 0)
|
|
560
|
-
throw new Error(`Project ${pkg.name} requires Node >= ${required} in the Node ${major}.x branch (with N-API >= ${pkg.engines.napi})`);
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
function read_package_json() {
|
|
565
|
-
let pkg = {};
|
|
566
|
-
|
|
567
|
-
if (package_dir != null) {
|
|
568
|
-
try {
|
|
569
|
-
let json = fs.readFileSync(package_dir + '/package.json', { encoding: 'utf-8' });
|
|
570
|
-
pkg = JSON.parse(json);
|
|
571
|
-
} catch (err) {
|
|
572
|
-
if (err.code != 'ENOENT')
|
|
573
|
-
throw err;
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
if (pkg.cnoke == null)
|
|
578
|
-
pkg.cnoke = {};
|
|
579
|
-
|
|
580
|
-
return pkg;
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
function unlink_recursive(path) {
|
|
584
|
-
try {
|
|
585
|
-
if (fs.rmSync != null) {
|
|
586
|
-
fs.rmSync(path, { recursive: true, maxRetries: process.platform == 'win32' ? 3 : 0 });
|
|
587
|
-
} else {
|
|
588
|
-
fs.rmdirSync(path, { recursive: true, maxRetries: process.platform == 'win32' ? 3 : 0 });
|
|
589
|
-
}
|
|
590
|
-
} catch (err) {
|
|
591
|
-
if (err.code !== 'ENOENT')
|
|
592
|
-
throw err;
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
async function download(url, dest) {
|
|
597
|
-
if (Array.isArray(url)) {
|
|
598
|
-
let urls = url;
|
|
599
|
-
|
|
600
|
-
for (let url of urls) {
|
|
601
|
-
try {
|
|
602
|
-
await download(url, dest);
|
|
603
|
-
return;
|
|
604
|
-
} catch (err) {
|
|
605
|
-
if (err.code != 404)
|
|
606
|
-
throw err;
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
throw new Error('All URLs returned error 404');
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
console.log('>> Downloading ' + url);
|
|
614
|
-
|
|
615
|
-
let [tmp_name, file] = open_temporary_stream(dest);
|
|
616
|
-
|
|
617
|
-
try {
|
|
618
|
-
await new Promise((resolve, reject) => {
|
|
619
|
-
let request = http.get(url, response => {
|
|
620
|
-
if (response.statusCode != 200) {
|
|
621
|
-
let err = new Error(`Download failed: ${response.statusMessage} [${response.statusCode}]`);
|
|
622
|
-
err.code = response.statusCode;
|
|
623
|
-
|
|
624
|
-
reject(err);
|
|
625
|
-
|
|
626
|
-
return;
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
response.pipe(file);
|
|
630
|
-
|
|
631
|
-
file.on('finish', () => file.close(() => {
|
|
632
|
-
try {
|
|
633
|
-
fs.renameSync(file.path, dest);
|
|
634
|
-
} catch (err) {
|
|
635
|
-
if (err.code != 'EBUSY')
|
|
636
|
-
reject(err);
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
resolve();
|
|
640
|
-
}));
|
|
641
|
-
});
|
|
642
|
-
|
|
643
|
-
request.on('error', reject);
|
|
644
|
-
file.on('error', reject);
|
|
645
|
-
});
|
|
646
|
-
} catch (err) {
|
|
647
|
-
file.close();
|
|
648
|
-
|
|
649
|
-
try {
|
|
650
|
-
fs.unlinkSync(tmp_name);
|
|
651
|
-
} catch (err) {
|
|
652
|
-
if (err.code != 'ENOENT')
|
|
653
|
-
throw err;
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
throw err;
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
function open_temporary_stream(prefix) {
|
|
661
|
-
let buf = Buffer.allocUnsafe(4);
|
|
662
|
-
|
|
663
|
-
for (;;) {
|
|
664
|
-
try {
|
|
665
|
-
crypto.randomFillSync(buf);
|
|
666
|
-
|
|
667
|
-
let suffix = buf.toString('hex').padStart(8, '0');
|
|
668
|
-
let filename = `${prefix}.${suffix}`;
|
|
669
|
-
|
|
670
|
-
let file = fs.createWriteStream(filename, { flags: 'wx', mode: 0o644 });
|
|
671
|
-
return [filename, file];
|
|
672
|
-
} catch (err) {
|
|
673
|
-
if (err.code != 'EEXIST')
|
|
674
|
-
throw err;
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
function read_file_header(filename, read) {
|
|
680
|
-
let fd = null;
|
|
681
|
-
|
|
682
|
-
try {
|
|
683
|
-
let fd = fs.openSync(filename);
|
|
684
|
-
|
|
685
|
-
let buf = Buffer.allocUnsafe(read);
|
|
686
|
-
let len = fs.readSync(fd, buf);
|
|
687
|
-
|
|
688
|
-
return buf.subarray(0, len);
|
|
689
|
-
} finally {
|
|
690
|
-
if (fd != null)
|
|
691
|
-
fs.closeSync(fd);
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
function extract_targz(filename, dest_dir, strip = 0) {
|
|
696
|
-
let reader = fs.createReadStream(filename).pipe(zlib.createGunzip());
|
|
697
|
-
|
|
698
|
-
return new Promise((resolve, reject) => {
|
|
699
|
-
let header = null;
|
|
700
|
-
let extended = {};
|
|
701
|
-
|
|
702
|
-
reader.on('readable', () => {
|
|
703
|
-
try {
|
|
704
|
-
for (;;) {
|
|
705
|
-
if (header == null) {
|
|
706
|
-
let buf = reader.read(512);
|
|
707
|
-
if (buf == null)
|
|
708
|
-
break;
|
|
709
|
-
|
|
710
|
-
// Two zeroed 512-byte blocks end the stream
|
|
711
|
-
if (!buf[0])
|
|
712
|
-
continue;
|
|
713
|
-
|
|
714
|
-
header = {
|
|
715
|
-
filename: buf.toString('utf-8', 0, 100).replace(/\0/g, ''),
|
|
716
|
-
mode: parseInt(buf.toString('ascii', 100, 109), 8),
|
|
717
|
-
size: parseInt(buf.toString('ascii', 124, 137), 8),
|
|
718
|
-
type: String.fromCharCode(buf[156])
|
|
719
|
-
};
|
|
720
|
-
|
|
721
|
-
// UStar filename prefix
|
|
722
|
-
/*if (buf.toString('ascii', 257, 263) == 'ustar\0') {
|
|
723
|
-
let prefix = buf.toString('utf-8', 345, 500).replace(/\0/g, '');
|
|
724
|
-
console.log(prefix);
|
|
725
|
-
header.filename = prefix ? (prefix + '/' + header.filename) : header.filename;
|
|
726
|
-
}*/
|
|
727
|
-
|
|
728
|
-
Object.assign(header, extended);
|
|
729
|
-
extended = {};
|
|
730
|
-
|
|
731
|
-
// Safety checks
|
|
732
|
-
header.filename = header.filename.replace(/\\/g, '/');
|
|
733
|
-
if (!header.filename.length)
|
|
734
|
-
throw new Error(`Insecure empty filename inside TAR archive`);
|
|
735
|
-
if (header.filename[0] == '/')
|
|
736
|
-
throw new Error(`Insecure filename starting with / inside TAR archive`);
|
|
737
|
-
if (path_has_dotdot(header.filename))
|
|
738
|
-
throw new Error(`Insecure filename containing '..' inside TAR archive`);
|
|
739
|
-
|
|
740
|
-
for (let i = 0; i < strip; i++)
|
|
741
|
-
header.filename = header.filename.substr(header.filename.indexOf('/') + 1);
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
let aligned = Math.floor((header.size + 511) / 512) * 512;
|
|
745
|
-
let data = header.size ? reader.read(aligned) : null;
|
|
746
|
-
if (data == null) {
|
|
747
|
-
if (header.size)
|
|
748
|
-
break;
|
|
749
|
-
data = Buffer.alloc(0);
|
|
750
|
-
}
|
|
751
|
-
data = data.subarray(0, header.size);
|
|
752
|
-
|
|
753
|
-
if (header.type == '0' || header.type == '7') {
|
|
754
|
-
let filename = dest_dir + '/' + header.filename;
|
|
755
|
-
let dirname = path.dirname(filename);
|
|
756
|
-
|
|
757
|
-
fs.mkdirSync(dirname, { recursive: true, mode: 0o755 });
|
|
758
|
-
fs.writeFileSync(filename, data, { mode: header.mode });
|
|
759
|
-
} else if (header.type == '5') {
|
|
760
|
-
let filename = dest_dir + '/' + header.filename;
|
|
761
|
-
fs.mkdirSync(filename, { recursive: true, mode: header.mode });
|
|
762
|
-
} else if (header.type == 'L') { // GNU tar
|
|
763
|
-
extended.filename = data.toString('utf-8').replace(/\0/g, '');
|
|
764
|
-
} else if (header.type == 'x') { // PAX entry
|
|
765
|
-
let str = data.toString('utf-8');
|
|
766
|
-
|
|
767
|
-
try {
|
|
768
|
-
while (str.length) {
|
|
769
|
-
let matches = str.match(/^([0-9]+) ([a-zA-Z0-9\._]+)=(.*)\n/);
|
|
770
|
-
|
|
771
|
-
let skip = parseInt(matches[1], 10);
|
|
772
|
-
let key = matches[2];
|
|
773
|
-
let value = matches[3];
|
|
774
|
-
|
|
775
|
-
switch (key) {
|
|
776
|
-
case 'path': { extended.filename = value; } break;
|
|
777
|
-
case 'size': { extended.size = parseInt(value, 10); } break;
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
str = str.substr(skip).trimStart();
|
|
781
|
-
}
|
|
782
|
-
} catch (err) {
|
|
783
|
-
throw new Error('Malformed PAX entry');
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
header = null;
|
|
788
|
-
}
|
|
789
|
-
} catch (err) {
|
|
790
|
-
reject(err);
|
|
791
|
-
}
|
|
792
|
-
});
|
|
793
|
-
|
|
794
|
-
reader.on('error', reject);
|
|
795
|
-
reader.on('end', resolve);
|
|
796
|
-
});
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
function path_is_absolute(path) {
|
|
800
|
-
if (process.platform == 'win32' && path.match(/^[a-zA-Z]:/))
|
|
801
|
-
path = path.substr(2);
|
|
802
|
-
return is_path_separator(path[0]);
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
function path_has_dotdot(path) {
|
|
806
|
-
let start = 0;
|
|
807
|
-
|
|
808
|
-
for (;;) {
|
|
809
|
-
let offset = path.indexOf('..', start);
|
|
810
|
-
if (offset < 0)
|
|
811
|
-
break;
|
|
812
|
-
start = offset + 2;
|
|
813
|
-
|
|
814
|
-
if (offset && !is_path_separator(path[offset - 1]))
|
|
815
|
-
continue;
|
|
816
|
-
if (offset + 2 < path.length && !is_path_separator(path[offset + 2]))
|
|
817
|
-
continue;
|
|
818
|
-
|
|
819
|
-
return true;
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
return false;
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
function is_path_separator(c) {
|
|
826
|
-
if (c == '/')
|
|
827
|
-
return true;
|
|
828
|
-
if (process.platform == 'win32' && c == '\\')
|
|
829
|
-
return true;
|
|
830
|
-
|
|
831
|
-
return false;
|
|
832
|
-
}
|
|
833
|
-
|
|
834
|
-
function find_parent_directory(dirname, basename)
|
|
835
|
-
{
|
|
836
|
-
if (process.platform == 'win32')
|
|
837
|
-
dirname = dirname.replace(/\\/g, '/');
|
|
838
|
-
|
|
839
|
-
do {
|
|
840
|
-
if (fs.existsSync(dirname + '/' + basename))
|
|
841
|
-
return dirname;
|
|
842
|
-
|
|
843
|
-
dirname = path.dirname(dirname);
|
|
844
|
-
} while (!dirname.endsWith('/'));
|
|
845
|
-
|
|
846
|
-
return null;
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
function determine_arch() {
|
|
850
|
-
let arch = process.arch;
|
|
851
|
-
|
|
852
|
-
if (arch == 'riscv32' || arch == 'riscv64') {
|
|
853
|
-
let buf = read_file_header(process.execPath, 512);
|
|
854
|
-
let header = decode_elf_header(buf);
|
|
855
|
-
let float_abi = (header.e_flags & 0x6) >> 1;
|
|
856
|
-
|
|
857
|
-
switch (float_abi) {
|
|
858
|
-
case 0: { arch += 'sf'; } break;
|
|
859
|
-
case 1: { arch += 'hf32'; } break;
|
|
860
|
-
case 2: { arch += 'hf64'; } break;
|
|
861
|
-
case 3: { arch += 'hf128'; } break;
|
|
862
|
-
}
|
|
863
|
-
} else if (arch == 'arm') {
|
|
864
|
-
arch = 'arm32';
|
|
865
|
-
|
|
866
|
-
let buf = read_file_header(process.execPath, 512);
|
|
867
|
-
let header = decode_elf_header(buf);
|
|
868
|
-
|
|
869
|
-
if (header.e_flags & 0x400) {
|
|
870
|
-
arch += 'hf';
|
|
871
|
-
} else if (header.e_flags & 0x200) {
|
|
872
|
-
arch += 'sf';
|
|
873
|
-
} else {
|
|
874
|
-
throw new Error('Unknown ARM floating-point ABI');
|
|
875
|
-
}
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
return arch;
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
function decode_elf_header(buf) {
|
|
882
|
-
let header = {};
|
|
883
|
-
|
|
884
|
-
if (buf.length < 16)
|
|
885
|
-
throw new Error('Truncated header');
|
|
886
|
-
if (buf[0] != 0x7F || buf[1] != 69 || buf[2] != 76 || buf[3] != 70)
|
|
887
|
-
throw new Error('Invalid magic number');
|
|
888
|
-
if (buf[6] != 1)
|
|
889
|
-
throw new Error('Invalid ELF version');
|
|
890
|
-
if (buf[5] != 1)
|
|
891
|
-
throw new Error('Big-endian architectures are not supported');
|
|
892
|
-
|
|
893
|
-
let machine = buf.readUInt16LE(18);
|
|
894
|
-
|
|
895
|
-
switch (machine) {
|
|
896
|
-
case 3: { header.e_machine = 'ia32'; } break;
|
|
897
|
-
case 40: { header.e_machine = 'arm'; } break;
|
|
898
|
-
case 62: { header.e_machine = 'amd64'; } break;
|
|
899
|
-
case 183: { header.e_machine = 'arm64'; } break;
|
|
900
|
-
case 243: {
|
|
901
|
-
switch (buf[4]) {
|
|
902
|
-
case 1: { header.e_machine = 'riscv32'; } break;
|
|
903
|
-
case 2: { header.e_machine = 'riscv64'; } break;
|
|
904
|
-
}
|
|
905
|
-
} break;
|
|
906
|
-
default: throw new Error('Unknown ELF machine type');
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
switch (buf[4]) {
|
|
910
|
-
case 1: { // 32 bit
|
|
911
|
-
buf = buf.subarray(0, 68);
|
|
912
|
-
if (buf.length < 68)
|
|
913
|
-
throw new Error('Truncated ELF header');
|
|
914
|
-
|
|
915
|
-
header.ei_class = 32;
|
|
916
|
-
header.e_flags = buf.readUInt32LE(36);
|
|
917
|
-
} break;
|
|
918
|
-
case 2: { // 64 bit
|
|
919
|
-
buf = buf.subarray(0, 120);
|
|
920
|
-
if (buf.length < 120)
|
|
921
|
-
throw new Error('Truncated ELF header');
|
|
922
|
-
|
|
923
|
-
header.ei_class = 64;
|
|
924
|
-
header.e_flags = buf.readUInt32LE(48);
|
|
925
|
-
} break;
|
|
926
|
-
default: throw new Error('Invalid ELF class');
|
|
927
|
-
}
|
|
928
|
-
|
|
929
|
-
return header;
|
|
930
|
-
}
|
|
931
|
-
|
|
932
|
-
// Versioning
|
|
933
|
-
|
|
934
|
-
function get_napi_version(napi, major) {
|
|
935
|
-
if (napi > 8)
|
|
936
|
-
return null;
|
|
937
|
-
|
|
938
|
-
// https://nodejs.org/api/n-api.html#node-api-version-matrix
|
|
939
|
-
const support = {
|
|
940
|
-
6: ['6.14.2', '6.14.2', '6.14.2'],
|
|
941
|
-
8: ['8.6.0', '8.10.0', '8.11.2'],
|
|
942
|
-
9: ['9.0.0', '9.3.0', '9.11.0'],
|
|
943
|
-
10: ['10.0.0', '10.0.0', '10.0.0', '10.16.0', '10.17.0', '10.20.0', '10.23.0'],
|
|
944
|
-
11: ['11.0.0', '11.0.0', '11.0.0', '11.8.0'],
|
|
945
|
-
12: ['12.0.0', '12.0.0', '12.0.0', '12.0.0', '12.11.0', '12.17.0', '12.19.0', '12.22.0'],
|
|
946
|
-
13: ['13.0.0', '13.0.0', '13.0.0', '13.0.0', '13.0.0'],
|
|
947
|
-
14: ['14.0.0', '14.0.0', '14.0.0', '14.0.0', '14.0.0', '14.0.0', '14.12.0', '14.17.0'],
|
|
948
|
-
15: ['15.0.0', '15.0.0', '15.0.0', '15.0.0', '15.0.0', '15.0.0', '15.0.0', '15.12.0']
|
|
949
|
-
};
|
|
950
|
-
const max = Math.max(...Object.keys(support).map(k => parseInt(k, 10)));
|
|
951
|
-
|
|
952
|
-
if (major > max)
|
|
953
|
-
return major + '.0.0';
|
|
954
|
-
if (support[major] == null)
|
|
955
|
-
return null;
|
|
956
|
-
|
|
957
|
-
let required = support[major][napi - 1] || null;
|
|
958
|
-
return required;
|
|
959
|
-
}
|
|
960
|
-
|
|
961
|
-
// Ignores prerelease suffixes
|
|
962
|
-
function cmp_version(ver1, ver2) {
|
|
963
|
-
ver1 = String(ver1).replace(/-.*$/, '').split('.').reduce((acc, v, idx) => acc + parseInt(v, 10) * Math.pow(10, 2 * (5 - idx)), 0);
|
|
964
|
-
ver2 = String(ver2).replace(/-.*$/, '').split('.').reduce((acc, v, idx) => acc + parseInt(v, 10) * Math.pow(10, 2 * (5 - idx)), 0);
|
|
965
|
-
|
|
966
|
-
let cmp = Math.min(Math.max(ver1 - ver2, -1), 1);
|
|
967
|
-
return cmp;
|
|
968
|
-
}
|