Skip to content

Commit fb8f589

Browse files
committed
lib: create a Python symlink and add it to PATH
Helps to ensure a version of Python validated by lib/find-python.js is used to run various Python scripts generated by gyp. Known to affect gyp-mac-tool, probably affects gyp-flock-tool as well. These Python scripts (such as `gyp-mac-tool`) are invoked directly, via the generated Makefile, so their shebang lines determine which Python binary is used to run them. The shebang lines of these scripts are all `#!/usr/bin/env python3`, so the first `python3` on the user's PATH will be used. By adding a symlink to the Python binary validated by find-python.js, and putting this symlink first on the PATH, we can ensure we use a compatible version of Python to run these scripts. (Only on Unix/Unix-like OSes. Symlinks are tricky on Windows, and Python isn't used at build-time anyhow on Windows, so this intervention isn't useful or necessary on Windows. A similar technique for Windows, no symlinks required, would be to make batch scripts which execute the target binary, much like what Node does for its bundled copy of npm on Windows.)
1 parent 4b83c3d commit fb8f589

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

lib/build.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,13 @@ function build (gyp, argv, callback) {
185185
}
186186
}
187187

188+
if (!win) {
189+
// Add build-time dependency symlinks (such as Python) to PATH
190+
const buildBinsDir = path.resolve('build', 'node_gyp_bins')
191+
process.env.PATH = `${buildBinsDir}:${process.env.PATH}`
192+
log.verbose('bin symlinks', `adding symlinks (such as Python), at "${buildBinsDir}", to PATH`)
193+
}
194+
188195
var proc = gyp.spawn(command, argv)
189196
proc.on('exit', onExit)
190197
}

lib/configure.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ if (win) {
1616
function configure (gyp, argv, callback) {
1717
var python
1818
var buildDir = path.resolve('build')
19+
var buildBinsDir = path.join(buildDir, 'node_gyp_bins')
1920
var configNames = ['config.gypi', 'common.gypi']
2021
var configs = []
2122
var nodeDir
@@ -72,7 +73,9 @@ function configure (gyp, argv, callback) {
7273

7374
function createBuildDir () {
7475
log.verbose('build dir', 'attempting to create "build" dir: %s', buildDir)
75-
fs.mkdir(buildDir, { recursive: true }, function (err, isNew) {
76+
77+
const deepestBuildDirSubdirectory = win ? buildDir : buildBinsDir
78+
fs.mkdir(deepestBuildDirSubdirectory, { recursive: true }, function (err, isNew) {
7679
if (err) {
7780
return callback(err)
7881
}
@@ -81,11 +84,22 @@ function configure (gyp, argv, callback) {
8184
findVisualStudio(release.semver, gyp.opts.msvs_version,
8285
createConfigFile)
8386
} else {
87+
createPythonSymlink()
8488
createConfigFile()
8589
}
8690
})
8791
}
8892

93+
function createPythonSymlink () {
94+
const symlinkDestination = path.join(buildBinsDir, 'python3')
95+
96+
log.verbose('python symlink', `creating symlink to "${python}" at "${symlinkDestination}"`)
97+
98+
fs.unlink(symlinkDestination, function () {
99+
fs.symlink(python, symlinkDestination, function () {})
100+
})
101+
}
102+
89103
function createConfigFile (err, vsInfo) {
90104
if (err) {
91105
return callback(err)

0 commit comments

Comments
 (0)