Skip to content
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

Support Visual Studio 2017 and 2019 #2

Merged
merged 5 commits into from Aug 11, 2020

Conversation

DeeDeeG
Copy link
Member

@DeeDeeG DeeDeeG commented Aug 10, 2020

Description of the Change

Main change:

  • Detect Visual Studio 2017 and 2019

Related changes:

  • Stop detecting unsupported versions, which node-gyp refuses to use (Visual Studio 2010 - 2013)
  • Don't set the --msvs_version node-gyp flag, which sets a specific version of Visual Studio that node-gyp must find, or else it will error out.
    • Our detection for actually-working Visual Studio installs is substantially worse than node-gyp's. We should let them detect and use whatever usable version of Visual Studio they can find.
Explanation (click to expand):

Builds on apm's existing code to detect installs of Visual Studio, by adding the ability to detect Visual Studio 2017 and 2019.

Those versions of Visual Studio are now fully supported in the version of node-gyp we use (node-gyp@5).

As of node-gyp PR nodejs/node-gyp#1762, node-gyp is much better than us at finding Visual Studio installs and identifying whether on not they can be used. This isn't a simple matter of having Visual Studio or not, but also various components must be installed.

Given that our detection is worse, I have made it so apm no-longer sets the --msvs_version flag. This flag forces node-gyp to use the specified major version of Visual Studio/Build Tools. It can only restrict node-gyp within usable installs. There is no scenario where setting this causes any benefit to us. But if we get it wrong (and our detection is worse, so we very likely would), this can cause node-gyp to refuse to use a valid Visual Studio/Build Tools install and error out.

Alternate Designs

This, but with some of the changes reverted/taken out.

All commits in this PR are designed to be logical choices that are well-backed-up by the explanation and reasoning given.

That said, the commits are in order of how radical the change is, or how controversial I thought the change might be. If any of the commits/changes are objectionable, please let me know, and the rest of the PR still makes sense without that change. This is a few related changes bundled together, but any of the three bullet points is a positive step in the right direction, and works independent of the other two bullet points.

Benefits

  • Lets apm and node-gyp use Visual Studio 2017 and 2019, even if 2015 or older is also installed
  • Stops causing errors for our users, such as by rejecting Visual Studio 2017 and 2019 if a buggy 2015 or earlier install is the first one found
  • Gets out of the way of a critical dependency detection task that node-gyp is doing better than us at
  • More successful package builds, more happy customers?
  • Keeps up with the latest Visual Studio major versions we support (via node-gyp).

Possible Drawbacks

None that I am aware of. Before this PR, we have been artificially limiting how good a job node-gyp could do to find Visual Studio, in certain cases. Now, with this PR, we stop doing that.

Reaching for a hypothetical problem: I suppose if Visual Studio 2017 or 2019 are buggy, this exposes our users to that. (In my experience, VS 2017 and 2019 are not buggy.)

Verification Process

Lengthy "Verification Process" section contents (click to expand):

This un-blocks apm from using a correctly-detected, working install of Visual Studio 2019 in (forked) Atom's CI.

Breakdown of the "Before" case: The issue in this case was that apm detected an install of 2015 that turned out to be unusable. The error is: "could not find MSBuild in registry for this version". At the bottom of the error message, a message points out that 2019 would have been a valid version, had we allowed node-gyp to use it:

gyp ERR! find VS valid versions for msvs_version:
gyp ERR! find VS - "2019"
gyp ERR! find VS - "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise"

Furthermore, apm --version can now find Visual Studio 2017 and 2019.

Before and after on the same machine, with Visual Studio 2019 Community installed:

Before:
C:\Users\[User]\>apm-dev --version
apm  2.5.0
npm  6.14.5
node 10.20.1 x64
atom 1.50.0-dev-110b05baf
python 2.7.18
git 2.27.0.windows.1
visual studio
After:
C:\Users\[User]>apm-dev --version
apm  2.5.0
npm  6.14.5
node 10.20.1 x64
atom 1.51.0-dev-912dad331
python 2.7.18
git 2.27.0.windows.1
visual studio 2019

