crossbind 2.0.0-beta.62 → 2.0.0-beta.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +6 -1
- package/src/actions/buildDependencies.js +15 -2
- package/src/actions/buildExternal.js +9 -1
- package/src/actions/buildLib.js +25 -8
- package/src/actions/buildNativeCommand.js +84 -0
- package/src/actions/buildNode.js +48 -7
- package/src/actions/buildTypes.js +8 -2
- package/src/actions/buildWasiCommand.js +0 -4
- package/src/actions/buildWasm.js +49 -29
- package/src/actions/cloudCommands.js +133 -0
- package/src/actions/createImportedBridges.js +64 -0
- package/src/actions/createInterface.js +247 -68
- package/src/actions/createLib.js +57 -41
- package/src/actions/getData.js +4 -1
- package/src/actions/getLinkInputs.js +12 -5
- package/src/actions/isSourceNewer.js +2 -0
- package/src/actions/licenses.js +143 -19
- package/src/actions/prepareConanDependencies.js +51 -0
- package/src/actions/publishBinary.js +32 -0
- package/src/actions/run.js +63 -66
- package/src/actions/runnerCommands.js +421 -0
- package/src/actions/writeRuntimeEntry.js +69 -0
- package/src/assets/cmake/command/CMakeLists.txt +21 -0
- package/src/assets/cmake/command/command.cpp +1 -0
- package/src/assets/cmake/dist.cmake +2 -1
- package/src/assets/configure/install.sh +22 -0
- package/src/assets/js-runtime/adapters/path-url.js +6 -3
- package/src/assets/js-runtime/adapters/unboundMessage.js +2 -0
- package/src/assets/js-runtime/adapters/worker-comlink.js +87 -60
- package/src/assets/js-runtime/core.js +11 -0
- package/src/assets/node-import-hooks.mjs +61 -0
- package/src/assets/toolchain-digests.json +19 -19
- package/src/assets/wasi-runtime/stubs.c +29 -0
- package/src/bin.js +257 -50
- package/src/index.js +3 -0
- package/src/integration/bindHeaderImports.js +18 -0
- package/src/integration/getCrossbindScript.js +46 -10
- package/src/integration/getDependFilePath.js +9 -0
- package/src/integration/resolveNativeImport.js +14 -0
- package/src/node/dev.mjs +19 -0
- package/src/runner/blobs.js +135 -0
- package/src/runner/files.js +193 -0
- package/src/runner/server.js +320 -0
- package/src/state/attachConanDependencies.js +56 -0
- package/src/state/index.js +17 -9
- package/src/state/loadConfig.js +33 -24
- package/src/state/refreshBuiltDependencies.js +20 -0
- package/src/state/refreshConanDependencies.js +17 -0
- package/src/utils/androidToolchain.js +4 -0
- package/src/utils/appRustCrates.js +15 -1
- package/src/utils/appSources.js +97 -6
- package/src/utils/archiveFlags.js +12 -0
- package/src/utils/boundHeaders.js +79 -0
- package/src/utils/bridgeExtras.js +486 -0
- package/src/utils/bridgeRuntimeFixes.js +48 -0
- package/src/utils/bundledLicenses.js +26 -0
- package/src/utils/cargoTarget.js +21 -3
- package/src/utils/cloudAccount.js +55 -0
- package/src/utils/conanDependencies.js +66 -0
- package/src/utils/conanImport.js +58 -0
- package/src/utils/conanInstall.js +154 -0
- package/src/utils/conanProfile.js +203 -0
- package/src/utils/conanStage.js +292 -0
- package/src/utils/copyToDistSource.js +13 -0
- package/src/utils/cppDts.js +58 -15
- package/src/utils/darwinToolchain.js +11 -0
- package/src/utils/dirLock.js +137 -28
- package/src/utils/downloadAndExtractFile.js +34 -7
- package/src/utils/embindArgumentGuards.js +41 -2
- package/src/utils/embindCallArguments.js +19 -0
- package/src/utils/embindJspiQueue.js +25 -0
- package/src/utils/execContainer.js +49 -0
- package/src/utils/headerImports.js +16 -5
- package/src/utils/hostPlatform.js +21 -0
- package/src/utils/iosToolchain.js +6 -0
- package/src/utils/isSourceCmakePackage.js +10 -0
- package/src/utils/licenseReport.js +11 -2
- package/src/utils/linuxToolchain.js +24 -0
- package/src/utils/makeTreeWritable.js +12 -0
- package/src/utils/nativeImports.js +23 -0
- package/src/utils/nativeSourceStamp.js +36 -0
- package/src/utils/nodeDevBuild.js +92 -0
- package/src/utils/packageLicense.js +101 -0
- package/src/utils/pthreadMainScript.js +14 -0
- package/src/utils/pullDockerImage.js +3 -1
- package/src/utils/relocatePrebuilt.js +119 -0
- package/src/utils/remoteClient.js +127 -0
- package/src/utils/remoteOutputs.js +39 -0
- package/src/utils/remoteRunner.js +97 -0
- package/src/utils/remoteUpload.js +134 -0
- package/src/utils/replaceFile.js +8 -0
- package/src/utils/runCargo.js +48 -51
- package/src/utils/runConan.js +257 -0
- package/src/utils/runtimeEntries.js +56 -0
- package/src/utils/rustBridgeGen.js +9 -4
- package/src/utils/rustMt.js +4 -0
- package/src/utils/scopedEmbind.js +22 -0
- package/src/utils/selectRunner.js +81 -0
- package/src/utils/sourceFingerprint.js +4 -3
- package/src/utils/swigInterface.js +69 -4
- package/src/utils/systemKeys.js +35 -3
- package/src/utils/targets.js +49 -4
- package/src/utils/toolchainNotices.js +5 -0
- package/src/utils/wasiToolchain.js +14 -1
- package/src/utils/windowsToolchain.js +18 -0
- package/vitest.config.js +11 -0
|
@@ -16,6 +16,29 @@ export function findIgnoredDeclarations(headerFile, configs, headerPath) {
|
|
|
16
16
|
return findHeaderOption('ignoredDeclarations', headerFile, configs, headerPath);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
// SWIG preprocessor lines a package puts right before one of its public headers, in export.swigPreamble: GDAL hides
|
|
20
|
+
// its C SRS API behind `#ifndef SWIG` for its own bindings, and picks VSIStatBufL's typedef by whether VSI_STAT64_T is
|
|
21
|
+
// defined, which a macro defined as itself answers while each platform's compiler still resolves the name.
|
|
22
|
+
export function findSwigPreamble(headerFile, configs, headerPath) {
|
|
23
|
+
return findHeaderOption('swigPreamble', headerFile, configs, headerPath);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Includes SWIG reads inlined into one of a package's headers, in export.swigInlineIncludes. SWIG reads no #include, and
|
|
27
|
+
// libgeotiff fills its key and code enums from .inc files included inside the enum bodies, where the file markers
|
|
28
|
+
// -includeall wraps around an included file do not parse.
|
|
29
|
+
export function findSwigInlineIncludes(headerFile, configs, headerPath) {
|
|
30
|
+
return findHeaderOption('swigInlineIncludes', headerFile, configs, headerPath);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const INCLUDE_LINE = /^[ \t]*#[ \t]*include[ \t]*"([^"]+)"[^\n]*$/gm;
|
|
34
|
+
|
|
35
|
+
export function inlineIncludes(headerText, names, readInclude) {
|
|
36
|
+
const included = new Set([...headerText.matchAll(INCLUDE_LINE)].map(([, name]) => name));
|
|
37
|
+
const missing = names.filter((name) => !included.has(name));
|
|
38
|
+
if (missing.length) throw new Error(`crossbind: swigInlineIncludes lists ${missing.join(', ')}, which the header does not include.`);
|
|
39
|
+
return headerText.replace(INCLUDE_LINE, (line, name) => (names.includes(name) ? readInclude(name) : line));
|
|
40
|
+
}
|
|
41
|
+
|
|
19
42
|
function findHeaderOption(option, headerFile, configs, headerPath) {
|
|
20
43
|
const file = upath.normalize(headerFile);
|
|
21
44
|
let owner = null;
|
|
@@ -40,26 +63,35 @@ export function interfaceIncludes(headerPath, prelude = []) {
|
|
|
40
63
|
|
|
41
64
|
// The prelude and the completing includes reach only the compiled wrapper and swigMacros only SWIG's parse: SWIG still
|
|
42
65
|
// wraps just the imported header. The ignored declarations follow the macros, so the retry without macros keeps them.
|
|
43
|
-
export function buildInterfaceContent({
|
|
66
|
+
export function buildInterfaceContent({
|
|
67
|
+
moduleName, headerPath, prelude = [], completing = [], swigMacros = [], ignored = [], constants = [], preamble = [], functions = ALL_NAMES,
|
|
68
|
+
extras = [],
|
|
69
|
+
}) {
|
|
44
70
|
const includes = [...new Set([...interfaceIncludes(headerPath, prelude), ...completing])]
|
|
45
71
|
.map((header) => `#include "${header}"`)
|
|
46
72
|
.join('\n');
|
|
47
73
|
const macros = swigMacros.length ? `${swigMacros.join('\n')}\n\n` : '';
|
|
48
74
|
const ignores = ignored.length ? `${ignored.map((name) => `%ignore ${name};`).join('\n')}\n\n` : '';
|
|
75
|
+
// The marker keeps a preamble that starts with #define apart from the macro block the retry drops.
|
|
76
|
+
const preambleBlock = preamble.length ? `// package preamble\n${preamble.join('\n')}\n\n` : '';
|
|
77
|
+
const extraBlock = extras.length ? `${extras.join('\n')}\n\n` : '';
|
|
78
|
+
// Named constants are asked for ahead of the macros, which may define one. Every constant is asked for after them:
|
|
79
|
+
// SWIG binds an interface's own #define lines, and the prelude only carries other headers' values for the parse.
|
|
80
|
+
const everyConstant = constants === ALL_NAMES;
|
|
49
81
|
const module = moduleName.replace(/\W/g, '_');
|
|
50
82
|
return `#ifndef _${module}_I
|
|
51
83
|
#define _${module}_I
|
|
52
84
|
|
|
53
85
|
%module ${module}
|
|
54
86
|
|
|
55
|
-
%{
|
|
87
|
+
${extraBlock}%{
|
|
56
88
|
${includes}
|
|
57
89
|
%}
|
|
58
90
|
|
|
59
|
-
${constantRequests(constants)}%feature("shared_ptr");
|
|
91
|
+
${everyConstant ? '' : constantRequests(constants)}%feature("shared_ptr");
|
|
60
92
|
%feature("polymorphic_shared_ptr");
|
|
61
93
|
|
|
62
|
-
${macros}${ignores}%include "${headerPath}"
|
|
94
|
+
${macros}${functionRequests(functions)}${ignores}${preambleBlock}${everyConstant ? constantRequests(constants) : ''}%include "${headerPath}"
|
|
63
95
|
|
|
64
96
|
#endif
|
|
65
97
|
`;
|
|
@@ -71,6 +103,19 @@ function constantRequests(constants) {
|
|
|
71
103
|
return constants.length ? `${constants.map((name) => `%feature("embind:constant") ${name};`).join('\n')}\n\n` : '';
|
|
72
104
|
}
|
|
73
105
|
|
|
106
|
+
// SWIG ignores every global function, then wraps the listed names again: class members, enums and constants stay. The
|
|
107
|
+
// package's own ignores come after, since SWIG applies the later of two renames of a name.
|
|
108
|
+
function functionRequests(functions) {
|
|
109
|
+
if (functions === ALL_NAMES) return '';
|
|
110
|
+
const names = [...new Set(functions)].sort();
|
|
111
|
+
return `%rename($ignore, %$isfunction, %$isglobal) "";\n${names.map((name) => `%rename("%s") ${name};\n`).join('')}\n`;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Editor declarations need the whole header even when the compiled bridge selects functions by import.
|
|
115
|
+
export function interfaceWithAllFunctions(content) {
|
|
116
|
+
return content.replace(/%rename\(\$ignore, %\$isfunction, %\$isglobal\) "";\n(?:%rename\("%s"\) [A-Za-z_]\w*;\n)*\n/g, '');
|
|
117
|
+
}
|
|
118
|
+
|
|
74
119
|
export function withoutSwigMacros(content) {
|
|
75
120
|
return content.replace(/(%feature\("polymorphic_shared_ptr"\);\n\n)(?:#define [^\n]*\n)+\n/, '$1');
|
|
76
121
|
}
|
|
@@ -333,6 +378,26 @@ function walkScopes(text, visit) {
|
|
|
333
378
|
});
|
|
334
379
|
}
|
|
335
380
|
|
|
381
|
+
// Whether the token at `index` sits inside the parentheses of the declaration it belongs to: a prototype's parameter.
|
|
382
|
+
function isInsideParentheses(tokens, index) {
|
|
383
|
+
let depth = 0;
|
|
384
|
+
for (let at = index - 1; at >= 0 && ![';', '{', '}'].includes(tokens[at]); at -= 1) {
|
|
385
|
+
if (tokens[at] === '(') depth += 1;
|
|
386
|
+
else if (tokens[at] === ')') depth -= 1;
|
|
387
|
+
}
|
|
388
|
+
return depth > 0;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// Whether a variable `name` is declared outside every class, namespace and block, as `extern int name;` is.
|
|
392
|
+
export function declaresAtFileScope(text, name) {
|
|
393
|
+
let found = false;
|
|
394
|
+
walkScopes(text, (token, index, tokens, scopes) => {
|
|
395
|
+
if (token === name && scopes.every((scope) => scope.kind === 'extern') && [';', '=', '[', ','].includes(tokens[index + 1])
|
|
396
|
+
&& !isInsideParentheses(tokens, index)) found = true;
|
|
397
|
+
});
|
|
398
|
+
return found;
|
|
399
|
+
}
|
|
400
|
+
|
|
336
401
|
// Classes, structs and enums by qualified name, including the names C typedefs give them, each mapped to the first header
|
|
337
402
|
// defining it. Preprocessor branches are all read.
|
|
338
403
|
export function indexTypeDefinitions(files) {
|
package/src/utils/systemKeys.js
CHANGED
|
@@ -4,12 +4,36 @@ const systemKeys = {
|
|
|
4
4
|
default: '',
|
|
5
5
|
},
|
|
6
6
|
RUNNER: {
|
|
7
|
-
description: '
|
|
8
|
-
options: ['DOCKER_RUN', 'DOCKER_EXEC', 'LOCAL'],
|
|
7
|
+
description: 'Where toolchain steps run: DOCKER_RUN, DOCKER_EXEC, LOCAL, or REMOTE on the runners REMOTE_URL and REMOTE_URL_<IMAGE> name; a machine that names none builds on crossbind cloud once signed in with crossbind login. The CROSSBIND_RUNNER environment variable overrides it.',
|
|
8
|
+
options: ['DOCKER_RUN', 'DOCKER_EXEC', 'LOCAL', 'REMOTE'],
|
|
9
9
|
default: 'DOCKER_RUN',
|
|
10
10
|
},
|
|
11
|
+
REMOTE_URL: {
|
|
12
|
+
description: 'Under RUNNER=REMOTE, the runner of every image without an address of its own. Its token comes from the CROSSBIND_TOKEN environment variable. The CROSSBIND_REMOTE_URL environment variable overrides it.',
|
|
13
|
+
default: '',
|
|
14
|
+
},
|
|
15
|
+
REMOTE_URL_WEB: {
|
|
16
|
+
description: 'Under RUNNER=REMOTE, the runner of the web image: wasm builds, wasi builds and the bridge steps of every platform but android. Token: CROSSBIND_TOKEN_WEB. The CROSSBIND_REMOTE_URL_WEB environment variable overrides it.',
|
|
17
|
+
default: '',
|
|
18
|
+
},
|
|
19
|
+
REMOTE_URL_ANDROID: {
|
|
20
|
+
description: 'Under RUNNER=REMOTE, the runner of the android image. Token: CROSSBIND_TOKEN_ANDROID. The CROSSBIND_REMOTE_URL_ANDROID environment variable overrides it.',
|
|
21
|
+
default: '',
|
|
22
|
+
},
|
|
23
|
+
REMOTE_URL_LINUX: {
|
|
24
|
+
description: 'Under RUNNER=REMOTE, the runner of the linux image (linux and linuxmusl builds). Token: CROSSBIND_TOKEN_LINUX. The CROSSBIND_REMOTE_URL_LINUX environment variable overrides it.',
|
|
25
|
+
default: '',
|
|
26
|
+
},
|
|
27
|
+
REMOTE_URL_WINDOWS: {
|
|
28
|
+
description: 'Under RUNNER=REMOTE, the runner of the windows image (win32 builds). Token: CROSSBIND_TOKEN_WINDOWS. The CROSSBIND_REMOTE_URL_WINDOWS environment variable overrides it.',
|
|
29
|
+
default: '',
|
|
30
|
+
},
|
|
31
|
+
CLOUD_URL: {
|
|
32
|
+
description: 'The crossbind cloud that crossbind login, logout and usage talk to. The CROSSBIND_CLOUD_URL environment variable overrides it.',
|
|
33
|
+
default: 'https://api.crossbind.dev',
|
|
34
|
+
},
|
|
11
35
|
WASI_SDK_PATH: {
|
|
12
|
-
description: 'Path to an extracted wasi-sdk (>= 34, wasm32-wasip3 sysroot)
|
|
36
|
+
description: 'Path to an extracted wasi-sdk (>= 34, wasm32-wasip3 sysroot) that platform:\'wasi\' builds use under RUNNER=LOCAL; the other runners use the sdk in the image. The CROSSBIND_WASI_SDK_PATH environment variable overrides it.',
|
|
13
37
|
default: '',
|
|
14
38
|
},
|
|
15
39
|
DOCKER_REGISTRY_MIRROR: {
|
|
@@ -35,3 +59,11 @@ const systemKeys = {
|
|
|
35
59
|
};
|
|
36
60
|
|
|
37
61
|
export default systemKeys;
|
|
62
|
+
|
|
63
|
+
// Read as LOCAL, a runner crossbind does not know would run recipes and build scripts on the host.
|
|
64
|
+
export function assertRunner(runner, name = 'RUNNER') {
|
|
65
|
+
if (!systemKeys.RUNNER.options.includes(runner)) {
|
|
66
|
+
throw new Error(`crossbind: the runner ${runner} is invalid; ${name} is one of ${systemKeys.RUNNER.options.join(', ')}.`);
|
|
67
|
+
}
|
|
68
|
+
return runner;
|
|
69
|
+
}
|
package/src/utils/targets.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Single source for the build-target matrix and its naming; state/ copies (and then
|
|
2
2
|
// decorates) these entries, and consumer runtimes read them without touching CLI state.
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
const BASE_TARGETS = [
|
|
5
5
|
{
|
|
6
6
|
platform: 'wasm', arch: 'wasm32', runtime: 'st', buildType: 'release', runtimeEnv: 'browser',
|
|
7
7
|
},
|
|
@@ -63,10 +63,10 @@ export const TARGETS = [
|
|
|
63
63
|
platform: 'wasm', arch: 'wasm64', runtime: 'mt', buildType: 'debug', runtimeEnv: 'node',
|
|
64
64
|
},
|
|
65
65
|
{
|
|
66
|
-
platform: 'wasi', arch: 'wasm32', runtime: 'st', buildType: 'release',
|
|
66
|
+
platform: 'wasi', arch: 'wasm32', runtime: 'st', buildType: 'release', runtimeEnv: 'wasi',
|
|
67
67
|
},
|
|
68
68
|
{
|
|
69
|
-
platform: 'wasi', arch: 'wasm32', runtime: 'st', buildType: 'debug',
|
|
69
|
+
platform: 'wasi', arch: 'wasm32', runtime: 'st', buildType: 'debug', runtimeEnv: 'wasi',
|
|
70
70
|
},
|
|
71
71
|
{
|
|
72
72
|
platform: 'android', arch: 'arm64-v8a', runtime: 'mt', buildType: 'release',
|
|
@@ -116,6 +116,18 @@ export const TARGETS = [
|
|
|
116
116
|
{
|
|
117
117
|
platform: 'linux', arch: 'x64', runtime: 'mt', buildType: 'debug', runtimeEnv: 'node',
|
|
118
118
|
},
|
|
119
|
+
{
|
|
120
|
+
platform: 'linuxmusl', arch: 'arm64', runtime: 'mt', buildType: 'release', runtimeEnv: 'node',
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
platform: 'linuxmusl', arch: 'arm64', runtime: 'mt', buildType: 'debug', runtimeEnv: 'node',
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
platform: 'linuxmusl', arch: 'x64', runtime: 'mt', buildType: 'release', runtimeEnv: 'node',
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
platform: 'linuxmusl', arch: 'x64', runtime: 'mt', buildType: 'debug', runtimeEnv: 'node',
|
|
130
|
+
},
|
|
119
131
|
{
|
|
120
132
|
platform: 'win32', arch: 'arm64', runtime: 'mt', buildType: 'release', runtimeEnv: 'node',
|
|
121
133
|
},
|
|
@@ -130,17 +142,43 @@ export const TARGETS = [
|
|
|
130
142
|
},
|
|
131
143
|
];
|
|
132
144
|
|
|
145
|
+
// A native executable links the same archives as the Node-API addon of its platform and arch.
|
|
146
|
+
export const TARGETS = [
|
|
147
|
+
...BASE_TARGETS,
|
|
148
|
+
...BASE_TARGETS
|
|
149
|
+
.filter((target) => target.runtimeEnv === 'node' && target.platform !== 'wasm')
|
|
150
|
+
.map((target) => ({ ...target, runtimeEnv: 'native' })),
|
|
151
|
+
];
|
|
152
|
+
|
|
133
153
|
// Built only when named with -p: a plain `crossbind build` keeps producing what it did before
|
|
134
154
|
// native Node.js addons existed.
|
|
135
|
-
export const OPT_IN_PLATFORMS = ['darwin', 'linux', 'win32'];
|
|
155
|
+
export const OPT_IN_PLATFORMS = ['darwin', 'linux', 'linuxmusl', 'win32'];
|
|
136
156
|
|
|
137
157
|
// Built on the host itself: Apple's linker and SDKs exist in no toolchain image.
|
|
138
158
|
export const HOST_BUILT_PLATFORMS = ['ios', 'darwin'];
|
|
139
159
|
|
|
160
|
+
// The runtime environment names the binary a build makes; android and ios have none, since
|
|
161
|
+
// React Native links them.
|
|
162
|
+
export const runtimeEnvsOf = (platform) => [
|
|
163
|
+
...new Set(TARGETS.filter((target) => target.platform === platform && target.runtimeEnv).map((target) => target.runtimeEnv)),
|
|
164
|
+
];
|
|
165
|
+
|
|
166
|
+
export const RUNTIME_ENVS = [...new Set(TARGETS.map((target) => target.runtimeEnv).filter(Boolean))];
|
|
167
|
+
|
|
168
|
+
// A build makes only the binaries it is asked for: -e first, then the config's target.runtimeEnv.
|
|
169
|
+
// Bundler plugins ask through getTargetParams instead.
|
|
170
|
+
export function selectRuntimeEnvs(cliRuntimeEnvs, configRuntimeEnv) {
|
|
171
|
+
if (cliRuntimeEnvs?.length) return cliRuntimeEnvs;
|
|
172
|
+
return configRuntimeEnv ? [configRuntimeEnv] : [];
|
|
173
|
+
}
|
|
174
|
+
|
|
140
175
|
export function targetPathOf(target) {
|
|
141
176
|
return `${target.platform}-${target.arch}-${target.runtime}-${target.buildType}`;
|
|
142
177
|
}
|
|
143
178
|
|
|
179
|
+
// The release build of a target, whose prebuilts a debug build of it falls back to.
|
|
180
|
+
export const releaseTargetOf = (target) => ({ ...target, buildType: 'release', path: target.releasePath });
|
|
181
|
+
|
|
144
182
|
// Every platform/arch addon of one build type sits next to a single loader, which fills in
|
|
145
183
|
// {platform} and {arch} from the running process. The loader is CommonJS whatever the package
|
|
146
184
|
// "type" says, since it needs __dirname and process.dlopen.
|
|
@@ -154,6 +192,13 @@ export function nodeAddonNamesOf(target, projectName) {
|
|
|
154
192
|
};
|
|
155
193
|
}
|
|
156
194
|
|
|
195
|
+
// One executable per platform, arch and build type, named like the addons it replaces.
|
|
196
|
+
export function nativeCommandNamesOf(target, projectName) {
|
|
197
|
+
const suffix = target.buildType === 'debug' ? '.debug' : '';
|
|
198
|
+
const extension = target.platform === 'win32' ? '.exe' : '';
|
|
199
|
+
return { commandName: `${projectName}.${target.platform}-${target.arch}${suffix}${extension}` };
|
|
200
|
+
}
|
|
201
|
+
|
|
157
202
|
export function filterTargetSpecs(targetSpecs, target) {
|
|
158
203
|
return targetSpecs?.filter(t => (
|
|
159
204
|
(!t.platform || t.platform === target.platform)
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Where a build keeps the notices of the runtime a toolchain image linked into its binaries,
|
|
2
|
+
// relative to the build directory; crossbind licenses reads them from there.
|
|
3
|
+
export default function toolchainNoticesDir(platform) {
|
|
4
|
+
return `toolchain-licenses/${platform}`;
|
|
5
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// Toolchain surface for platform:'wasi' (wasm32-wasip3, wasi-sdk >= 34; run under `wasmtime`).
|
|
2
2
|
|
|
3
|
+
import { isLocalRunner } from './selectRunner.js';
|
|
4
|
+
|
|
3
5
|
export const WASI_TARGET_TRIPLE = 'wasm32-wasip3';
|
|
4
6
|
// The sdk's clang still defaults to wasip1, so every compile/link carries --target explicitly.
|
|
5
7
|
export const WASI_TARGET_FLAGS = [`--target=${WASI_TARGET_TRIPLE}`];
|
|
@@ -31,6 +33,7 @@ export const WASI_LINK_LIBS = [
|
|
|
31
33
|
'-lunwind',
|
|
32
34
|
'-lsetjmp',
|
|
33
35
|
...WASI_EMULATION_LIBS,
|
|
36
|
+
'-Wl,--wrap=lseek',
|
|
34
37
|
];
|
|
35
38
|
|
|
36
39
|
export function wasiCFlags() {
|
|
@@ -41,7 +44,17 @@ export function wasiCxxFlags() {
|
|
|
41
44
|
return [...WASI_TARGET_FLAGS, ...WASI_COMPILE_DEFINES, '-fwasm-exceptions', ...WASI_EH_CFLAGS];
|
|
42
45
|
}
|
|
43
46
|
|
|
44
|
-
//
|
|
47
|
+
// The host sdk of a RUNNER=LOCAL build: env override first, then persistent ~/.crossbind.json; null when
|
|
48
|
+
// unset, and under the other runners, whose builds use the sdk in the image.
|
|
45
49
|
export function resolveWasiSdkPath(system, env = process.env) {
|
|
50
|
+
if (!isLocalRunner(system, env)) return null;
|
|
46
51
|
return env.CROSSBIND_WASI_SDK_PATH || system?.WASI_SDK_PATH || null;
|
|
47
52
|
}
|
|
53
|
+
|
|
54
|
+
// Recipes read the wasi-sdk location from the environment (lazily, in getBuildParams), so it names
|
|
55
|
+
// the sdk the build uses: the host's under RUNNER=LOCAL, none (the image's) under the other runners.
|
|
56
|
+
export function exportWasiSdkPath(system, env = process.env) {
|
|
57
|
+
const sdk = resolveWasiSdkPath(system, env);
|
|
58
|
+
if (sdk) env.CROSSBIND_WASI_SDK_PATH = sdk;
|
|
59
|
+
else delete env.CROSSBIND_WASI_SDK_PATH;
|
|
60
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// The windows image's llvm-mingw and its CMake toolchain files, one per target triple: port archives and
|
|
2
|
+
// Conan packages link into the same addon, so they move together.
|
|
3
|
+
const LLVM_MINGW = '/opt/llvm-mingw';
|
|
4
|
+
const WINDOWS_TOOLCHAIN = '/opt/crossbind/windows';
|
|
5
|
+
const WINDOWS_TRIPLES = { x64: 'x86_64-w64-mingw32', arm64: 'aarch64-w64-mingw32' };
|
|
6
|
+
|
|
7
|
+
export const windowsTriple = (target) => WINDOWS_TRIPLES[target.arch];
|
|
8
|
+
export const windowsToolchainFile = (target) => `${WINDOWS_TOOLCHAIN}/${windowsTriple(target)}.cmake`;
|
|
9
|
+
export const windowsTool = (target, name) => `${LLVM_MINGW}/bin/${windowsTriple(target)}-${name}`;
|
|
10
|
+
|
|
11
|
+
// The compilers, archive and resource tools of the target's triple, by the variables build systems read
|
|
12
|
+
// them from. The image's own .pc files describe its libraries, not the target's, so pkg-config reads none.
|
|
13
|
+
export const windowsBuildEnv = (target) => ({
|
|
14
|
+
...Object.fromEntries(Object.entries({
|
|
15
|
+
CC: 'clang', CXX: 'clang++', AR: 'ar', RANLIB: 'ranlib', NM: 'nm', STRIP: 'strip', RC: 'windres', WINDRES: 'windres',
|
|
16
|
+
}).map(([variable, tool]) => [variable, windowsTool(target, tool)])),
|
|
17
|
+
PKG_CONFIG_LIBDIR: '',
|
|
18
|
+
});
|
package/vitest.config.js
CHANGED
|
@@ -12,6 +12,17 @@ export default defineConfig({
|
|
|
12
12
|
test: {
|
|
13
13
|
include: ['test/**/*.test.js'],
|
|
14
14
|
environment: 'node',
|
|
15
|
+
// A developer's own runner settings must not decide where the tested steps run, and neither must their
|
|
16
|
+
// crossbind login: no one signs in to a cloud at this address.
|
|
17
|
+
env: {
|
|
18
|
+
CROSSBIND_RUNNER: '',
|
|
19
|
+
CROSSBIND_REMOTE_URL: '',
|
|
20
|
+
CROSSBIND_REMOTE_URL_WEB: '',
|
|
21
|
+
CROSSBIND_REMOTE_URL_ANDROID: '',
|
|
22
|
+
CROSSBIND_REMOTE_URL_LINUX: '',
|
|
23
|
+
CROSSBIND_REMOTE_URL_WINDOWS: '',
|
|
24
|
+
CROSSBIND_CLOUD_URL: 'http://127.0.0.1:9',
|
|
25
|
+
},
|
|
15
26
|
coverage: {
|
|
16
27
|
provider: 'v8',
|
|
17
28
|
reporter: ['text', 'html'],
|