@git.zone/tsrust 1.3.3 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.smartconfig.json +9 -5
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/index.d.ts +1 -0
- package/dist_ts/index.js +2 -1
- package/dist_ts/mod_cargo/classes.cargorunner.d.ts +1 -0
- package/dist_ts/mod_cargo/classes.cargorunner.js +10 -3
- package/dist_ts/mod_cli/classes.tsrustcli.js +55 -5
- package/dist_ts/mod_elf/classes.elfinspector.d.ts +8 -0
- package/dist_ts/mod_elf/classes.elfinspector.js +43 -0
- package/dist_ts/mod_elf/index.d.ts +1 -0
- package/dist_ts/mod_elf/index.js +2 -0
- package/package.json +14 -14
- package/readme.md +35 -3
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/index.ts +1 -0
- package/ts/mod_cargo/classes.cargorunner.ts +11 -3
- package/ts/mod_cli/classes.tsrustcli.ts +61 -4
- package/ts/mod_elf/classes.elfinspector.ts +52 -0
- package/ts/mod_elf/index.ts +1 -0
package/.smartconfig.json
CHANGED
|
@@ -19,11 +19,15 @@
|
|
|
19
19
|
]
|
|
20
20
|
},
|
|
21
21
|
"release": {
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
"targets": {
|
|
23
|
+
"npm": {
|
|
24
|
+
"registries": [
|
|
25
|
+
"https://verdaccio.lossless.digital",
|
|
26
|
+
"https://registry.npmjs.org"
|
|
27
|
+
],
|
|
28
|
+
"accessLevel": "public"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
27
31
|
}
|
|
28
32
|
}
|
|
29
33
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@git.zone/tsrust',
|
|
6
|
-
version: '1.
|
|
6
|
+
version: '1.4.1',
|
|
7
7
|
description: 'A tool for compiling Rust projects, detecting Cargo workspaces, building with cargo, and placing binaries in a conventional dist_rust directory.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxrQkFBa0I7SUFDeEIsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLGtKQUFrSjtDQUNoSyxDQUFBIn0=
|
package/dist_ts/index.d.ts
CHANGED
package/dist_ts/index.js
CHANGED
|
@@ -3,6 +3,7 @@ plugins.early.start('@git.zone/tsrust');
|
|
|
3
3
|
export * from './mod_fs/index.js';
|
|
4
4
|
export * from './mod_cargo/index.js';
|
|
5
5
|
export * from './mod_cli/index.js';
|
|
6
|
+
export * from './mod_elf/index.js';
|
|
6
7
|
export * from './mod_toolchain/index.js';
|
|
7
8
|
plugins.early.stop();
|
|
8
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0FBRXhDLGNBQWMsbUJBQW1CLENBQUM7QUFDbEMsY0FBYyxzQkFBc0IsQ0FBQztBQUNyQyxjQUFjLG9CQUFvQixDQUFDO0FBQ25DLGNBQWMsb0JBQW9CLENBQUM7QUFDbkMsY0FBYywwQkFBMEIsQ0FBQztBQUV6QyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDIn0=
|
|
@@ -23,13 +23,20 @@ export class CargoRunner {
|
|
|
23
23
|
console.log('Cleaning previous build...');
|
|
24
24
|
await this.clean();
|
|
25
25
|
}
|
|
26
|
+
// crt-static may only be injected together with an explicit --target:
|
|
27
|
+
// without one, cargo applies RUSTFLAGS to host artifacts too, and rustc
|
|
28
|
+
// cannot build proc-macros with +crt-static on linux-gnu.
|
|
29
|
+
if (options.crtStatic && !options.target) {
|
|
30
|
+
throw new Error('crtStatic requires an explicit target');
|
|
31
|
+
}
|
|
26
32
|
if (options.target) {
|
|
27
33
|
await this.ensureTarget(options.target);
|
|
28
34
|
}
|
|
29
35
|
const profile = options.debug ? '' : ' --release';
|
|
30
36
|
const targetFlag = options.target ? ` --target ${options.target}` : '';
|
|
31
|
-
const
|
|
32
|
-
|
|
37
|
+
const rustflagsPrefix = options.crtStatic ? 'RUSTFLAGS="-C target-feature=+crt-static" ' : '';
|
|
38
|
+
const command = `${this.envPrefix}cd ${this.rustDir} && ${rustflagsPrefix}cargo build${profile}${targetFlag}`;
|
|
39
|
+
console.log(`Running: ${rustflagsPrefix}cargo build${profile}${targetFlag}`);
|
|
33
40
|
const result = await this.shell.exec(command);
|
|
34
41
|
return {
|
|
35
42
|
success: result.exitCode === 0,
|
|
@@ -62,4 +69,4 @@ export class CargoRunner {
|
|
|
62
69
|
};
|
|
63
70
|
}
|
|
64
71
|
}
|
|
65
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
72
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5jYXJnb3J1bm5lci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL21vZF9jYXJnby9jbGFzc2VzLmNhcmdvcnVubmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBUXpDLE1BQU0sT0FBTyxXQUFXO0lBQ2QsS0FBSyxDQUFnQztJQUNyQyxPQUFPLENBQVM7SUFDaEIsU0FBUyxDQUFTO0lBRTFCLFlBQVksT0FBZSxFQUFFLFlBQW9CLEVBQUU7UUFDakQsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFDM0IsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLE9BQU8sQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDO1lBQzdDLFFBQVEsRUFBRSxNQUFNO1NBQ2pCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTSxLQUFLLENBQUMsbUJBQW1CO1FBQzlCLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxpQkFBaUIsQ0FBQyxDQUFDO1FBQy9FLE9BQU8sTUFBTSxDQUFDLFFBQVEsS0FBSyxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVNLEtBQUssQ0FBQyxlQUFlO1FBQzFCLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxpQkFBaUIsQ0FBQyxDQUFDO1FBQy9FLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUM5QixDQUFDO0lBRU0sS0FBSyxDQUFDLEtBQUssQ0FBQyxVQUFzRixFQUFFO1FBQ3pHLElBQUksT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2xCLE9BQU8sQ0FBQyxHQUFHLENBQUMsNEJBQTRCLENB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
|
|
@@ -2,6 +2,7 @@ import * as path from 'path';
|
|
|
2
2
|
import * as plugins from '../plugins.js';
|
|
3
3
|
import { CargoConfig } from '../mod_cargo/index.js';
|
|
4
4
|
import { CargoRunner } from '../mod_cargo/index.js';
|
|
5
|
+
import { ElfInspector } from '../mod_elf/index.js';
|
|
5
6
|
import { FsHelpers } from '../mod_fs/index.js';
|
|
6
7
|
import { ToolchainManager } from '../mod_toolchain/index.js';
|
|
7
8
|
/** Maps friendly target names to Rust target triples */
|
|
@@ -36,6 +37,13 @@ function friendlyName(triple) {
|
|
|
36
37
|
// Derive from triple: e.g. x86_64-unknown-linux-gnu → x86_64_unknown_linux_gnu
|
|
37
38
|
return triple.replace(/-/g, '_');
|
|
38
39
|
}
|
|
40
|
+
/** crt-static injection only applies to glibc targets; musl is static by default. */
|
|
41
|
+
function wantsCrtStatic(triple) {
|
|
42
|
+
return triple.endsWith('-linux-gnu');
|
|
43
|
+
}
|
|
44
|
+
function isLinuxTriple(triple) {
|
|
45
|
+
return triple.includes('-linux-');
|
|
46
|
+
}
|
|
39
47
|
export class TsRustCli {
|
|
40
48
|
cli;
|
|
41
49
|
cwd;
|
|
@@ -103,6 +111,10 @@ export class TsRustCli {
|
|
|
103
111
|
const targets = cliTargets
|
|
104
112
|
? (Array.isArray(cliTargets) ? cliTargets : [cliTargets])
|
|
105
113
|
: this.config.targets || [];
|
|
114
|
+
const useStatic = !!argvArg.static || !!this.config.static;
|
|
115
|
+
if (useStatic) {
|
|
116
|
+
console.log('Static linking enabled (crt-static for linux-gnu targets)');
|
|
117
|
+
}
|
|
106
118
|
if (targets.length > 0) {
|
|
107
119
|
// Cross-compilation mode
|
|
108
120
|
const resolvedTargets = targets.map((t) => ({
|
|
@@ -113,8 +125,16 @@ export class TsRustCli {
|
|
|
113
125
|
await FsHelpers.ensureEmptyDir(distDir);
|
|
114
126
|
for (const { triple, friendly } of resolvedTargets) {
|
|
115
127
|
console.log(`\n--- Building for ${friendly} (${triple}) ---`);
|
|
128
|
+
if (useStatic && !isLinuxTriple(triple)) {
|
|
129
|
+
console.log(`Note: static linking is not applicable for ${triple}; building with default linkage.`);
|
|
130
|
+
}
|
|
116
131
|
const cargoRunner = new CargoRunner(rustDir, envPrefix);
|
|
117
|
-
const buildResult = await cargoRunner.build({
|
|
132
|
+
const buildResult = await cargoRunner.build({
|
|
133
|
+
debug: isDebug,
|
|
134
|
+
clean: shouldClean,
|
|
135
|
+
target: triple,
|
|
136
|
+
crtStatic: useStatic && wantsCrtStatic(triple),
|
|
137
|
+
});
|
|
118
138
|
if (!buildResult.success) {
|
|
119
139
|
console.error(`Build failed for target ${triple} with exit code ${buildResult.exitCode}`);
|
|
120
140
|
process.exit(1);
|
|
@@ -133,6 +153,13 @@ export class TsRustCli {
|
|
|
133
153
|
await FsHelpers.makeExecutable(destBinary);
|
|
134
154
|
const size = await FsHelpers.getFileSize(destBinary);
|
|
135
155
|
console.log(`Copied ${binName} (${FsHelpers.formatFileSize(size)}) -> dist_rust/${destName}`);
|
|
156
|
+
if (useStatic && isLinuxTriple(triple)) {
|
|
157
|
+
if (!(await ElfInspector.isStaticElf(destBinary))) {
|
|
158
|
+
console.error(`Error: ${destName} is not statically linked (PT_INTERP present) although static linking was requested.`);
|
|
159
|
+
process.exit(1);
|
|
160
|
+
}
|
|
161
|
+
console.log(`Verified statically linked: dist_rust/${destName}`);
|
|
162
|
+
}
|
|
136
163
|
}
|
|
137
164
|
// Only clean on first iteration
|
|
138
165
|
if (shouldClean) {
|
|
@@ -141,14 +168,30 @@ export class TsRustCli {
|
|
|
141
168
|
}
|
|
142
169
|
}
|
|
143
170
|
else {
|
|
144
|
-
// Native build
|
|
171
|
+
// Native build. When static linking is requested, build with an
|
|
172
|
+
// explicit host --target so RUSTFLAGS never reach host artifacts
|
|
173
|
+
// (proc-macros cannot build with +crt-static on linux-gnu).
|
|
174
|
+
let nativeTriple;
|
|
175
|
+
if (useStatic) {
|
|
176
|
+
nativeTriple = new ToolchainManager().getHostTriple();
|
|
177
|
+
if (!isLinuxTriple(nativeTriple)) {
|
|
178
|
+
console.log(`Note: static linking is not applicable for ${nativeTriple}; building with default linkage.`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
145
181
|
const cargoRunner = new CargoRunner(rustDir, envPrefix);
|
|
146
|
-
const buildResult = await cargoRunner.build({
|
|
182
|
+
const buildResult = await cargoRunner.build({
|
|
183
|
+
debug: isDebug,
|
|
184
|
+
clean: shouldClean,
|
|
185
|
+
target: nativeTriple,
|
|
186
|
+
crtStatic: !!nativeTriple && wantsCrtStatic(nativeTriple),
|
|
187
|
+
});
|
|
147
188
|
if (!buildResult.success) {
|
|
148
189
|
console.error(`Build failed with exit code ${buildResult.exitCode}`);
|
|
149
190
|
process.exit(1);
|
|
150
191
|
}
|
|
151
|
-
const targetDir =
|
|
192
|
+
const targetDir = nativeTriple
|
|
193
|
+
? path.join(rustDir, 'target', nativeTriple, profile)
|
|
194
|
+
: path.join(rustDir, 'target', profile);
|
|
152
195
|
await FsHelpers.ensureEmptyDir(distDir);
|
|
153
196
|
for (const binName of workspaceInfo.binTargets) {
|
|
154
197
|
const srcBinary = path.join(targetDir, binName);
|
|
@@ -161,6 +204,13 @@ export class TsRustCli {
|
|
|
161
204
|
await FsHelpers.makeExecutable(destBinary);
|
|
162
205
|
const size = await FsHelpers.getFileSize(destBinary);
|
|
163
206
|
console.log(`Copied ${binName} (${FsHelpers.formatFileSize(size)}) -> dist_rust/${binName}`);
|
|
207
|
+
if (useStatic && nativeTriple && isLinuxTriple(nativeTriple)) {
|
|
208
|
+
if (!(await ElfInspector.isStaticElf(destBinary))) {
|
|
209
|
+
console.error(`Error: ${binName} is not statically linked (PT_INTERP present) although static linking was requested.`);
|
|
210
|
+
process.exit(1);
|
|
211
|
+
}
|
|
212
|
+
console.log(`Verified statically linked: dist_rust/${binName}`);
|
|
213
|
+
}
|
|
164
214
|
}
|
|
165
215
|
}
|
|
166
216
|
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
@@ -208,4 +258,4 @@ export const runCli = async () => {
|
|
|
208
258
|
const cli = new TsRustCli();
|
|
209
259
|
cli.run();
|
|
210
260
|
};
|
|
211
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy50c3J1c3RjbGkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9tb2RfY2xpL2NsYXNzZXMudHNydXN0Y2xpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDcEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRTdELHdEQUF3RDtBQUN4RCxNQUFNLGNBQWMsR0FBMkI7SUFDN0MsV0FBVyxFQUFFLDBCQUEwQjtJQUN2QyxXQUFXLEVBQUUsMkJBQTJCO0lBQ3hDLGdCQUFnQixFQUFFLDJCQUEyQjtJQUM3QyxnQkFBZ0IsRUFBRSw0QkFBNEI7SUFDOUMsV0FBVyxFQUFFLHFCQUFxQjtJQUNsQyxXQUFXLEVBQUUsc0JBQXNCO0NBQ3BDLENBQUM7QUFFRiwrQ0FBK0M7QUFDL0MsTUFBTSxtQkFBbUIsR0FBMkIsRUFBRSxDQUFDO0FBQ3ZELEtBQUssTUFBTSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUM7SUFDaEUsbUJBQW1CLENBQUMsTUFBTSxDQUFDLEdBQUcsUUFBUSxDQUFDO0FBQ3pDLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFTLGtCQUFrQixDQUFDLElBQVk7SUFDdEMsT0FBTyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDO0FBQ3RDLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFTLFlBQVksQ0FBQyxNQUFjO0lBQ2xDLElBQUksbUJB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
|
|
261
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy50c3J1c3RjbGkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9tb2RfY2xpL2NsYXNzZXMudHNydXN0Y2xpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDcEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUMvQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUU3RCx3REFBd0Q7QUFDeEQsTUFBTSxjQUFjLEdBQTJCO0lBQzdDLFdBQVcsRUFBRSwwQkFBMEI7SUFDdkMsV0FBVyxFQUFFLDJCQUEyQjtJQUN4QyxnQkFBZ0IsRUFBRSwyQkFBMkI7SUFDN0MsZ0JBQWdCLEVBQUUsNEJBQTRCO0lBQzlDLFdBQVcsRUFBRSxxQkFBcUI7SUFDbEMsV0FBVyxFQUFFLHNCQUFzQjtDQUNwQyxDQUFDO0FBRUYsK0NBQStDO0FBQy9DLE1BQU0sbUJBQW1CLEdBQTJCLEVBQUUsQ0FBQztBQUN2RCxLQUFLLE1BQU0sQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDO0lBQ2hFLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQztBQUN6QyxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBUyxrQkFBa0IsQ0FBQyxJQUFZO0lBQ3RDLE9BQU8sY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQztBQUN0QyxDQUFDO0FBRUQ7OztH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
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare class ElfInspector {
|
|
2
|
+
/**
|
|
3
|
+
* Returns true when the ELF binary has no PT_INTERP program header, i.e. it
|
|
4
|
+
* is statically linked (including static-pie). Works for foreign
|
|
5
|
+
* architectures since only headers are parsed. Throws for non-ELF files.
|
|
6
|
+
*/
|
|
7
|
+
static isStaticElf(filePath: string): Promise<boolean>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
const ELF_MAGIC = 0x7f454c46;
|
|
3
|
+
const PT_INTERP = 3;
|
|
4
|
+
export class ElfInspector {
|
|
5
|
+
/**
|
|
6
|
+
* Returns true when the ELF binary has no PT_INTERP program header, i.e. it
|
|
7
|
+
* is statically linked (including static-pie). Works for foreign
|
|
8
|
+
* architectures since only headers are parsed. Throws for non-ELF files.
|
|
9
|
+
*/
|
|
10
|
+
static async isStaticElf(filePath) {
|
|
11
|
+
const fileHandle = await fs.promises.open(filePath, 'r');
|
|
12
|
+
try {
|
|
13
|
+
const header = Buffer.alloc(64);
|
|
14
|
+
await fileHandle.read(header, 0, header.length, 0);
|
|
15
|
+
if (header.readUInt32BE(0) !== ELF_MAGIC) {
|
|
16
|
+
throw new Error(`Not an ELF binary: ${filePath}`);
|
|
17
|
+
}
|
|
18
|
+
const is64 = header[4] === 2;
|
|
19
|
+
const isLittleEndian = header[5] === 1;
|
|
20
|
+
const readU16 = (buf, offset) => isLittleEndian ? buf.readUInt16LE(offset) : buf.readUInt16BE(offset);
|
|
21
|
+
const readU32 = (buf, offset) => isLittleEndian ? buf.readUInt32LE(offset) : buf.readUInt32BE(offset);
|
|
22
|
+
const readU64 = (buf, offset) => isLittleEndian ? buf.readBigUInt64LE(offset) : buf.readBigUInt64BE(offset);
|
|
23
|
+
const phOffset = is64 ? Number(readU64(header, 0x20)) : readU32(header, 0x1c);
|
|
24
|
+
const phEntrySize = is64 ? readU16(header, 0x36) : readU16(header, 0x2a);
|
|
25
|
+
const phCount = is64 ? readU16(header, 0x38) : readU16(header, 0x2c);
|
|
26
|
+
if (phOffset === 0 || phEntrySize === 0 || phCount === 0) {
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
const table = Buffer.alloc(phEntrySize * phCount);
|
|
30
|
+
await fileHandle.read(table, 0, table.length, phOffset);
|
|
31
|
+
for (let i = 0; i < phCount; i++) {
|
|
32
|
+
if (readU32(table, i * phEntrySize) === PT_INTERP) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
await fileHandle.close();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5lbGZpbnNwZWN0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9tb2RfZWxmL2NsYXNzZXMuZWxmaW5zcGVjdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBRXpCLE1BQU0sU0FBUyxHQUFHLFVBQVUsQ0FBQztBQUM3QixNQUFNLFNBQVMsR0FBRyxDQUFDLENBQUM7QUFFcEIsTUFBTSxPQUFPLFlBQVk7SUFDdkI7Ozs7T0FJRztJQUNJLE1BQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLFFBQWdCO1FBQzlDLE1BQU0sVUFBVSxHQUFHLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3pELElBQUksQ0FBQztZQUNILE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDaEMsTUFBTSxVQUFVLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztZQUVuRCxJQUFJLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3pDLE1BQU0sSUFBSSxLQUFLLENBQUMsc0JBQXNCLFFBQVEsRUFBRSxDQUFDLENBQUM7WUFDcEQsQ0FBQztZQUVELE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDN0IsTUFBTSxjQUFjLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN2QyxNQUFNLE9BQU8sR0FBRyxDQUFDLEdBQVcsRUFBRSxNQUFjLEVBQUUsRUFBRSxDQUM5QyxjQUFjLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdkUsTUFBTSxPQUFPLEdBQUcsQ0FBQyxHQUFXLEVBQUUsTUFBYyxFQUFFLEVBQUUsQ0FDOUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3ZFLE1BQU0sT0FBTyxHQUFHLENBQUMsR0FBVyxFQUFFLE1BQWMsRUFBRSxFQUFFLENBQzlDLGNBQWMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUU3RSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDOUUsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ3pFLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztZQUVyRSxJQUFJLFFBQVEsS0FBSyxDQUFDLElBQUksV0FBVyxLQUFLLENBQUMsSUFBSSxPQUFPLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ3pELE9BQU8sSUFBSSxDQUFDO1lBQ2QsQ0FBQztZQUVELE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxDQUFDO1lBQ2xELE1BQU0sVUFBVSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFFeEQsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUNqQyxJQUFJLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxLQUFLLFNBQVMsRUFBRSxDQUFDO29CQUNsRCxPQUFPLEtBQUssQ0FBQztnQkFDZixDQUFDO1lBQ0gsQ0FBQztZQUNELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztnQkFBUyxDQUFDO1lBQ1QsTUFBTSxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDM0IsQ0FBQztJQUNILENBQUM7Q0FDRiJ9
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ElfInspector } from './classes.elfinspector.js';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { ElfInspector } from './classes.elfinspector.js';
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9tb2RfZWxmL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQyJ9
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@git.zone/tsrust",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A tool for compiling Rust projects, detecting Cargo workspaces, building with cargo, and placing binaries in a conventional dist_rust directory.",
|
|
6
6
|
"main": "dist_ts/index.js",
|
|
@@ -9,10 +9,6 @@
|
|
|
9
9
|
"bin": {
|
|
10
10
|
"tsrust": "./cli.js"
|
|
11
11
|
},
|
|
12
|
-
"scripts": {
|
|
13
|
-
"test": "tstest test/test.ts --verbose",
|
|
14
|
-
"build": "tsbuild --web"
|
|
15
|
-
},
|
|
16
12
|
"repository": {
|
|
17
13
|
"type": "git",
|
|
18
14
|
"url": "https://code.foss.global/git.zone/tsrust.git"
|
|
@@ -34,18 +30,18 @@
|
|
|
34
30
|
"homepage": "https://code.foss.global/git.zone/tsrust#README",
|
|
35
31
|
"dependencies": {
|
|
36
32
|
"@push.rocks/early": "^4.0.4",
|
|
37
|
-
"@push.rocks/smartcli": "^4.0.
|
|
38
|
-
"@push.rocks/smartconfig": "^6.
|
|
39
|
-
"@push.rocks/smartfile": "^13.1.
|
|
33
|
+
"@push.rocks/smartcli": "^4.0.21",
|
|
34
|
+
"@push.rocks/smartconfig": "^6.1.1",
|
|
35
|
+
"@push.rocks/smartfile": "^13.1.3",
|
|
40
36
|
"@push.rocks/smartpath": "^6.0.0",
|
|
41
37
|
"@push.rocks/smartshell": "^3.3.8",
|
|
42
38
|
"smol-toml": "^1.6.1"
|
|
43
39
|
},
|
|
44
40
|
"devDependencies": {
|
|
45
|
-
"@git.zone/tsbuild": "^4.4.
|
|
46
|
-
"@git.zone/tsrun": "^2.0.
|
|
47
|
-
"@git.zone/tstest": "^3.
|
|
48
|
-
"@types/node": "^25.
|
|
41
|
+
"@git.zone/tsbuild": "^4.4.2",
|
|
42
|
+
"@git.zone/tsrun": "^2.0.4",
|
|
43
|
+
"@git.zone/tstest": "^3.6.6",
|
|
44
|
+
"@types/node": "^25.9.1"
|
|
49
45
|
},
|
|
50
46
|
"files": [
|
|
51
47
|
"ts/**/*",
|
|
@@ -59,5 +55,9 @@
|
|
|
59
55
|
],
|
|
60
56
|
"browserslist": [
|
|
61
57
|
"last 1 chrome versions"
|
|
62
|
-
]
|
|
63
|
-
|
|
58
|
+
],
|
|
59
|
+
"scripts": {
|
|
60
|
+
"test": "tstest test/test.ts --verbose",
|
|
61
|
+
"build": "tsbuild --web"
|
|
62
|
+
}
|
|
63
|
+
}
|
package/readme.md
CHANGED
|
@@ -8,16 +8,16 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
|
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
11
|
-
Install globally
|
|
11
|
+
Install globally with pnpm:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
|
|
14
|
+
pnpm add -g @git.zone/tsrust
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
Or as a project-level dev dependency:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
pnpm
|
|
20
|
+
pnpm add --save-dev @git.zone/tsrust
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
> ⚡ **No Rust required!** If `cargo` isn't found on your system, `tsrust` automatically downloads and installs a minimal Rust toolchain to `/tmp/tsrust_toolchain/`. This gives a zero-setup experience. If you already have Rust installed, `tsrust` uses your system toolchain.
|
|
@@ -145,6 +145,38 @@ You can set default cross-compilation targets in your project's `.smartconfig.js
|
|
|
145
145
|
|
|
146
146
|
When targets are configured in `.smartconfig.json`, simply running `tsrust` will cross-compile for all listed targets. CLI `--target` flags take full precedence — if any `--target` is provided, the `.smartconfig.json` targets are ignored entirely.
|
|
147
147
|
|
|
148
|
+
### Static Linking
|
|
149
|
+
|
|
150
|
+
`tsrust` can produce fully statically linked Linux binaries (static-pie) that run on both glibc distros (Debian/Ubuntu) and musl distros (Alpine). Enable it via `.smartconfig.json`:
|
|
151
|
+
|
|
152
|
+
```json
|
|
153
|
+
{
|
|
154
|
+
"@git.zone/tsrust": {
|
|
155
|
+
"targets": ["linux_amd64", "linux_arm64"],
|
|
156
|
+
"static": true
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Or per invocation with the `--static` flag:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
tsrust --static
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Behavior per target:
|
|
168
|
+
|
|
169
|
+
- `*-linux-gnu`: `tsrust` injects `RUSTFLAGS="-C target-feature=+crt-static"` into its cargo invocation.
|
|
170
|
+
- `*-linux-musl`: already statically linked by default; no flags are injected.
|
|
171
|
+
- `*-apple-darwin`: full static linking is not applicable on macOS; the target builds with default linkage.
|
|
172
|
+
|
|
173
|
+
After the build, `tsrust` verifies every Linux binary in `dist_rust/` is actually statically linked (no `PT_INTERP` ELF program header — the check is architecture-independent, so cross-compiled binaries are verified too) and fails the build otherwise.
|
|
174
|
+
|
|
175
|
+
Why `tsrust` injects the flag instead of the project setting `rustflags` in `rust/.cargo/config.toml`:
|
|
176
|
+
|
|
177
|
+
- `tsrust` always builds with an explicit `--target`, so the flag never applies to host artifacts. A repo-wide `rustflags` entry also applies to proc-macros and build scripts whenever cargo runs *without* `--target` (plain `cargo test`, `cargo check`, rust-analyzer) — and rustc cannot build proc-macros with `+crt-static` on linux-gnu, breaking those commands.
|
|
178
|
+
- Keep `rust/.cargo/config.toml` free of `rustflags` when using `static` — the injected `RUSTFLAGS` environment variable *replaces* any config-file `rustflags` (cargo does not merge them). `linker` entries (e.g. for aarch64 cross-compilation) are unaffected and should stay.
|
|
179
|
+
|
|
148
180
|
### 🗑️ Clean Only
|
|
149
181
|
|
|
150
182
|
Remove all build artifacts without rebuilding:
|
package/ts/00_commitinfo_data.ts
CHANGED
package/ts/index.ts
CHANGED
|
@@ -29,21 +29,29 @@ export class CargoRunner {
|
|
|
29
29
|
return result.stdout.trim();
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
public async build(options: { debug?: boolean; clean?: boolean; target?: string } = {}): Promise<ICargoRunResult> {
|
|
32
|
+
public async build(options: { debug?: boolean; clean?: boolean; target?: string; crtStatic?: boolean } = {}): Promise<ICargoRunResult> {
|
|
33
33
|
if (options.clean) {
|
|
34
34
|
console.log('Cleaning previous build...');
|
|
35
35
|
await this.clean();
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
// crt-static may only be injected together with an explicit --target:
|
|
39
|
+
// without one, cargo applies RUSTFLAGS to host artifacts too, and rustc
|
|
40
|
+
// cannot build proc-macros with +crt-static on linux-gnu.
|
|
41
|
+
if (options.crtStatic && !options.target) {
|
|
42
|
+
throw new Error('crtStatic requires an explicit target');
|
|
43
|
+
}
|
|
44
|
+
|
|
38
45
|
if (options.target) {
|
|
39
46
|
await this.ensureTarget(options.target);
|
|
40
47
|
}
|
|
41
48
|
|
|
42
49
|
const profile = options.debug ? '' : ' --release';
|
|
43
50
|
const targetFlag = options.target ? ` --target ${options.target}` : '';
|
|
44
|
-
const
|
|
51
|
+
const rustflagsPrefix = options.crtStatic ? 'RUSTFLAGS="-C target-feature=+crt-static" ' : '';
|
|
52
|
+
const command = `${this.envPrefix}cd ${this.rustDir} && ${rustflagsPrefix}cargo build${profile}${targetFlag}`;
|
|
45
53
|
|
|
46
|
-
console.log(`Running: cargo build${profile}${targetFlag}`);
|
|
54
|
+
console.log(`Running: ${rustflagsPrefix}cargo build${profile}${targetFlag}`);
|
|
47
55
|
const result = await this.shell.exec(command);
|
|
48
56
|
|
|
49
57
|
return {
|
|
@@ -2,6 +2,7 @@ import * as path from 'path';
|
|
|
2
2
|
import * as plugins from '../plugins.js';
|
|
3
3
|
import { CargoConfig } from '../mod_cargo/index.js';
|
|
4
4
|
import { CargoRunner } from '../mod_cargo/index.js';
|
|
5
|
+
import { ElfInspector } from '../mod_elf/index.js';
|
|
5
6
|
import { FsHelpers } from '../mod_fs/index.js';
|
|
6
7
|
import { ToolchainManager } from '../mod_toolchain/index.js';
|
|
7
8
|
|
|
@@ -43,6 +44,16 @@ function friendlyName(triple: string): string {
|
|
|
43
44
|
|
|
44
45
|
interface ITsrustConfig {
|
|
45
46
|
targets?: string[];
|
|
47
|
+
static?: boolean;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** crt-static injection only applies to glibc targets; musl is static by default. */
|
|
51
|
+
function wantsCrtStatic(triple: string): boolean {
|
|
52
|
+
return triple.endsWith('-linux-gnu');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function isLinuxTriple(triple: string): boolean {
|
|
56
|
+
return triple.includes('-linux-');
|
|
46
57
|
}
|
|
47
58
|
|
|
48
59
|
export class TsRustCli {
|
|
@@ -128,6 +139,11 @@ export class TsRustCli {
|
|
|
128
139
|
? (Array.isArray(cliTargets) ? cliTargets : [cliTargets])
|
|
129
140
|
: this.config.targets || [];
|
|
130
141
|
|
|
142
|
+
const useStatic = !!(argvArg as any).static || !!this.config.static;
|
|
143
|
+
if (useStatic) {
|
|
144
|
+
console.log('Static linking enabled (crt-static for linux-gnu targets)');
|
|
145
|
+
}
|
|
146
|
+
|
|
131
147
|
if (targets.length > 0) {
|
|
132
148
|
// Cross-compilation mode
|
|
133
149
|
const resolvedTargets = targets.map((t: string) => ({
|
|
@@ -141,8 +157,16 @@ export class TsRustCli {
|
|
|
141
157
|
|
|
142
158
|
for (const { triple, friendly } of resolvedTargets) {
|
|
143
159
|
console.log(`\n--- Building for ${friendly} (${triple}) ---`);
|
|
160
|
+
if (useStatic && !isLinuxTriple(triple)) {
|
|
161
|
+
console.log(`Note: static linking is not applicable for ${triple}; building with default linkage.`);
|
|
162
|
+
}
|
|
144
163
|
const cargoRunner = new CargoRunner(rustDir, envPrefix);
|
|
145
|
-
const buildResult = await cargoRunner.build({
|
|
164
|
+
const buildResult = await cargoRunner.build({
|
|
165
|
+
debug: isDebug,
|
|
166
|
+
clean: shouldClean,
|
|
167
|
+
target: triple,
|
|
168
|
+
crtStatic: useStatic && wantsCrtStatic(triple),
|
|
169
|
+
});
|
|
146
170
|
|
|
147
171
|
if (!buildResult.success) {
|
|
148
172
|
console.error(`Build failed for target ${triple} with exit code ${buildResult.exitCode}`);
|
|
@@ -167,6 +191,14 @@ export class TsRustCli {
|
|
|
167
191
|
|
|
168
192
|
const size = await FsHelpers.getFileSize(destBinary);
|
|
169
193
|
console.log(`Copied ${binName} (${FsHelpers.formatFileSize(size)}) -> dist_rust/${destName}`);
|
|
194
|
+
|
|
195
|
+
if (useStatic && isLinuxTriple(triple)) {
|
|
196
|
+
if (!(await ElfInspector.isStaticElf(destBinary))) {
|
|
197
|
+
console.error(`Error: ${destName} is not statically linked (PT_INTERP present) although static linking was requested.`);
|
|
198
|
+
process.exit(1);
|
|
199
|
+
}
|
|
200
|
+
console.log(`Verified statically linked: dist_rust/${destName}`);
|
|
201
|
+
}
|
|
170
202
|
}
|
|
171
203
|
|
|
172
204
|
// Only clean on first iteration
|
|
@@ -175,16 +207,33 @@ export class TsRustCli {
|
|
|
175
207
|
}
|
|
176
208
|
}
|
|
177
209
|
} else {
|
|
178
|
-
// Native build
|
|
210
|
+
// Native build. When static linking is requested, build with an
|
|
211
|
+
// explicit host --target so RUSTFLAGS never reach host artifacts
|
|
212
|
+
// (proc-macros cannot build with +crt-static on linux-gnu).
|
|
213
|
+
let nativeTriple: string | undefined;
|
|
214
|
+
if (useStatic) {
|
|
215
|
+
nativeTriple = new ToolchainManager().getHostTriple();
|
|
216
|
+
if (!isLinuxTriple(nativeTriple)) {
|
|
217
|
+
console.log(`Note: static linking is not applicable for ${nativeTriple}; building with default linkage.`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
179
221
|
const cargoRunner = new CargoRunner(rustDir, envPrefix);
|
|
180
|
-
const buildResult = await cargoRunner.build({
|
|
222
|
+
const buildResult = await cargoRunner.build({
|
|
223
|
+
debug: isDebug,
|
|
224
|
+
clean: shouldClean,
|
|
225
|
+
target: nativeTriple,
|
|
226
|
+
crtStatic: !!nativeTriple && wantsCrtStatic(nativeTriple),
|
|
227
|
+
});
|
|
181
228
|
|
|
182
229
|
if (!buildResult.success) {
|
|
183
230
|
console.error(`Build failed with exit code ${buildResult.exitCode}`);
|
|
184
231
|
process.exit(1);
|
|
185
232
|
}
|
|
186
233
|
|
|
187
|
-
const targetDir =
|
|
234
|
+
const targetDir = nativeTriple
|
|
235
|
+
? path.join(rustDir, 'target', nativeTriple, profile)
|
|
236
|
+
: path.join(rustDir, 'target', profile);
|
|
188
237
|
|
|
189
238
|
await FsHelpers.ensureEmptyDir(distDir);
|
|
190
239
|
|
|
@@ -202,6 +251,14 @@ export class TsRustCli {
|
|
|
202
251
|
|
|
203
252
|
const size = await FsHelpers.getFileSize(destBinary);
|
|
204
253
|
console.log(`Copied ${binName} (${FsHelpers.formatFileSize(size)}) -> dist_rust/${binName}`);
|
|
254
|
+
|
|
255
|
+
if (useStatic && nativeTriple && isLinuxTriple(nativeTriple)) {
|
|
256
|
+
if (!(await ElfInspector.isStaticElf(destBinary))) {
|
|
257
|
+
console.error(`Error: ${binName} is not statically linked (PT_INTERP present) although static linking was requested.`);
|
|
258
|
+
process.exit(1);
|
|
259
|
+
}
|
|
260
|
+
console.log(`Verified statically linked: dist_rust/${binName}`);
|
|
261
|
+
}
|
|
205
262
|
}
|
|
206
263
|
}
|
|
207
264
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
|
|
3
|
+
const ELF_MAGIC = 0x7f454c46;
|
|
4
|
+
const PT_INTERP = 3;
|
|
5
|
+
|
|
6
|
+
export class ElfInspector {
|
|
7
|
+
/**
|
|
8
|
+
* Returns true when the ELF binary has no PT_INTERP program header, i.e. it
|
|
9
|
+
* is statically linked (including static-pie). Works for foreign
|
|
10
|
+
* architectures since only headers are parsed. Throws for non-ELF files.
|
|
11
|
+
*/
|
|
12
|
+
public static async isStaticElf(filePath: string): Promise<boolean> {
|
|
13
|
+
const fileHandle = await fs.promises.open(filePath, 'r');
|
|
14
|
+
try {
|
|
15
|
+
const header = Buffer.alloc(64);
|
|
16
|
+
await fileHandle.read(header, 0, header.length, 0);
|
|
17
|
+
|
|
18
|
+
if (header.readUInt32BE(0) !== ELF_MAGIC) {
|
|
19
|
+
throw new Error(`Not an ELF binary: ${filePath}`);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const is64 = header[4] === 2;
|
|
23
|
+
const isLittleEndian = header[5] === 1;
|
|
24
|
+
const readU16 = (buf: Buffer, offset: number) =>
|
|
25
|
+
isLittleEndian ? buf.readUInt16LE(offset) : buf.readUInt16BE(offset);
|
|
26
|
+
const readU32 = (buf: Buffer, offset: number) =>
|
|
27
|
+
isLittleEndian ? buf.readUInt32LE(offset) : buf.readUInt32BE(offset);
|
|
28
|
+
const readU64 = (buf: Buffer, offset: number) =>
|
|
29
|
+
isLittleEndian ? buf.readBigUInt64LE(offset) : buf.readBigUInt64BE(offset);
|
|
30
|
+
|
|
31
|
+
const phOffset = is64 ? Number(readU64(header, 0x20)) : readU32(header, 0x1c);
|
|
32
|
+
const phEntrySize = is64 ? readU16(header, 0x36) : readU16(header, 0x2a);
|
|
33
|
+
const phCount = is64 ? readU16(header, 0x38) : readU16(header, 0x2c);
|
|
34
|
+
|
|
35
|
+
if (phOffset === 0 || phEntrySize === 0 || phCount === 0) {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const table = Buffer.alloc(phEntrySize * phCount);
|
|
40
|
+
await fileHandle.read(table, 0, table.length, phOffset);
|
|
41
|
+
|
|
42
|
+
for (let i = 0; i < phCount; i++) {
|
|
43
|
+
if (readU32(table, i * phEntrySize) === PT_INTERP) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return true;
|
|
48
|
+
} finally {
|
|
49
|
+
await fileHandle.close();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ElfInspector } from './classes.elfinspector.js';
|