Skip to content

Commit 3a9aa80

Browse files
committed
editors/vscode: added patchelf after download
1 parent a4e6963 commit 3a9aa80

File tree

1 file changed

+48
-1
lines changed

1 file changed

+48
-1
lines changed

editors/code/src/main.ts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as vscode from 'vscode';
22
import * as path from "path";
33
import * as os from "os";
4-
import { promises as fs } from "fs";
4+
import { promises as fs, PathLike } from "fs";
55

66
import * as commands from './commands';
77
import { activateInlayHints } from './inlay_hints';
@@ -12,6 +12,7 @@ import { log, assert, isValidExecutable } from './util';
1212
import { PersistentState } from './persistent_state';
1313
import { fetchRelease, download } from './net';
1414
import { activateTaskProvider } from './tasks';
15+
import { exec } from 'child_process';
1516

1617
let ctx: Ctx | undefined;
1718

@@ -188,6 +189,46 @@ async function bootstrapServer(config: Config, state: PersistentState): Promise<
188189
return path;
189190
}
190191

192+
async function patchelf(dest: PathLike): Promise<void> {
193+
await vscode.window.withProgress(
194+
{
195+
location: vscode.ProgressLocation.Notification,
196+
title: "Patching rust-analysis for NixOS"
197+
},
198+
async (progress, _) => {
199+
let patch_path = path.join(os.tmpdir(), "patch-ra.nix")
200+
progress.report({message: "Writing nix file", increment: 5})
201+
await fs.writeFile(patch_path, `
202+
{src, pkgs ? import <nixpkgs> {}}:
203+
pkgs.stdenv.mkDerivation {
204+
name = "rust-analyzer";
205+
inherit src;
206+
phases = [ "installPhase" "fixupPhase" ];
207+
installPhase = "cp $src $out";
208+
fixupPhase = ''
209+
chmod 755 $out
210+
patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out
211+
'';
212+
}
213+
`)
214+
let orig_file = dest + "-orig"
215+
await fs.rename(dest, orig_file)
216+
progress.report({message: "Patching executable", increment: 20})
217+
await new Promise((resolve, reject) => {
218+
exec(`nix-build ${patch_path} --arg src '${orig_file}' -o ${dest}`,
219+
(err, stdout, stderr) => {
220+
if (err != null) {
221+
reject(Error(stderr))
222+
} else {
223+
resolve(stdout)
224+
}
225+
})
226+
})
227+
// await fs.unlink(orig_file)
228+
}
229+
)
230+
}
231+
191232
async function getServer(config: Config, state: PersistentState): Promise<string | undefined> {
192233
const explicitPath = process.env.__RA_LSP_SERVER_DEBUG ?? config.serverPath;
193234
if (explicitPath) {
@@ -237,6 +278,12 @@ async function getServer(config: Config, state: PersistentState): Promise<string
237278
assert(!!artifact, `Bad release: ${JSON.stringify(release)}`);
238279

239280
await download(artifact.browser_download_url, dest, "Downloading rust-analyzer server", { mode: 0o755 });
281+
282+
// Patching executable if that's NixOS.
283+
if (fs.stat("/etc/nixos").then(_ => true).catch(_ => false)) {
284+
await patchelf(dest)
285+
}
286+
240287
await state.updateServerVersion(config.package.version);
241288
return dest;
242289
}

0 commit comments

Comments
 (0)