crossbind 2.0.0-beta.52 → 2.0.0-beta.55
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/AGENTS.md +1 -1
- package/CHANGELOG.md +8 -0
- package/README.md +1 -1
- package/package.json +51 -54
- package/src/actions/buildBinTools.js +0 -0
- package/src/actions/buildLib.js +8 -1
- package/src/actions/buildWasm.js +8 -9
- package/src/actions/createLib.js +1 -1
- package/src/actions/run.js +100 -60
- package/src/assets/toolchain-digests.json +36 -0
- package/src/utils/binTools.js +5 -0
- package/src/utils/dockerSecurity.js +4 -0
- package/src/utils/overrideDependency.js +1 -1
- package/src/utils/pullDockerImage.js +15 -21
- package/src/utils/runCargo.js +63 -28
- package/src/utils/rustSysrootPin.js +8 -5
- package/src/utils/sourceFingerprint.js +13 -0
package/AGENTS.md
CHANGED
|
@@ -33,7 +33,7 @@ Side-quests:
|
|
|
33
33
|
|
|
34
34
|
## Public API contract
|
|
35
35
|
|
|
36
|
-
Anything exported from `src/index.js` is consumed by `plugins/*` and a few CLI scripts (`scripts/check-*.js`). Treat its surface as semver-public — additive changes free, breaking changes need a beta bump and a
|
|
36
|
+
Anything exported from `src/index.js` is consumed by `plugins/*` and a few CLI scripts (`scripts/check-*.js`). Treat its surface as semver-public — additive changes free, breaking changes need a beta bump and a human-authored `releases/crossbind/<version>.md` note.
|
|
37
37
|
|
|
38
38
|
Currently exported (snapshot):
|
|
39
39
|
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# crossbind
|
|
2
2
|
|
|
3
|
+
## 2.0.0-beta.53
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- The rebuild the source stamp triggers now clears the previous upstream release's configure
|
|
8
|
+
output and staged install tree first. Without that, an install step fails where it cannot
|
|
9
|
+
overwrite a file it did not create, which is what stopped the beta.52 publish partway.
|
|
10
|
+
|
|
3
11
|
## 2.0.0-beta.52
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -87,7 +87,7 @@ adapters.
|
|
|
87
87
|
## Quick start
|
|
88
88
|
|
|
89
89
|
Prefer to scaffold and configure the project yourself? You need
|
|
90
|
-
[Node.js
|
|
90
|
+
[Node.js 24+](https://nodejs.org/) and
|
|
91
91
|
[Docker](https://www.docker.com/). Docker carries the browser, Android, and
|
|
92
92
|
WASI toolchains and is pulled automatically on the first build. iOS additionally
|
|
93
93
|
requires macOS, CMake 3.28+, Xcode, and CocoaPods.
|
package/package.json
CHANGED
|
@@ -1,55 +1,52 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
"test:coverage": "vitest run --coverage"
|
|
54
|
-
}
|
|
55
|
-
}
|
|
2
|
+
"name": "crossbind",
|
|
3
|
+
"version": "2.0.0-beta.55",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"homepage": "https://crossbind.dev",
|
|
6
|
+
"repository": "https://github.com/crossbind/crossbind.git",
|
|
7
|
+
"description": "Bind C++ to JavaScript without extra code. crossbind supports WebAssembly and React Native for cross-platform compatibility.",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": ">=24"
|
|
11
|
+
},
|
|
12
|
+
"bin": {
|
|
13
|
+
"crossbind": "./src/bin.js"
|
|
14
|
+
},
|
|
15
|
+
"main": "src/index.js",
|
|
16
|
+
"scripts": {
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"test:watch": "vitest",
|
|
19
|
+
"test:coverage": "vitest run --coverage"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
23
|
+
"vitest": "^4.1.10"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@rollup/plugin-commonjs": "^29.0.3",
|
|
27
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
28
|
+
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
29
|
+
"@rollup/plugin-virtual": "^3.0.2",
|
|
30
|
+
"comlink": "^4.4.2",
|
|
31
|
+
"commander": "^15.0.0",
|
|
32
|
+
"glob": "^13.0.6",
|
|
33
|
+
"log-update": "^8.0.0",
|
|
34
|
+
"picocolors": "^1.1.1",
|
|
35
|
+
"replace": "^1.2.2",
|
|
36
|
+
"rollup": "^4.62.4",
|
|
37
|
+
"spdx-expression-parse": "^5.0.0",
|
|
38
|
+
"upath": "^3.0.8"
|
|
39
|
+
},
|
|
40
|
+
"keywords": [
|
|
41
|
+
"webassembly",
|
|
42
|
+
"react-native",
|
|
43
|
+
"bind",
|
|
44
|
+
"c++",
|
|
45
|
+
"emscripten",
|
|
46
|
+
"embind",
|
|
47
|
+
"swig",
|
|
48
|
+
"android",
|
|
49
|
+
"ios",
|
|
50
|
+
"mobile"
|
|
51
|
+
]
|
|
52
|
+
}
|
|
Binary file
|
package/src/actions/buildLib.js
CHANGED
|
@@ -6,7 +6,7 @@ import { getBuildTargets, getFilteredTargetSpec } from './target.js';
|
|
|
6
6
|
import state from '../state/index.js';
|
|
7
7
|
import logger from '../utils/logger.js';
|
|
8
8
|
import findFiles from '../utils/findFiles.js';
|
|
9
|
-
import { getSourceFingerprint, isSourceFingerprintStale, writeSourceFingerprint } from '../utils/sourceFingerprint.js';
|
|
9
|
+
import { getSourceFingerprint, isSourceFingerprintStale, staleTargetDirectories, writeSourceFingerprint } from '../utils/sourceFingerprint.js';
|
|
10
10
|
|
|
11
11
|
export default function buildLib(targetParams, options = {}) {
|
|
12
12
|
let isChanged = false;
|
|
@@ -24,6 +24,13 @@ export default function buildLib(targetParams, options = {}) {
|
|
|
24
24
|
const sourceFingerprint = getSourceFingerprint(state.config);
|
|
25
25
|
const sourceChanged = isSourceFingerprintStale(libdir, sourceFingerprint);
|
|
26
26
|
if (isCargo || sourceChanged || !fs.existsSync(`${libdir}/lib`)) {
|
|
27
|
+
if (sourceChanged) {
|
|
28
|
+
for (const stale of staleTargetDirectories({
|
|
29
|
+
buildPath: state.config.paths.build,
|
|
30
|
+
outputPath: state.config.paths.output,
|
|
31
|
+
targetPath: target.path,
|
|
32
|
+
})) fs.rmSync(stale, { recursive: true, force: true });
|
|
33
|
+
}
|
|
27
34
|
// createLib caches on existence too, so re-entering is not enough: a stale stamp means
|
|
28
35
|
// the lib on disk came from a different upstream release and has to be rebuilt.
|
|
29
36
|
createLib(target, 'Source', { buildSource: true, force: sourceChanged });
|
package/src/actions/buildWasm.js
CHANGED
|
@@ -169,19 +169,19 @@ export default async function buildWasm(target, options = {}) {
|
|
|
169
169
|
triggerExtensions('buildWasm', 'beforeBuildBrowser', [emccFlags]);
|
|
170
170
|
|
|
171
171
|
const data = Object.entries(getData('data', target)).map(([key, value]) => ['--preload-file', `${key.replaceAll('@', '@@')}@/crossbind/${value}`]).flat();
|
|
172
|
-
run('
|
|
172
|
+
run('em++', [
|
|
173
173
|
'-lembind',
|
|
174
174
|
...emccFlags,
|
|
175
175
|
// '-lwebsocket.js', '-sPROXY_POSIX_SOCKETS', '-sWEBSOCKET_DEBUG=1', '-sJSPI', '-g', '-sWASMFS',
|
|
176
|
-
'-
|
|
176
|
+
'-s', 'FORCE_FILESYSTEM=1',
|
|
177
177
|
'-sEXPORT_NAME=Module2', // '-pthread', '-sPTHREAD_POOL_SIZE=5',
|
|
178
178
|
...linkLibs, ...rustSources, `${state.config.paths.cli}/assets/cpp-runtime/browser.cpp`,
|
|
179
179
|
...(isProd ? ['-O3'] : []),
|
|
180
180
|
'-s', 'WASM=1', '-s', 'MODULARIZE=1', '-s', 'DYNAMIC_EXECUTION=0',
|
|
181
181
|
'-s', 'RESERVED_FUNCTION_POINTERS=200', // '-s', 'FORCE_FILESYSTEM=1',
|
|
182
182
|
'-s', 'ALLOW_MEMORY_GROWTH=1',
|
|
183
|
-
//
|
|
184
|
-
//
|
|
183
|
+
// Keep this explicit: Firefox/WebKit TextDecoder rejects views over resizable
|
|
184
|
+
// ArrayBuffers, breaking every string crossing the wasm boundary.
|
|
185
185
|
'-s', 'GROWABLE_ARRAYBUFFERS=0',
|
|
186
186
|
'-s', 'WASMFS',
|
|
187
187
|
'-s', 'ENVIRONMENT=web,webview,worker',
|
|
@@ -240,10 +240,9 @@ export default async function buildWasm(target, options = {}) {
|
|
|
240
240
|
triggerExtensions('buildWasm', 'beforeBuildEdge', [emccFlags]);
|
|
241
241
|
|
|
242
242
|
const data = Object.entries(getData('data', target)).map(([key, value]) => ['--preload-file', `${key.replaceAll('@', '@@')}@/crossbind/${value}`]).flat();
|
|
243
|
-
run('
|
|
243
|
+
run('em++', [
|
|
244
244
|
'-lembind',
|
|
245
245
|
...emccFlags,
|
|
246
|
-
'-sWASM_BIGINT=1',
|
|
247
246
|
'-sEXPORT_NAME=Module2',
|
|
248
247
|
// rustSources carries the embind-rust adapter TU (emval/json/tid hooks); without
|
|
249
248
|
// it any linked Rust package archive fails with undefined crossbind_* symbols.
|
|
@@ -273,11 +272,11 @@ export default async function buildWasm(target, options = {}) {
|
|
|
273
272
|
|
|
274
273
|
triggerExtensions('buildWasm', 'beforeBuildNodeJS', [emccFlags]);
|
|
275
274
|
|
|
276
|
-
run('
|
|
275
|
+
run('em++', [
|
|
277
276
|
'-lembind',
|
|
278
277
|
...emccFlags,
|
|
279
|
-
// '-s', 'FETCH', '-sJSPI', '-
|
|
280
|
-
'-
|
|
278
|
+
// '-s', 'FETCH', '-sJSPI', '-pthread', '-sPTHREAD_POOL_SIZE=5',
|
|
279
|
+
'-s', 'FORCE_FILESYSTEM=1',
|
|
281
280
|
...linkLibs, ...rustSources, `${state.config.paths.cli}/assets/cpp-runtime/node.cpp`,
|
|
282
281
|
...(isProd ? ['-O3'] : []),
|
|
283
282
|
'-s', 'WASM=1', '-s', 'MODULARIZE=1', '-s', 'DYNAMIC_EXECUTION=0',
|
package/src/actions/createLib.js
CHANGED
|
@@ -203,7 +203,7 @@ export default function createLib(target, fileType, options = {}) {
|
|
|
203
203
|
stageWasiStubs();
|
|
204
204
|
}
|
|
205
205
|
run(null, [
|
|
206
|
-
'./configure',
|
|
206
|
+
state.config.build?.configureProgram || './configure',
|
|
207
207
|
...buildParams,
|
|
208
208
|
`--prefix=${libdir}`,
|
|
209
209
|
], platformPrefix, target, buildEnv);
|
package/src/actions/run.js
CHANGED
|
@@ -3,6 +3,7 @@ import fs from 'node:fs';
|
|
|
3
3
|
import pullDockerImage, { getDockerImage, getDockerContainerName, imageRoleFor } from '../utils/pullDockerImage.js';
|
|
4
4
|
import getOsUserAndGroupId from '../utils/getOsUserAndGroupId.js';
|
|
5
5
|
import replaceBasePathForDockerUtil from '../utils/replaceBasePathForDocker.js';
|
|
6
|
+
import { DOCKER_RUN_SECURITY_ARGS } from '../utils/dockerSecurity.js';
|
|
6
7
|
import state from '../state/index.js';
|
|
7
8
|
import { wasiCFlags, wasiCxxFlags, resolveWasiSdkPath, WASI_TARGET_TRIPLE } from '../utils/wasiToolchain.js';
|
|
8
9
|
|
|
@@ -20,51 +21,70 @@ const iosSdkPath = `${iOSDevPath}/Platforms/iPhoneOS.platform/Developer/SDKs/iPh
|
|
|
20
21
|
const iosSimSdkPath = `${iOSDevPath}/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk`;
|
|
21
22
|
|
|
22
23
|
const androidParamsArm64 = [
|
|
23
|
-
'-e',
|
|
24
|
-
|
|
25
|
-
'-e',
|
|
26
|
-
|
|
27
|
-
'-e',
|
|
28
|
-
|
|
29
|
-
'-e',
|
|
30
|
-
|
|
31
|
-
'-e',
|
|
24
|
+
'-e',
|
|
25
|
+
`AR=${t}/llvm-ar`,
|
|
26
|
+
'-e',
|
|
27
|
+
`AS=${t}/llvm-as`,
|
|
28
|
+
'-e',
|
|
29
|
+
`CC=${t}/${CROSSCOMPILER_ARM64}-clang`,
|
|
30
|
+
'-e',
|
|
31
|
+
`CXX=${t}/${CROSSCOMPILER_ARM64}-clang++`,
|
|
32
|
+
'-e',
|
|
33
|
+
`LD=${t}/ld`,
|
|
34
|
+
'-e',
|
|
35
|
+
`RANLIB=${t}/llvm-ranlib`,
|
|
36
|
+
'-e',
|
|
37
|
+
`STRIP=${t}/llvm-strip`,
|
|
38
|
+
'-e',
|
|
39
|
+
`NM=${t}/nm`,
|
|
40
|
+
'-e',
|
|
41
|
+
`CFLAGS=--sysroot=${t2}/sysroot`,
|
|
32
42
|
];
|
|
33
43
|
|
|
34
44
|
const androidParamsX86_64 = [
|
|
35
|
-
'-e',
|
|
36
|
-
|
|
37
|
-
'-e',
|
|
38
|
-
|
|
39
|
-
'-e',
|
|
40
|
-
|
|
41
|
-
'-e',
|
|
42
|
-
|
|
43
|
-
'-e',
|
|
45
|
+
'-e',
|
|
46
|
+
`AR=${t}/llvm-ar`,
|
|
47
|
+
'-e',
|
|
48
|
+
`AS=${t}/llvm-as`,
|
|
49
|
+
'-e',
|
|
50
|
+
`CC=${t}/${CROSSCOMPILER_x86_64}-clang`,
|
|
51
|
+
'-e',
|
|
52
|
+
`CXX=${t}/${CROSSCOMPILER_x86_64}-clang++`,
|
|
53
|
+
'-e',
|
|
54
|
+
`LD=${t}/ld`,
|
|
55
|
+
'-e',
|
|
56
|
+
`RANLIB=${t}/llvm-ranlib`,
|
|
57
|
+
'-e',
|
|
58
|
+
`STRIP=${t}/llvm-strip`,
|
|
59
|
+
'-e',
|
|
60
|
+
`NM=${t}/nm`,
|
|
61
|
+
'-e',
|
|
62
|
+
`CFLAGS=--sysroot=${t2}/sysroot`,
|
|
44
63
|
];
|
|
45
64
|
|
|
46
65
|
const IOS_HOST_FLAGS = `-arch arm64 -isysroot ${iosSdkPath} -fembed-bitcode`;
|
|
47
66
|
const IOS_SIM_HOST_FLAGS = `-arch arm64 -isysroot ${iosSimSdkPath} -fembed-bitcode`;
|
|
48
|
-
const IOS_IPHONE_PARAMS = [
|
|
49
|
-
|
|
50
|
-
'-e', `CXXFLAGS="${IOS_HOST_FLAGS}"`,
|
|
51
|
-
'-e', `LDFLAGS="${IOS_HOST_FLAGS}"`,
|
|
52
|
-
];
|
|
53
|
-
const IOS_SIM_PARAMS = [
|
|
54
|
-
'-e', `CFLAGS="${IOS_SIM_HOST_FLAGS}"`,
|
|
55
|
-
'-e', `CXXFLAGS="${IOS_SIM_HOST_FLAGS}"`,
|
|
56
|
-
'-e', `LDFLAGS="${IOS_SIM_HOST_FLAGS}"`,
|
|
57
|
-
];
|
|
67
|
+
const IOS_IPHONE_PARAMS = ['-e', `CFLAGS="${IOS_HOST_FLAGS}"`, '-e', `CXXFLAGS="${IOS_HOST_FLAGS}"`, '-e', `LDFLAGS="${IOS_HOST_FLAGS}"`];
|
|
68
|
+
const IOS_SIM_PARAMS = ['-e', `CFLAGS="${IOS_SIM_HOST_FLAGS}"`, '-e', `CXXFLAGS="${IOS_SIM_HOST_FLAGS}"`, '-e', `LDFLAGS="${IOS_SIM_HOST_FLAGS}"`];
|
|
58
69
|
const iosParams = [
|
|
59
|
-
'-e',
|
|
60
|
-
|
|
61
|
-
'-e',
|
|
62
|
-
|
|
63
|
-
'-e',
|
|
64
|
-
|
|
65
|
-
'-e',
|
|
66
|
-
|
|
67
|
-
'-e',
|
|
70
|
+
'-e',
|
|
71
|
+
`AR=${iosBinPath}/ar`,
|
|
72
|
+
'-e',
|
|
73
|
+
`AS=${iosBinPath}/as`,
|
|
74
|
+
'-e',
|
|
75
|
+
`CC=${iosBinPath}/clang`,
|
|
76
|
+
'-e',
|
|
77
|
+
`CXX=${iosBinPath}/clang++`,
|
|
78
|
+
'-e',
|
|
79
|
+
`CPP=${iosBinPath}/cpp`,
|
|
80
|
+
'-e',
|
|
81
|
+
`LD=${iosBinPath}/ld`,
|
|
82
|
+
'-e',
|
|
83
|
+
`RANLIB=${iosBinPath}/ranlib`,
|
|
84
|
+
'-e',
|
|
85
|
+
`STRIP=${iosBinPath}/strip`,
|
|
86
|
+
'-e',
|
|
87
|
+
`NM=${iosBinPath}/llvm-nm`,
|
|
68
88
|
];
|
|
69
89
|
|
|
70
90
|
/* const iosMetalParams = [
|
|
@@ -103,7 +123,7 @@ export default function run(program, params = [], platformPrefix = null, target
|
|
|
103
123
|
switch (target.platform) {
|
|
104
124
|
case 'wasm':
|
|
105
125
|
platformParams = ['-e', 'CXXFLAGS=-fwasm-exceptions', '-e', 'CFLAGS=-fwasm-exceptions'];
|
|
106
|
-
if (params[0].includes('configure')) dProgram = 'emconfigure';
|
|
126
|
+
if (params[0].toLowerCase().includes('configure')) dProgram = 'emconfigure';
|
|
107
127
|
else if (params[0] === 'make') dProgram = 'emmake';
|
|
108
128
|
else if (params[0] === 'cmake') dProgram = 'emcmake';
|
|
109
129
|
else if (params[0] === 'cc') dProgram = 'emcc';
|
|
@@ -111,23 +131,29 @@ export default function run(program, params = [], platformPrefix = null, target
|
|
|
111
131
|
case 'wasi': {
|
|
112
132
|
const wasiSdk = wasiHostSdk || '/opt/wasi-sdk';
|
|
113
133
|
if (wasiHostSdk && !fs.existsSync(`${wasiHostSdk}/share/wasi-sysroot/lib/${WASI_TARGET_TRIPLE}`)) {
|
|
114
|
-
throw new Error(
|
|
134
|
+
throw new Error(
|
|
135
|
+
`crossbind: the wasi-sdk at ${wasiHostSdk} has no ${WASI_TARGET_TRIPLE} sysroot. platform:'wasi' targets WASI 0.3 (p3) - upgrade to wasi-sdk >= 34.`,
|
|
136
|
+
);
|
|
115
137
|
}
|
|
116
138
|
[dProgram, ...dParams] = params;
|
|
117
139
|
platformParams = [
|
|
118
|
-
'-e',
|
|
119
|
-
|
|
120
|
-
'-e',
|
|
121
|
-
|
|
122
|
-
'-e',
|
|
123
|
-
|
|
124
|
-
'-e',
|
|
140
|
+
'-e',
|
|
141
|
+
`CC=${wasiSdk}/bin/clang`,
|
|
142
|
+
'-e',
|
|
143
|
+
`CXX=${wasiSdk}/bin/clang++`,
|
|
144
|
+
'-e',
|
|
145
|
+
`AR=${wasiSdk}/bin/ar`,
|
|
146
|
+
'-e',
|
|
147
|
+
`RANLIB=${wasiSdk}/bin/ranlib`,
|
|
148
|
+
'-e',
|
|
149
|
+
`NM=${wasiSdk}/bin/nm`,
|
|
150
|
+
'-e',
|
|
151
|
+
`CFLAGS=${wasiCFlags().join(' ')}`,
|
|
152
|
+
'-e',
|
|
153
|
+
`CXXFLAGS=${wasiCxxFlags().join(' ')}`,
|
|
125
154
|
];
|
|
126
155
|
if (dProgram === 'cmake' && dParams[0] !== '--build' && dParams[0] !== '--install') {
|
|
127
|
-
dParams = [
|
|
128
|
-
...dParams,
|
|
129
|
-
`-DCMAKE_TOOLCHAIN_FILE=${wasiSdk}/share/cmake/wasi-sdk-p3.cmake`,
|
|
130
|
-
];
|
|
156
|
+
dParams = [...dParams, `-DCMAKE_TOOLCHAIN_FILE=${wasiSdk}/share/cmake/wasi-sdk-p3.cmake`];
|
|
131
157
|
} else if (dProgram === 'wasi-clang++') {
|
|
132
158
|
dProgram = `${wasiSdk}/bin/clang++`;
|
|
133
159
|
platformParams = [];
|
|
@@ -158,7 +184,8 @@ export default function run(program, params = [], platformPrefix = null, target
|
|
|
158
184
|
if (dParams[0] !== '--build' && dParams[0] !== '--install') {
|
|
159
185
|
dParams = [
|
|
160
186
|
...dParams,
|
|
161
|
-
'-G',
|
|
187
|
+
'-G',
|
|
188
|
+
'Xcode',
|
|
162
189
|
'-DBUILD_SHARED_LIBS=OFF',
|
|
163
190
|
'-DFRAMEWORK=TRUE',
|
|
164
191
|
'-DCMAKE_OSX_DEPLOYMENT_TARGET=13.0',
|
|
@@ -170,7 +197,7 @@ export default function run(program, params = [], platformPrefix = null, target
|
|
|
170
197
|
'-DCMAKE_SYSTEM_PROCESSOR=arm64',
|
|
171
198
|
`-DCMAKE_C_FLAGS=${target.arch === 'iphoneos' ? '-fembed-bitcode' : '-fembed-bitcode-marker'}`,
|
|
172
199
|
`-DCMAKE_CXX_FLAGS=${target.arch === 'iphoneos' ? '-fembed-bitcode' : '-fembed-bitcode-marker'}`,
|
|
173
|
-
|
|
200
|
+
"-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY='iPhone Developer'",
|
|
174
201
|
`-DCMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM=${state.config.system.XCODE_DEVELOPMENT_TEAM}`,
|
|
175
202
|
];
|
|
176
203
|
}
|
|
@@ -195,7 +222,7 @@ export default function run(program, params = [], platformPrefix = null, target
|
|
|
195
222
|
'-DCMAKE_SYSTEM_PROCESSOR=arm64',
|
|
196
223
|
`-DCMAKE_C_FLAGS=${target.arch === 'iphoneos' ? '-fembed-bitcode' : '-fembed-bitcode-marker'}`,
|
|
197
224
|
`-DCMAKE_CXX_FLAGS=${target.arch === 'iphoneos' ? '-fembed-bitcode' : '-fembed-bitcode-marker'}`,
|
|
198
|
-
|
|
225
|
+
"-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY='iPhone Developer'",
|
|
199
226
|
`-DCMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM=${state.config.system.XCODE_DEVELOPMENT_TEAM}`,
|
|
200
227
|
];
|
|
201
228
|
}
|
|
@@ -207,14 +234,25 @@ export default function run(program, params = [], platformPrefix = null, target
|
|
|
207
234
|
|
|
208
235
|
const env = {};
|
|
209
236
|
let runner = 'DOCKER';
|
|
210
|
-
if (
|
|
237
|
+
if (
|
|
238
|
+
((target?.platform === 'ios' || (target?.platform === 'wasi' && wasiHostSdk)) && program === null) ||
|
|
239
|
+
state.config.system.RUNNER === 'LOCAL'
|
|
240
|
+
) {
|
|
211
241
|
runner = 'LOCAL';
|
|
212
242
|
}
|
|
213
243
|
|
|
214
244
|
if (runner === 'LOCAL') {
|
|
215
245
|
const allowedEnv = [
|
|
216
|
-
'^PWD$',
|
|
217
|
-
'^
|
|
246
|
+
'^PWD$',
|
|
247
|
+
'^SHELL$',
|
|
248
|
+
'^LC_CTYPE$',
|
|
249
|
+
'^PATH$',
|
|
250
|
+
'^HOME$',
|
|
251
|
+
'^TMPDIR$',
|
|
252
|
+
'^USER$',
|
|
253
|
+
'^PODS_*',
|
|
254
|
+
'^CONFIGURATION_BUILD_DIR$',
|
|
255
|
+
'^UNLOCALIZED_RESOURCES_FOLDER_PATH$',
|
|
218
256
|
];
|
|
219
257
|
Object.entries(process.env).forEach(([key, value]) => {
|
|
220
258
|
if (allowedEnv.some((e) => key.match(e))) {
|
|
@@ -230,7 +268,7 @@ export default function run(program, params = [], platformPrefix = null, target
|
|
|
230
268
|
const value = rest.join('=');
|
|
231
269
|
if (['CFLAGS', 'CXXFLAGS', 'CPPFLAGS', 'LDFLAGS'].includes(key)) {
|
|
232
270
|
let v = value;
|
|
233
|
-
if (v.startsWith('
|
|
271
|
+
if (v.startsWith("'") || v.startsWith('"')) {
|
|
234
272
|
v = v.substring(1, v.length - 1);
|
|
235
273
|
}
|
|
236
274
|
if (env[key]) env[key] += ` ${v}`;
|
|
@@ -264,7 +302,7 @@ export default function run(program, params = [], platformPrefix = null, target
|
|
|
264
302
|
const role = imageRoleFor(target);
|
|
265
303
|
if (state.config.system.RUNNER === 'DOCKER_RUN') {
|
|
266
304
|
imageOrContainer = getDockerImage(role);
|
|
267
|
-
runnerParams = ['run', '--rm', '-v', `${state.config.paths.base}:/tmp/crossbind/live`];
|
|
305
|
+
runnerParams = ['run', '--rm', ...DOCKER_RUN_SECURITY_ARGS, '-v', `${state.config.paths.base}:/tmp/crossbind/live`];
|
|
268
306
|
if (target?.platform === 'android') {
|
|
269
307
|
// Google ships the linux NDK for x86_64 only; use the amd64 leaf ref (classic store holds one platform per digest).
|
|
270
308
|
pullDockerImage(role, 'linux/amd64');
|
|
@@ -280,8 +318,10 @@ export default function run(program, params = [], platformPrefix = null, target
|
|
|
280
318
|
|
|
281
319
|
const args = [
|
|
282
320
|
...runnerParams,
|
|
283
|
-
'--user',
|
|
284
|
-
|
|
321
|
+
'--user',
|
|
322
|
+
getOsUserAndGroupId(),
|
|
323
|
+
'--workdir',
|
|
324
|
+
replaceBasePathForDocker(dockerOptions.workdir || buildPath),
|
|
285
325
|
...replaceBasePathForDocker(dockerEnv),
|
|
286
326
|
// '-e', replaceBasePathForDocker(`CCACHE_DIR=${state.config.paths.build}/ccache`),
|
|
287
327
|
imageOrContainer,
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.0.3",
|
|
3
|
+
"registry": "ghcr.io/crossbind",
|
|
4
|
+
"toolchains": {
|
|
5
|
+
"rust": "1.98.1"
|
|
6
|
+
},
|
|
7
|
+
"images": {
|
|
8
|
+
"rust-sysroot": {
|
|
9
|
+
"index": "sha256:6a5db2ecf54398d837fdbbd8c1f2cdaafd14fd486ac3af4206d21bc9fe66e923",
|
|
10
|
+
"platforms": {
|
|
11
|
+
"linux/arm64": "sha256:b5dbd8b4f233f5d6c0cfe7554b95b412e0e3396d4d4847facf116c155251b0b7",
|
|
12
|
+
"linux/amd64": "sha256:1989d0ab32d2372a2086efe50e33dbb861fa903e451b891f30004e0f172a1a9a"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"base": {
|
|
16
|
+
"index": "sha256:c9b501dca53bc2e51dddd1af64ede75220792e66a47ed488ad6172b58bee1b37",
|
|
17
|
+
"platforms": {
|
|
18
|
+
"linux/arm64": "sha256:edf01f0c4d7fc551e18775e76b2a6c2b9b54075b59f21f7635ccecaebcc6c282",
|
|
19
|
+
"linux/amd64": "sha256:debea6ee164eeba49155ad59365313a9dd291491b3339491a780b46d1b5b96f4"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"web": {
|
|
23
|
+
"index": "sha256:633da840658f12f291c17c3305adf265c7d52307b3b61b84156d5f85f3121779",
|
|
24
|
+
"platforms": {
|
|
25
|
+
"linux/arm64": "sha256:a5fe9f3693d789f04490963afbe80fa71a8ff0d0cc6e442b76ca37492fbf3221",
|
|
26
|
+
"linux/amd64": "sha256:65abff12143740d4557e9cbfd923b6fd6c5d01f25e96a1d27bbad5e083bb9f74"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"android": {
|
|
30
|
+
"index": "sha256:1f415db57ccb57c8850ad4498d9fead35f5104099fd355c067208b2e53c25b23",
|
|
31
|
+
"platforms": {
|
|
32
|
+
"linux/amd64": "sha256:38d7a10c233cfab13adb110383e386e2a649364a8285d6b3ad0696e1e343b58a"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
package/src/utils/binTools.js
CHANGED
|
@@ -74,3 +74,8 @@ export function renderDispatcher(bin) {
|
|
|
74
74
|
'',
|
|
75
75
|
].join('\n');
|
|
76
76
|
}
|
|
77
|
+
|
|
78
|
+
// Under the target build tree, never os.tmpdir(): the containerized compiler only sees paths.base.
|
|
79
|
+
export function multitoolWorkRoot(buildPath, platformPrefix, targetPath) {
|
|
80
|
+
return `${buildPath}/${platformPrefix}/${targetPath}`;
|
|
81
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// Compilation executes project build scripts and third-party toolchains. These flags do not turn
|
|
2
|
+
// Docker into a sandbox, but they remove privileges a compiler does not need. Keep the list shared
|
|
3
|
+
// so the generic command runner and the dedicated cargo runner cannot drift.
|
|
4
|
+
export const DOCKER_RUN_SECURITY_ARGS = Object.freeze(['--cap-drop', 'ALL', '--security-opt', 'no-new-privileges=true']);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getContentHash } from './hash.js';
|
|
2
2
|
|
|
3
3
|
const REPLACE_RECIPE_KEYS = [
|
|
4
|
-
'buildType', 'getURL', 'env', 'copyToSource', 'copyToDist',
|
|
4
|
+
'buildType', 'configureProgram', 'getURL', 'env', 'copyToSource', 'copyToDist',
|
|
5
5
|
'beforeRun', 'useIOSCMake', 'sourceReplaceList', 'getExtraLibs',
|
|
6
6
|
];
|
|
7
7
|
|
|
@@ -1,27 +1,21 @@
|
|
|
1
1
|
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
2
3
|
import { getContentHash } from './hash.js';
|
|
3
4
|
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
amd64: `${REGISTRY}/web@sha256:9010948430c95120b8c19f73377f8684bc6b54e03537790f465237225e48dae2`,
|
|
19
|
-
},
|
|
20
|
-
android: {
|
|
21
|
-
ref: `${REGISTRY}/android@sha256:a3facbf2181f568f12a9fe89054188895665a63e2c147b790fd7e25f3e128ac8`,
|
|
22
|
-
amd64: `${REGISTRY}/android@sha256:4694c6210379a87d8cf0e7f8b56a76a9c74a8724a1aff037c943dcdb521f4de1`,
|
|
23
|
-
},
|
|
24
|
-
};
|
|
5
|
+
// This committed JSON is the one digest table for the CLI, release manifests and release assets.
|
|
6
|
+
// scripts/pin-docker-image.js replaces it from the image workflow's verified `digests` artifact.
|
|
7
|
+
const table = createRequire(import.meta.url)('../assets/toolchain-digests.json');
|
|
8
|
+
const REGISTRY = table.registry;
|
|
9
|
+
const IMAGE_VERSION = table.version;
|
|
10
|
+
const IMAGES = Object.fromEntries(
|
|
11
|
+
['web', 'android'].map((role) => [
|
|
12
|
+
role,
|
|
13
|
+
{
|
|
14
|
+
ref: `${REGISTRY}/${role}@${table.images[role].index}`,
|
|
15
|
+
amd64: `${REGISTRY}/${role}@${table.images[role].platforms['linux/amd64']}`,
|
|
16
|
+
},
|
|
17
|
+
]),
|
|
18
|
+
);
|
|
25
19
|
|
|
26
20
|
const OVERRIDE_KEYS = { web: 'CROSSBIND_IMAGE_WEB', android: 'CROSSBIND_IMAGE_ANDROID' };
|
|
27
21
|
|
package/src/utils/runCargo.js
CHANGED
|
@@ -6,6 +6,7 @@ import state from '../state/index.js';
|
|
|
6
6
|
import getOsUserAndGroupId from './getOsUserAndGroupId.js';
|
|
7
7
|
import replaceBasePathForDockerUtil, { DOCKER_BASE } from './replaceBasePathForDocker.js';
|
|
8
8
|
import pullDockerImage, { getDockerImage, getDockerContainerName, imageRoleFor } from './pullDockerImage.js';
|
|
9
|
+
import { DOCKER_RUN_SECURITY_ARGS } from './dockerSecurity.js';
|
|
9
10
|
|
|
10
11
|
// Every cargo invocation crossbind makes goes through here.
|
|
11
12
|
//
|
|
@@ -28,14 +29,26 @@ const RUSTFLAGS_SEPARATOR = String.fromCharCode(0x1f);
|
|
|
28
29
|
// the compiler - RUSTC_WRAPPER, CARGO_BUILD_RUSTC, CARGO_TARGET_<TRIPLE>_LINKER, RUSTFLAGS,
|
|
29
30
|
// RUSTUP_TOOLCHAIN, RUSTC_BOOTSTRAP - cannot reach cargo from the caller's environment.
|
|
30
31
|
const ALLOWED_ENV = [
|
|
31
|
-
/^PATH$/,
|
|
32
|
-
/^
|
|
33
|
-
/^
|
|
32
|
+
/^PATH$/,
|
|
33
|
+
/^HOME$/,
|
|
34
|
+
/^USER$/,
|
|
35
|
+
/^LOGNAME$/,
|
|
36
|
+
/^SHELL$/,
|
|
37
|
+
/^TERM$/,
|
|
38
|
+
/^TMPDIR$/,
|
|
39
|
+
/^TEMP$/,
|
|
40
|
+
/^TMP$/,
|
|
41
|
+
/^LANG$/,
|
|
42
|
+
/^LC_[A-Z_]+$/,
|
|
34
43
|
/^RUSTUP_HOME$/,
|
|
35
44
|
/^SSH_AUTH_SOCK$/, // git dependencies over ssh
|
|
36
|
-
/^CARGO_NET_/,
|
|
45
|
+
/^CARGO_NET_/,
|
|
46
|
+
/^CARGO_REGISTRIES_/, // offline/vendored builds and private registries
|
|
37
47
|
/^(HTTP|HTTPS|ALL|NO)_PROXY$/i,
|
|
38
|
-
/^SYSTEMROOT$/i,
|
|
48
|
+
/^SYSTEMROOT$/i,
|
|
49
|
+
/^WINDIR$/i,
|
|
50
|
+
/^USERPROFILE$/i,
|
|
51
|
+
/^PROGRAMDATA$/i, // windows cannot spawn without these
|
|
39
52
|
];
|
|
40
53
|
|
|
41
54
|
// Recent cargo applies config.toml only, but the extensionless name is still read by older
|
|
@@ -76,14 +89,18 @@ export function assertCleanConfigChain(home, cwd) {
|
|
|
76
89
|
for (const name of CONFIG_NAMES) {
|
|
77
90
|
const file = path.join(home, name);
|
|
78
91
|
if (fs.existsSync(file)) {
|
|
79
|
-
throw new Error(
|
|
92
|
+
throw new Error(
|
|
93
|
+
`crossbind: unexpected cargo config at ${file} - crossbind owns this CARGO_HOME and never writes one. Remove it and build again.`,
|
|
94
|
+
);
|
|
80
95
|
}
|
|
81
96
|
}
|
|
82
97
|
for (let dir = cwd; ; dir = path.dirname(dir)) {
|
|
83
98
|
for (const name of CONFIG_NAMES) {
|
|
84
99
|
const file = path.join(dir, '.cargo', name);
|
|
85
100
|
if (fs.existsSync(file)) {
|
|
86
|
-
throw new Error(
|
|
101
|
+
throw new Error(
|
|
102
|
+
`crossbind: ${file} would apply to this build - cargo discovers config by walking up from the working directory. crossbind builds from a neutral directory to avoid that; move the file or report this.`,
|
|
103
|
+
);
|
|
87
104
|
}
|
|
88
105
|
}
|
|
89
106
|
if (path.dirname(dir) === dir) return;
|
|
@@ -106,9 +123,7 @@ function allowedEnv() {
|
|
|
106
123
|
return env;
|
|
107
124
|
}
|
|
108
125
|
|
|
109
|
-
function cargoEnv({
|
|
110
|
-
home, rustflags, panic, allowUnstable,
|
|
111
|
-
}) {
|
|
126
|
+
function cargoEnv({ home, rustflags, panic, allowUnstable }) {
|
|
112
127
|
const env = { CARGO_HOME: home };
|
|
113
128
|
// Depth defence: -Z fails with E0554 instead of quietly enabling unstable behaviour. The value
|
|
114
129
|
// -1 disables unstable features on EVERY channel, nightly included, so the one caller that
|
|
@@ -131,6 +146,7 @@ function createHint(name, base, home, image) {
|
|
|
131
146
|
return [
|
|
132
147
|
'Create it with:',
|
|
133
148
|
` docker run -d --name ${name} \\`,
|
|
149
|
+
` ${DOCKER_RUN_SECURITY_ARGS.join(' ')} \\`,
|
|
134
150
|
` -v ${base}:${DOCKER_BASE} \\`,
|
|
135
151
|
` -v ${home}:${CONTAINER_CARGO_HOME} \\`,
|
|
136
152
|
` ${image} sleep infinity`,
|
|
@@ -138,7 +154,13 @@ function createHint(name, base, home, image) {
|
|
|
138
154
|
}
|
|
139
155
|
|
|
140
156
|
function samePath(a, b) {
|
|
141
|
-
const real = (p) => {
|
|
157
|
+
const real = (p) => {
|
|
158
|
+
try {
|
|
159
|
+
return fs.realpathSync(p);
|
|
160
|
+
} catch {
|
|
161
|
+
return path.resolve(p);
|
|
162
|
+
}
|
|
163
|
+
};
|
|
142
164
|
return real(a) === real(b);
|
|
143
165
|
}
|
|
144
166
|
|
|
@@ -152,13 +174,20 @@ function assertExecContainer(name, base, home, image) {
|
|
|
152
174
|
throw new Error(`crossbind: RUNNER=DOCKER_EXEC needs a container named '${name}', which does not exist.\n${hint}`);
|
|
153
175
|
}
|
|
154
176
|
if (!info?.State?.Running) {
|
|
155
|
-
throw new Error(
|
|
177
|
+
throw new Error(
|
|
178
|
+
`crossbind: the container '${name}' exists but is not running. Start it with \`docker start ${name}\`, or recreate it.\n${hint}`,
|
|
179
|
+
);
|
|
156
180
|
}
|
|
157
|
-
for (const [destination, source] of [
|
|
181
|
+
for (const [destination, source] of [
|
|
182
|
+
[DOCKER_BASE, base],
|
|
183
|
+
[CONTAINER_CARGO_HOME, home],
|
|
184
|
+
]) {
|
|
158
185
|
const mount = (info.Mounts ?? []).find((m) => m.Destination === destination);
|
|
159
186
|
if (!mount || !samePath(mount.Source, source)) {
|
|
160
187
|
const found = mount ? ` - it mounts ${mount.Source} there` : '';
|
|
161
|
-
throw new Error(
|
|
188
|
+
throw new Error(
|
|
189
|
+
`crossbind: the container '${name}' does not mount ${source} at ${destination}${found}. It predates the cargo mount, so recreate it.\n${hint}`,
|
|
190
|
+
);
|
|
162
191
|
}
|
|
163
192
|
}
|
|
164
193
|
// `docker run --workdir` creates the directory; `docker exec --workdir` does not, and cargo
|
|
@@ -170,9 +199,7 @@ function assertExecContainer(name, base, home, image) {
|
|
|
170
199
|
}
|
|
171
200
|
}
|
|
172
201
|
|
|
173
|
-
export default function runCargo(args, {
|
|
174
|
-
cwd, rustflags = [], panic, capture = false, maxBuffer, allowUnstable = false, target,
|
|
175
|
-
} = {}) {
|
|
202
|
+
export default function runCargo(args, { cwd, rustflags = [], panic, capture = false, maxBuffer, allowUnstable = false, target } = {}) {
|
|
176
203
|
const home = cargoHome();
|
|
177
204
|
const workdir = cwd ?? neutralCwd();
|
|
178
205
|
fs.mkdirSync(home, { recursive: true });
|
|
@@ -200,7 +227,10 @@ export default function runCargo(args, {
|
|
|
200
227
|
// Only what cargo needs travels in: the image already carries PATH, RUSTUP_HOME and the
|
|
201
228
|
// toolchain, and the host's PATH would be meaningless there.
|
|
202
229
|
const env = cargoEnv({
|
|
203
|
-
home: CONTAINER_CARGO_HOME,
|
|
230
|
+
home: CONTAINER_CARGO_HOME,
|
|
231
|
+
rustflags,
|
|
232
|
+
panic,
|
|
233
|
+
allowUnstable,
|
|
204
234
|
});
|
|
205
235
|
const envArgs = Object.entries(env).flatMap(([key, value]) => ['-e', `${key}=${value}`]);
|
|
206
236
|
|
|
@@ -208,20 +238,25 @@ export default function runCargo(args, {
|
|
|
208
238
|
if (runner === 'DOCKER_EXEC') {
|
|
209
239
|
const name = getDockerContainerName(base, role);
|
|
210
240
|
assertExecContainer(name, base, home, getDockerImage(role, platform));
|
|
211
|
-
runnerArgs = ['exec', ...envArgs,
|
|
212
|
-
'--user', getOsUserAndGroupId(),
|
|
213
|
-
'--workdir', CONTAINER_CWD,
|
|
214
|
-
name];
|
|
241
|
+
runnerArgs = ['exec', ...envArgs, '--user', getOsUserAndGroupId(), '--workdir', CONTAINER_CWD, name];
|
|
215
242
|
} else {
|
|
216
243
|
pullDockerImage(role, platform);
|
|
217
|
-
runnerArgs = [
|
|
244
|
+
runnerArgs = [
|
|
245
|
+
'run',
|
|
246
|
+
'--rm',
|
|
218
247
|
...(platform ? ['--platform', platform] : []),
|
|
219
|
-
|
|
220
|
-
'-v',
|
|
248
|
+
...DOCKER_RUN_SECURITY_ARGS,
|
|
249
|
+
'-v',
|
|
250
|
+
`${base}:${DOCKER_BASE}`,
|
|
251
|
+
'-v',
|
|
252
|
+
`${home}:${CONTAINER_CARGO_HOME}`,
|
|
221
253
|
...envArgs,
|
|
222
|
-
'--user',
|
|
223
|
-
|
|
224
|
-
|
|
254
|
+
'--user',
|
|
255
|
+
getOsUserAndGroupId(),
|
|
256
|
+
'--workdir',
|
|
257
|
+
CONTAINER_CWD,
|
|
258
|
+
getDockerImage(role, platform),
|
|
259
|
+
];
|
|
225
260
|
}
|
|
226
261
|
|
|
227
262
|
return spawnSync('docker', [...runnerArgs, 'cargo', ...replaceBasePathForDockerUtil(args, base)], options);
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
// Generated by scripts/pin-rust-sysroot.js - do not edit by hand.
|
|
2
|
-
//
|
|
3
1
|
// The published sysroot image a host build (RUNNER=LOCAL) reads its Rust sysroots out of - the same
|
|
4
2
|
// object the web image embeds, not a repackaged copy, so the two channels cannot drift. The index
|
|
5
3
|
// digest is the whole contract: the loader verifies the index body against it, then each descriptor
|
|
6
4
|
// inside a verified body authenticates the next fetch, down to the layer.
|
|
5
|
+
import { createRequire } from 'node:module';
|
|
6
|
+
|
|
7
|
+
const table = createRequire(import.meta.url)('../assets/toolchain-digests.json');
|
|
8
|
+
const sysroot = table.images['rust-sysroot'];
|
|
9
|
+
|
|
7
10
|
export default {
|
|
8
|
-
version:
|
|
9
|
-
image:
|
|
10
|
-
index:
|
|
11
|
+
version: table.version,
|
|
12
|
+
image: `${table.registry}/rust-sysroot`,
|
|
13
|
+
index: sysroot.index,
|
|
11
14
|
};
|
|
@@ -25,3 +25,16 @@ export function writeSourceFingerprint(libdir, fingerprint) {
|
|
|
25
25
|
fs.mkdirSync(libdir, { recursive: true });
|
|
26
26
|
fs.writeFileSync(`${libdir}/${SOURCE_FINGERPRINT_FILE}`, fingerprint);
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
// A changed upstream release leaves the previous configure output and install tree behind. Reusing
|
|
30
|
+
// them makes `make install` fail where it cannot chmod a file it did not create, and would leave
|
|
31
|
+
// files of the old version in the output next to the new ones.
|
|
32
|
+
export function staleTargetDirectories({ buildPath, outputPath, targetPath }) {
|
|
33
|
+
return [
|
|
34
|
+
`${buildPath}/Source-Release/${targetPath}`,
|
|
35
|
+
`${buildPath}/Source-Release/prebuilt/${targetPath}`,
|
|
36
|
+
`${buildPath}/Source-Debug/${targetPath}`,
|
|
37
|
+
`${buildPath}/Source-Debug/prebuilt/${targetPath}`,
|
|
38
|
+
`${outputPath}/prebuilt/${targetPath}`,
|
|
39
|
+
];
|
|
40
|
+
}
|