Skip to content
This repository has been archived by the owner on Dec 15, 2022. It is now read-only.

Better Support for Visual Studio 2017 and 2019 #892

Merged
merged 4 commits into from Jan 29, 2021

Conversation

DeeDeeG
Copy link
Contributor

@DeeDeeG DeeDeeG commented Jul 15, 2020

Requirements

  • Filling out the template is required. Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion.
  • All new code requires tests to ensure against regressions

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

Fixes #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
Copy link
Contributor Author

DeeDeeG commented Jul 15, 2020

cc @darangi, @lkashef, @aminya so this is on your radar.

@DeeDeeG DeeDeeG changed the title Support Visual Studio 2017 and 2019 Btetter Support for Visual Studio 2017 and 2019 Aug 24, 2020
@DeeDeeG DeeDeeG changed the title Btetter Support for Visual Studio 2017 and 2019 Better Support for Visual Studio 2017 and 2019 Aug 24, 2020
@DeeDeeG
Copy link
Contributor Author

DeeDeeG commented Aug 24, 2020

More research to confirm this PR is the right approach:

atom/flight-manual.atom.io#630 (comment)

Conclusions:

  • Visual Studio 2015 works with all npm versions. (But with npm older than 6.10.1, you must do npm config set msvs_version=2015, OR in your environment variables set GYP_MSVS_VERSION=2015.)
  • Visual Studio 2017 works with npm 4.5.0 or newer, no environment variable or config setting needed.
  • Visual Studio 2019 works with npm 6.10.1 or newer, no environment variable or config settings needed.

We bundle/use the latest npm (npm 6.14.x), which is more than new enough to pick a Visual Studio installation automatically.

aminya added a commit to atom-community/atom that referenced this pull request Sep 24, 2020
Windows-build-tools v4 (which is an old unmainteind version) installs 
Visual Studio 2015. But we can use the pre-installed 2017 in 
vs2017-win2016

Requires atom/apm#892
aminya added a commit to atom-community/atom that referenced this pull request Sep 24, 2020
Windows-build-tools v4 (which is an old unmaintaind version) installs 
Visual Studio 2015. But we can use the pre-installed 2017 in 
vs2017-win2016

Requires atom/apm#892
@aminya
Copy link
Contributor

aminya commented Sep 24, 2020

I created a PR for atom which depends on this.
atom/atom#21379

@aminya
Copy link
Contributor

aminya commented Nov 26, 2020

@sadick254 @darangi Will this ever be merged? I was interested in improving superstring, but it is not worth it without using std=C++17.

@DeeDeeG
Copy link
Contributor Author

DeeDeeG commented Nov 28, 2020

I hope this helps with reviewing this Pull Request; To summarize what this Pull Request does, here is the behavior before and after:

Before:

  • apm checks on the disk for Visual Studio install folders, doing a so-so job detecting which Visual Studio version is installed
    • Picks the newest one out of 2015, 2013, 2012 and 2010
    • Forces that version to be used
    • If none of the above are detected, apm gives up trying to force a version

(This behavior was helpful way back years ago, with what are now very old versions of npm, but it isn't useful anymore, and hard-coding the wrong (too old) Visual Studio versions makes this worse than doing nothing. Modern npm/node-gyp do a really good job of picking a working copy of Visual Studio, so IMO we should just get out of the way and let node-gyp pick.)

With this PR:

  • apm never forces a particular version of Visual Studio to be used (node-gyp picks the right version for us)
  • apm generally doesn't try to detect Visual Studio installs on-disk anymore...
    • Except to find what version to print for apm --version.
      • For the sake of apm --version, apm knows to check for Visual Studio 2019, 2017 and 2015, which are all the versions modern node-gyp supports when used with Node > 8. We cannot use older Visual Studio versions, so I stopped checking for them.

@DeeDeeG
Copy link
Contributor Author

DeeDeeG commented Dec 1, 2020

In Azure Pipelines CI, there are copies of multiple Visual Studio installs, but not all of them are usable. Particularly, there is an unusable (for building Atom) partial install of Visual Studio 2015.

This PR makes it possible to use Visual Studio 2017 instead. Otherwise, apm will see the partial VS2015 install and force Visual Studio 2015. That errors out, since the VS2015 install is missing some components.

Please consider merging this PR so it is convenient to test with Visual Studio 2017 or 2019 in Atom's CI.

aminya added a commit to atom-minimap/minimap that referenced this pull request Dec 25, 2020
Copy link
Contributor

@sadick254 sadick254 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me @DeeDeeG. Thanks for all the investigation work. This really helps us do quicker reviews.

@sadick254 sadick254 merged commit 5576234 into atom:master Jan 29, 2021
@DeeDeeG
Copy link
Contributor Author

DeeDeeG commented Jan 29, 2021

Thank you for merging! This is one of the contributions to apm I am proudest of, and that I think makes a big difference for compatibility with modern systems that have newer Visual Studio.

darangi pushed a commit to atom/atom that referenced this pull request May 10, 2021
Windows-build-tools v4 (which is an old unmaintaind version) installs 
Visual Studio 2015. But we can use the pre-installed 2017 in 
vs2017-win2016

Requires atom/apm#892
DeeDeeG added a commit to DeeDeeG/github that referenced this pull request May 30, 2021
Mostly removing this because it has been erroring out in CI.

We already get the latest version of Visual Studio
from GitHub Actions' Windows base image.

(We used to need to manually install an older version
of Visual Studio, but we no-longer need to do that,
now that Atom ships a new enough version of apm
with atom/apm#892 included.

That PR gives apm better support for multiple Visual Studio installs
on a given system, better handling of newer versions (2017+) of VS.)
DeeDeeG pushed a commit to DeeDeeG/atom that referenced this pull request May 31, 2021
Windows-build-tools v4 (which is an old unmaintaind version) installs
Visual Studio 2015. But we can use the pre-installed 2017 in
vs2017-win2016

Requires atom/apm#892

(cherry picked from commit 8dd9901)
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
4 participants