Note that Visual Studio 2019 is detected: visual studio 2019 (on the bottom line of output from apm --version).

Here's the before and after on another machine, this time with Visual Studio 2017:

Before
C:\Users\[User]>apm-dev --version
apm  2.5.0
npm  6.14.5
node 10.20.1 x64
atom 1.50.0-dev-9c16e5c67
python 2.7.18
git 2.27.0.windows.1
visual studio
After
C:\Users\[User]>apm-dev --version
apm  2.5.0
npm  6.14.5
node 10.20.1 x64
atom 1.51.0-dev-912dad331
python 2.7.18
git 2.27.0.windows.1
visual studio 2017

Note that Visual Studio 2017 is detected: visual studio 2017 (on the bottom line of output from apm --version).

Applicable Issues

Upstream PR: atom#892

Fixes atom#893

These are supported in `node-gyp@5`, which we now use.

We should be able to detect these versions to set the `--msvs_version`
node-gyp flag correctly.

The default install path structure is different starting
with Visual Studio 2017.

e.g. C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\IDE
Older versions have only one path to check,
whereas starting with Visual Studio/C++ Build Tools 2017,
multiple distinct install directories exist (one per edition).

i.e. Community, Professional, Enterprise, Build Tools, and Express.

Conditioning these path checks by version
can reduce the filesystem reads (in the worst-case scenario) by 22.
node-gyp v5 refuses to use any Visual Studio older than 2013.
With Node >= 8, node-gyp v5 also refuses to use Visual Studio 2013.

We bundle and enforce the use of Node 10 now, eventually even newer.

Therefore, with versions of Visual Studio < 2015 not usable,
we shouldn't detect them or have apm/node-gyp attempt to use them.

(This also saves up to 3 filesystem reads.)
In modern node-gyp, this flag only serves to limit
node-gyp to using a specific version of Visual Studio.

It can't make node-gyp find a version it wouldn't have found.

Our checks are much less sophisticated at detecting usable
installations of Visual Studio. We should let node-gyp
use the install of Visual Studio/Build Tools it thinks is best.

It will pick any usable Visual Studio install, preferring the newest
if multiple are installed and usable. It generally will not pick one
mistakenly that it actually can't use.

Given that the stakes are "we might prevent a valid installation
of Visual Studio from being used," and there is no benefit to be had,
this flag should not be set.
@DeeDeeG DeeDeeG added this to In progress in 2.6.x Aug 10, 2020
@DeeDeeG
Copy link
Member Author

DeeDeeG commented Aug 11, 2020

This and the "Node 12.0.0" PR are copied exactly from the upstream PRs.

@aminya
Copy link
Member

aminya commented Aug 11, 2020

As a general Note: when writing draw-backs, if it doesn't have one, it is better to write nothing and don't make an illusion that this PR has a drawback by explaining why it does not! This explanation is usually destructive rather constructive. Move the discussion about the rationale to the description instead.

From my experience, I see that people are too picky about this part of the description. Just move the information to the description and people will feel better!

@aminya aminya merged commit 003e6cf into master Aug 11, 2020
2.6.x automation moved this from In progress to Done Aug 11, 2020
@DeeDeeG
Copy link
Member Author

DeeDeeG commented Aug 11, 2020

Yes. I think you are right, sadly. (Or not sadly, if I think about it.)

The instinct to self-review is to show I take contributing changes to upstream seriously, and have considered the ramifications. Then I am so conservative about my changes that there are usually no downsides! So I can't project all this concern and caution when there isn't much reason to feel that way from the code being suggested.

I have to strike a balance, or put "none" and let reviewers see if they feel there is a downside. A middle ground option would be to hold back some of the verbosity here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
2.6.x
  
Done
2 participants