-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Python symlink to path (for non-Windows OSes only) #2362
Conversation
Hi folks, just wanted to mention the other solution I found for fixing this bug. It involves patching See this commit at my fork for the alternative fix: DeeDeeG@a68d184 Weighing the pros and cons of this alternate approach. (Click to expand)Pros:
Cons:
I am open to either approach, but this PR currently has the solution that is the more general one (no need to patch each individual generator, just set the environment up the way we want and it all works after that), and one which is easier to land without considering implications for Also, I can acknowledge that being "surgically precise" also means getting more of the precise details right, as opposed to throwing the desired Python on the PATH and being done. I also would want this to be better tested on SmartOS and AIX. I am not aware of a way to test on AIX. Testing on SmartOS is a pain, but doable in VirtualBox if I get some time. (Overall I'm leaning toward the symlinks, which is why I submitted that approach in this PR.) |
I added a couple of commits just now to pare down redundant information in the warning output and improve its formatting. (Although, of course, in most cases I expect there will be no warnings at all.) Before (click to expand)
After (click to expand)
(These example warnings were generated by changing the owner of the symlink to I don't want these warnings to be too scary or attract too much attention in case we go on to successfully build the module. I just want them to be there to let folks know what's going on behind the scenes, and in case of an eventual build failure along the lines of #2351. |
Questions for reviewers:
I have gone with
I noticed that the Implementation ideas:
|
I'd stick with rimraf, symlinks in windows are finicky at best so I'd go for the solution that has worked so far. |
Update: A quick microbenchmark shows that loading and using @imatlopez thanks for the feedback. But this PR isn't doing symlinks on Windows, only on other OSes. More on why symlinks are weird on Windows, but this is a bit off-topicYeah, I agree symlinks on Windows are weird from what I've heard. And they require Administrator permissions or a special "Developer Mode" toggle in the Settings app, so the vast majority of people probably can't use symlinks on Windows. |
But in new tests in #2254 ( |
@cclauss @gengjiawen this would help users with Python 3.5 or older first on the PATH and newer Python 3.x located somewhere else. (Debian 9 users maybe?) (Without this PR, for those users, Thoughts? Please take a look, thank you. |
Please fix the conflicts. Our minimum Python is now 3.7 in alignment with README.md and https://devguide.python.org/#status-of-python-branches. How does this code ensure we are not building a symlink to an invalid I like this approach because it is JavaScript-based. We improve maintainability when we remove Python code from gyp. |
That is a matter handled in (This PR makes a symlink to whatever copy of Python Edit: On another note, merge conflicts are fixed. |
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.)
Add missing functions "unlink()" and "symlink()" to mocked module.
Warn users about errors, but continue on in case the user does happen to have new enough Python on their PATH. (The symlinks are only meant to fix an issue in a corner case, where the user told `node-gyp` where new enough Python is, but it's not the first `python3` on their PATH. We should not introduce a new potential failure mode to all users when fixing this bug. So no hard errors during the symlink process.)
Logging the entire error object shows the stack twice, and all the other information is contained in the stack. It also messes with the order of what is logged. Rather than logging a bunch of redundant information in a messy way, we can log only the stack. Logging it in a separate log.warn() also gets rid of an extra space character at the beginning of the line.
This info (err.errno) is the only piece of information in the error object that is not redundant to err.stack.
These messages aren't important enough to be `log.warn`s. Log as verbose only; they will also appear in full error output.
e3de45d
to
54328e1
Compare
Checklist
npm install && npm test
passesDescription of change
An attempt to fix #2351 for the rest of users not yet addressed by #2355.
lib/find-python.js
atbuild/node_gyp_bins/python3
build/node_gyp_bins
to thePATH
just before buildingbuild/gyp-mac-tool
orbuild/gyp-flock-tool
) will be run with the Python binary validated bylib/find-python.js
More notes/thoughts/explanation
The corner case/bug is not applicable to Windows. So this PR changes nothing on Windows.
This PR changes nothing on Windows. The bug being fixed is Not Applicable to Windows; There are no Python scripts to run at build time on Windows, per my testing, nor as far as I can deduce from research.
(If someone can prove that there are ever Python scripts at build-time on Windows, or the maintainers prefer to do something on Windows just in case, I can work on a solution involving writing a batch script to
build/node_gyp_bins/python3.bat
that runs the validated Python binary fromlib/find-python.js
. That should work just as well. Non-administrator users cannot create symlinks by default on Windows, so in my opinion we can't rely on symlinks on Windows. But again, I don't think there's any Python to run during the build phase on Windows. So this all should be moot!)Who is this for?
Specifically, folks with older or somehow invalid
python3
(< 3.6) first on theirPATH
, who have nevertheless managed to supply a newer, valid Python binary tonode-gyp
, probably by command-line--python=/some/python3
or as an env varPYTHON=/some/python3
.(Note that Debian Jessie and Stretch, as well as Ubuntu Xenial all ship
python3
older than 3.6. Perhaps these users will get newer Python3 and opt not to put it early on the PATH?)What does this PR achieve? A user with older Python on their PATH who manages to supply a valid Python version to
node-gyp
and make it through the configure stage (includinglib/find-python.js
) should not abruptly hit errors at the build stage. This PR aims to solve that corner case. (See: #2351 for details.)Where did the idea come from? This was inspired by the approach that
nodejs/node
takes when setting up the build for NodeJS itself. Seeconfigure.py
at that repository: