summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBetsy McPhail <betsy.mcphail@kitware.com>2021-10-22 16:24:48 -0400
committerPeter Scheibel <scheibel1@llnl.gov>2022-03-17 09:01:01 -0700
commita7101db39de6aa754a3cce8f6e39231ababc6f67 (patch)
tree57244f525dbaae3fe700844d5a8e55b13405a245
parentf587a9ce6813eeda40563863f89520ce42c429bf (diff)
downloadspack-a7101db39de6aa754a3cce8f6e39231ababc6f67.tar.gz
spack-a7101db39de6aa754a3cce8f6e39231ababc6f67.tar.bz2
spack-a7101db39de6aa754a3cce8f6e39231ababc6f67.tar.xz
spack-a7101db39de6aa754a3cce8f6e39231ababc6f67.zip
MSVC Compiler Find and vcvars env integration (#22856)
Made the vcvars batch script location a member variable of the msvc compiler subclass, initialized from the compiler executable path. Added a setup_custom_environment() method to the msvc subclass that sources the vcvars script, dumps the environment, and copies the relevant environment variables to the Spack environment. Added class variables to the Windows OS and MSVC compiler subclasses to enable finding the compiler executables and determining their versions.
-rw-r--r--lib/spack/spack/compiler.py8
-rw-r--r--lib/spack/spack/compilers/msvc.py47
-rwxr-xr-xlib/spack/spack/operating_systems/windows_os.py33
3 files changed, 86 insertions, 2 deletions
diff --git a/lib/spack/spack/compiler.py b/lib/spack/spack/compiler.py
index 976699702b..cf903c129c 100644
--- a/lib/spack/spack/compiler.py
+++ b/lib/spack/spack/compiler.py
@@ -37,8 +37,12 @@ def _get_compiler_version_output(compiler_path, version_arg, ignore_errors=()):
version_arg (str): the argument used to extract version information
"""
compiler = spack.util.executable.Executable(compiler_path)
- output = compiler(
- version_arg, output=str, error=str, ignore_errors=ignore_errors)
+ if version_arg:
+ output = compiler(
+ version_arg, output=str, error=str, ignore_errors=ignore_errors)
+ else:
+ output = compiler(
+ output=str, error=str, ignore_errors=ignore_errors)
return output
diff --git a/lib/spack/spack/compilers/msvc.py b/lib/spack/spack/compilers/msvc.py
index ac5da84705..a613d02d36 100644
--- a/lib/spack/spack/compilers/msvc.py
+++ b/lib/spack/spack/compilers/msvc.py
@@ -3,7 +3,11 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+import os
+import subprocess
+import sys
from typing import List # novm
+
from spack.compiler import Compiler
@@ -26,6 +30,22 @@ class Msvc(Compiler):
'f77': '',
'fc': ''}
+ #: Compiler argument that produces version information
+ version_argument = ''
+
+ #: Regex used to extract version from compiler's output
+ version_regex = r'([1-9][0-9]*\.[0-9]*\.[0-9]*)'
+
+ # Initialize, deferring to base class but then adding the vcvarsallfile
+ # file based on compiler executable path.
+
+ def __init__(self, *args, **kwargs):
+ super(Msvc, self).__init__(*args, **kwargs)
+ self.vcvarsallfile = os.path.abspath(
+ os.path.join(self.cc, '../../../../../../..'))
+ self.vcvarsallfile = os.path.join(
+ self.vcvarsallfile, 'Auxiliary', 'Build', 'vcvarsall.bat')
+
@property
def verbose_flag(self):
return ""
@@ -33,3 +53,30 @@ class Msvc(Compiler):
@property
def pic_flag(self):
return ""
+
+ def setup_custom_environment(self, pkg, env):
+ """Set environment variables for MSVC using the Microsoft-provided
+ script."""
+ if sys.version_info[:2] > (2, 6):
+ # Capture output from batch script and DOS environment dump
+ out = subprocess.check_output( # novermin
+ 'cmd /u /c "{0}" {1} && set'.format(self.vcvarsallfile, 'amd64'),
+ stderr=subprocess.STDOUT)
+ if sys.version_info[0] >= 3:
+ out = out.decode('utf-16le', errors='replace')
+ else:
+ print("Cannot pull msvc compiler information in Python 2.6 or below")
+
+ # Process in to nice Python dictionary
+ vc_env = { # novermin
+ key.lower(): value
+ for key, _, value in
+ (line.partition('=') for line in out.splitlines())
+ if key and value
+ }
+
+ # Request setting environment variables
+ if 'path' in vc_env:
+ env.set_path('PATH', vc_env['path'].split(';'))
+ env.set_path('INCLUDE', vc_env.get('include', '').split(';'))
+ env.set_path('LIB', vc_env.get('lib', '').split(';'))
diff --git a/lib/spack/spack/operating_systems/windows_os.py b/lib/spack/spack/operating_systems/windows_os.py
index c4f8fa7f84..a9132c7bce 100755
--- a/lib/spack/spack/operating_systems/windows_os.py
+++ b/lib/spack/spack/operating_systems/windows_os.py
@@ -3,6 +3,10 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+import sys
+import os
+import subprocess
+import glob
from spack.architecture import OperatingSystem
from spack.version import Version
@@ -22,6 +26,35 @@ class WindowsOs(OperatingSystem):
using the major version operating system number, e.g. 10.
"""
+ # Find MSVC directories using vswhere
+ compSearchPaths = []
+ root = os.environ.get('ProgramFiles(x86)') or os.environ.get('ProgramFiles')
+ if root:
+ try:
+ extra_args = {}
+ if sys.version_info[:3] >= (3, 6, 0):
+ extra_args = {'encoding': 'mbcs', 'errors': 'strict'}
+ paths = subprocess.check_output([
+ os.path.join(root, "Microsoft Visual Studio", "Installer",
+ "vswhere.exe"),
+ "-prerelease",
+ "-requires", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
+ "-property", "installationPath",
+ "-products", "*",
+ ], **extra_args).strip()
+ if (3, 0) <= sys.version_info[:2] <= (3, 5):
+ paths = paths.decode()
+ msvcPaths = paths.split('\n')
+ msvcPaths = [os.path.join(path, "VC", "Tools", "MSVC")
+ for path in msvcPaths]
+ for p in msvcPaths:
+ compSearchPaths.extend(
+ glob.glob(os.path.join(p, '*', 'bin', 'Hostx64', 'x64')))
+ except (subprocess.CalledProcessError, OSError, UnicodeDecodeError):
+ pass
+ if compSearchPaths:
+ compiler_search_paths = compSearchPaths
+
def __init__(self):
super(WindowsOs, self).__init__('Windows10', '10')