From fb147126e8458683b3e554a3fa2b530df35bd7d3 Mon Sep 17 00:00:00 2001 From: Jeremy Rifkin <51220084+jeremy-rifkin@users.noreply.github.com> Date: Sat, 16 Sep 2023 15:59:26 -0400 Subject: [PATCH] Fix WSL for systems that don't have windows paths (#5480) Attempt to fix #5476. As far as I can tell `process.env.winTmp` is needed just for windows executables and WslVcCompiler. It should be possible to just ignore the exec error and continue. If for some reason the user doesn't have windows paths in their WSL but does want to run windows executables they can pass `-tmpDir`. --- app.ts | 12 ++++++++---- docs/WindowsSubsystemForLinux.md | 3 ++- lib/compilers/wsl-vc.ts | 2 +- lib/exec.ts | 3 ++- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/app.ts b/app.ts index f018f64e9..cff90c01c 100755 --- a/app.ts +++ b/app.ts @@ -156,10 +156,14 @@ if (opts.tmpDir) { } else if (process.env.wsl) { // Dec 2017 preview builds of WSL include /bin/wslpath; do the parsing work for now. // Parsing example %TEMP% is C:\Users\apardoe\AppData\Local\Temp - const windowsTemp = child_process.execSync('cmd.exe /c echo %TEMP%').toString().replaceAll('\\', '/'); - const driveLetter = windowsTemp.substring(0, 1).toLowerCase(); - const directoryPath = windowsTemp.substring(2).trim(); - process.env.winTmp = path.join('/mnt', driveLetter, directoryPath); + try { + const windowsTemp = child_process.execSync('cmd.exe /c echo %TEMP%').toString().replaceAll('\\', '/'); + const driveLetter = windowsTemp.substring(0, 1).toLowerCase(); + const directoryPath = windowsTemp.substring(2).trim(); + process.env.winTmp = path.join('/mnt', driveLetter, directoryPath); + } catch (e) { + logger.warn('Unable to invoke cmd.exe to get windows %TEMP% path.'); + } } const distPath = utils.resolvePathFromAppRoot('.'); diff --git a/docs/WindowsSubsystemForLinux.md b/docs/WindowsSubsystemForLinux.md index 694146fec..5686bae4d 100644 --- a/docs/WindowsSubsystemForLinux.md +++ b/docs/WindowsSubsystemForLinux.md @@ -69,7 +69,8 @@ CE only required a few changes in order to run properly under WSL. Those changes WSL distros as they all run on the base Microsoft Linux kernel. - If the `-tmpDir` option is specified on the command line, both `process.env.tmpDir` and `process.env.winTmp` are set to the specified value Note that if this is specified as a non-Windows volume, Windows executables will fail to run - properly. Otherwise, `process.env.winTmp` is set to the value of the Windows `%TEMP%` directory. + properly. Otherwise, `process.env.winTmp` is set to the value of the Windows `%TEMP%` directory if CE can get the + temp path from invoking `cmd.exe` from WSL. - `lib/exec.js`: Execute the compiler in the temporary directory. If the compiler's binary is located on a mounted volume (`startsWith("/mnt"`)) and CE is running under WSL, run the compiler in the `winTmp` directory. Otherwise, use the Linux temp directory. diff --git a/lib/compilers/wsl-vc.ts b/lib/compilers/wsl-vc.ts index df465d06f..1908cb05f 100644 --- a/lib/compilers/wsl-vc.ts +++ b/lib/compilers/wsl-vc.ts @@ -60,7 +60,7 @@ export class WslVcCompiler extends Win32VcCompiler { // NPM temp package: https://www.npmjs.com/package/temp, see Affixes override newTempDir() { return new Promise((resolve, reject) => { - temp.mkdir({prefix: 'compiler-explorer-compiler', dir: process.env.winTmp}, (err, dirPath) => { + temp.mkdir({prefix: 'compiler-explorer-compiler', dir: unwrap(process.env.winTmp)}, (err, dirPath) => { if (err) reject(`Unable to open temp file: ${err}`); else resolve(dirPath); }); diff --git a/lib/exec.ts b/lib/exec.ts index d784bf447..27bf2c0c0 100644 --- a/lib/exec.ts +++ b/lib/exec.ts @@ -78,7 +78,8 @@ export function executeDirect( let okToCache = true; let timedOut = false; const cwd = - options.customCwd || (command.startsWith('/mnt') && process.env.wsl ? process.env.winTmp : process.env.tmpDir); + options.customCwd || + (command.startsWith('/mnt') && process.env.wsl && process.env.winTmp ? process.env.winTmp : process.env.tmpDir); logger.debug('Execution', {type: 'executing', command: command, args: args, env: env, cwd: cwd}); const startTime = process.hrtime.bigint();