Packaging of netlib-lapack for windows (#24993)
MSVC's internal CMake and Ninja now detected by spack external find and added to packages.yaml Saving progress on packaging zlib for Windows Fixing the shared CMake flag * Loading Intel's ifx Fortran compiler into MSVC; if there are multiple versions of MSVC installed and detected, ifx will only be placed into the first block written in compilers.yaml. The version number of ifx can be detected using MSVC's version flag (instead of /QV) by using ignore_version_errors. This commit also provides support for detection of Intel compilers in their own compiler block by adding ifx.exe to the fc/f77_name blocks inside intel.py * Giving CMake a Fortran compiler argument * Adding patch file for removing duplicated mangling header for versions 3.9.1 and older; static and shared now successfully building on Windows * Have netlib-lapack depend on ninja@1.10 Co-authored-by: John R. Cary <cary@txcorp.com> Co-authored-by: Jared Popelar <jpopelar@txcorp.com> Making a default config.yaml for Windows Small path length for build_stage Provide more prerequisite details, mention default config.yaml Killing an unnecessary setvars call Replacing some lost changes, proofreading, updating windows-supported package list Co-authored-by: John Parent <john.parent@kitware.com>
This commit is contained in:
committed by
Peter Scheibel
parent
012758c179
commit
15ef85e161
@@ -174,6 +174,10 @@ def _std_args(pkg):
|
||||
define('CMAKE_CXX_COMPILER:FILEPATH', pkg.compiler.cxx.replace('\\', '/'))
|
||||
]
|
||||
|
||||
if pkg.compiler.fc is not None:
|
||||
args.append(define('CMAKE_Fortran_COMPILER:FILEPATH',
|
||||
pkg.compiler.fc.replace('\\', '/')))
|
||||
|
||||
# CMAKE_INTERPROCEDURAL_OPTIMIZATION only exists for CMake >= 3.9
|
||||
if pkg.spec.satisfies('^cmake@3.9:'):
|
||||
args.append(define('CMAKE_INTERPROCEDURAL_OPTIMIZATION', ipo))
|
||||
|
||||
@@ -211,7 +211,6 @@ def find_compilers(path_hints=None):
|
||||
for o in all_os_classes():
|
||||
search_paths = getattr(o, 'compiler_search_paths', default_paths)
|
||||
arguments.extend(arguments_to_detect_version_fn(o, search_paths))
|
||||
|
||||
# Here we map the function arguments to the corresponding calls
|
||||
tp = multiprocessing.pool.ThreadPool()
|
||||
try:
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
|
||||
import sys
|
||||
|
||||
from spack.compiler import Compiler, UnsupportedCompilerFlag
|
||||
from spack.version import ver
|
||||
|
||||
@@ -29,8 +31,15 @@ class Intel(Compiler):
|
||||
PrgEnv = 'PrgEnv-intel'
|
||||
PrgEnv_compiler = 'intel'
|
||||
|
||||
version_argument = '--version'
|
||||
version_regex = r'\((?:IFORT|ICC)\) ([^ ]+)'
|
||||
if sys.platform == 'win32':
|
||||
version_argument = '/QV'
|
||||
else:
|
||||
version_argument = '--version'
|
||||
|
||||
if sys.platform == 'win32':
|
||||
version_regex = r'([1-9][0-9]*\.[0-9]*\.[0-9]*)'
|
||||
else:
|
||||
version_regex = r'\((?:IFORT|ICC)\) ([^ ]+)'
|
||||
|
||||
@property
|
||||
def verbose_flag(self):
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
import sys
|
||||
from typing import List # novm
|
||||
|
||||
import spack.operating_systems.windows_os
|
||||
import spack.util.executable
|
||||
from spack.compiler import Compiler
|
||||
|
||||
|
||||
@@ -19,20 +21,24 @@ class Msvc(Compiler):
|
||||
cxx_names = ['cl.exe']
|
||||
|
||||
# Subclasses use possible names of Fortran 77 compiler
|
||||
f77_names = [] # type: List[str]
|
||||
f77_names = ['ifx.exe'] # type: List[str]
|
||||
|
||||
# Subclasses use possible names of Fortran 90 compiler
|
||||
fc_names = [] # type: List[str]
|
||||
fc_names = ['ifx.exe'] # type: List[str]
|
||||
|
||||
# Named wrapper links within build_env_path
|
||||
link_paths = {'cc': 'msvc/cl.exe',
|
||||
'cxx': 'msvc/cl.exe',
|
||||
link_paths = {'cc': '',
|
||||
'cxx': '',
|
||||
'f77': '',
|
||||
'fc': ''}
|
||||
|
||||
#: Compiler argument that produces version information
|
||||
version_argument = ''
|
||||
|
||||
# For getting ifx's version, call it with version_argument
|
||||
# and ignore the error code
|
||||
ignore_version_errors = [1]
|
||||
|
||||
#: Regex used to extract version from compiler's output
|
||||
version_regex = r'([1-9][0-9]*\.[0-9]*\.[0-9]*)'
|
||||
|
||||
@@ -41,10 +47,15 @@ class Msvc(Compiler):
|
||||
|
||||
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')
|
||||
if os.getenv("ONEAPI_ROOT"):
|
||||
# If this found, it sets all the vars
|
||||
self.setvarsfile = os.path.join(
|
||||
os.getenv("ONEAPI_ROOT"), "setvars.bat")
|
||||
else:
|
||||
self.setvarsfile = os.path.abspath(
|
||||
os.path.join(self.cc, '../../../../../../..'))
|
||||
self.setvarsfile = os.path.join(
|
||||
self.setvarsfile, 'Auxiliary', 'Build', 'vcvars64.bat')
|
||||
|
||||
@property
|
||||
def verbose_flag(self):
|
||||
@@ -55,28 +66,60 @@ def pic_flag(self):
|
||||
return ""
|
||||
|
||||
def setup_custom_environment(self, pkg, env):
|
||||
"""Set environment variables for MSVC using the Microsoft-provided
|
||||
script."""
|
||||
"""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
|
||||
# Set the build environment variables for spack. Just using
|
||||
# subprocess.call() doesn't work since that operates in its own
|
||||
# environment which is destroyed (along with the adjusted variables)
|
||||
# once the process terminates. So go the long way around: examine
|
||||
# output, sort into dictionary, use that to make the build
|
||||
# environment.
|
||||
out = subprocess.check_output( # novermin
|
||||
'cmd /u /c "{0}" {1} && set'.format(self.vcvarsallfile, 'amd64'),
|
||||
'cmd /u /c "{}" {} && set'.format(self.setvarsfile, 'amd64'),
|
||||
stderr=subprocess.STDOUT)
|
||||
if sys.version_info[0] >= 3:
|
||||
out = out.decode('utf-16le', errors='replace')
|
||||
out = out.decode('utf-16le', errors='replace') # novermin
|
||||
|
||||
int_env = { # novermin
|
||||
key.lower(): value
|
||||
for key, _, value in
|
||||
(line.partition('=') for line in out.splitlines())
|
||||
if key and value
|
||||
}
|
||||
|
||||
if 'path' in int_env:
|
||||
env.set_path('PATH', int_env['path'].split(';'))
|
||||
env.set_path('INCLUDE', int_env.get('include', '').split(';'))
|
||||
env.set_path('LIB', int_env.get('lib', '').split(';'))
|
||||
else:
|
||||
# Should not this be an exception?
|
||||
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
|
||||
}
|
||||
# fc_version only loads the ifx compiler into the first MSVC stanza;
|
||||
# if there are other versions of Microsoft VS installed and detected, they
|
||||
# will only have cl.exe as the C/C++ compiler
|
||||
|
||||
# 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(';'))
|
||||
@classmethod
|
||||
def fc_version(cls, fc):
|
||||
# We're using intel for the Fortran compilers, which exist if
|
||||
# ONEAPI_ROOT is a meaningful variable
|
||||
if os.getenv("ONEAPI_ROOT"):
|
||||
try:
|
||||
sps = spack.operating_systems.windows_os.WindowsOs.compiler_search_paths
|
||||
except Exception:
|
||||
print("sps not found.")
|
||||
raise
|
||||
try:
|
||||
clp = spack.util.executable.which_string("cl", path=sps)
|
||||
except Exception:
|
||||
print("cl not found.")
|
||||
raise
|
||||
ver = cls.default_version(clp)
|
||||
return ver
|
||||
else:
|
||||
return cls.default_version(fc)
|
||||
|
||||
@classmethod
|
||||
def f77_version(cls, f77):
|
||||
return cls.fc_version(f77)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
import llnl.util.filesystem
|
||||
import llnl.util.tty
|
||||
|
||||
import spack.operating_systems.windows_os as winOs
|
||||
import spack.util.environment
|
||||
|
||||
from .common import (
|
||||
@@ -40,7 +41,18 @@ def executables_in_path(path_hints=None):
|
||||
path_hints (list): list of paths to be searched. If None the list will be
|
||||
constructed based on the PATH environment variable.
|
||||
"""
|
||||
# build_environment.py::1013: If we're on a Windows box, run vswhere, steal the installationPath using
|
||||
# windows_os.py logic, construct paths to CMake and Ninja, add to PATH
|
||||
path_hints = path_hints or spack.util.environment.get_path('PATH')
|
||||
if sys.platform == 'win32':
|
||||
msvcPaths = winOs.WindowsOs.vsInstallPaths
|
||||
msvcCMakePaths = [os.path.join(path, "Common7", "IDE", "CommonExtensions", "Microsoft", "CMake", "CMake", "bin")
|
||||
for path in msvcPaths]
|
||||
[path_hints.insert(0, path) for path in msvcCMakePaths]
|
||||
msvcNinjaPaths = [os.path.join(path, "Common7", "IDE", "CommonExtensions", "Microsoft", "CMake", "Ninja")
|
||||
for path in msvcPaths]
|
||||
[path_hints.insert(0, path) for path in msvcNinjaPaths]
|
||||
|
||||
search_paths = llnl.util.filesystem.search_paths_for_executables(*path_hints)
|
||||
|
||||
path_to_exe = {}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
from spack.architecture import OperatingSystem
|
||||
from spack.version import Version
|
||||
|
||||
|
||||
# FIXME: To get the actual Windows version, we need a python that runs
|
||||
# natively on Windows, not Cygwin.
|
||||
def windows_version():
|
||||
@@ -22,21 +21,23 @@ def windows_version():
|
||||
class WindowsOs(OperatingSystem):
|
||||
"""This class represents the Windows operating system. This will be
|
||||
auto detected using the python platform.win32_ver() once we have a
|
||||
python setup that runs natively. The Windows platform will be represented
|
||||
using the major version operating system number, e.g. 10.
|
||||
python setup that runs natively. The Windows platform will be
|
||||
represented using the major version operating system number, e.g.
|
||||
10.
|
||||
"""
|
||||
|
||||
# Find MSVC directories using vswhere
|
||||
compSearchPaths = []
|
||||
vsInstallPaths = []
|
||||
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"),
|
||||
paths = subprocess.check_output([ # novermin
|
||||
os.path.join(root, "Microsoft Visual Studio",
|
||||
"Installer", "vswhere.exe"),
|
||||
"-prerelease",
|
||||
"-requires", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
|
||||
"-property", "installationPath",
|
||||
@@ -44,16 +45,22 @@ class WindowsOs(OperatingSystem):
|
||||
], **extra_args).strip()
|
||||
if (3, 0) <= sys.version_info[:2] <= (3, 5):
|
||||
paths = paths.decode()
|
||||
msvcPaths = paths.split('\n')
|
||||
vsInstallPaths = paths.split('\n')
|
||||
msvcPaths = [os.path.join(path, "VC", "Tools", "MSVC")
|
||||
for path in msvcPaths]
|
||||
for path in vsInstallPaths]
|
||||
for p in msvcPaths:
|
||||
compSearchPaths.extend(
|
||||
glob.glob(os.path.join(p, '*', 'bin', 'Hostx64', 'x64')))
|
||||
if os.getenv("ONEAPI_ROOT"):
|
||||
comp_search_paths.extend(glob.glob(os.path.join(
|
||||
str(os.getenv("ONEAPI_ROOT")),
|
||||
'compiler', '*',
|
||||
'windows', 'bin')))
|
||||
except (subprocess.CalledProcessError, OSError, UnicodeDecodeError):
|
||||
pass
|
||||
if compSearchPaths:
|
||||
compiler_search_paths = compSearchPaths
|
||||
# print(vsInstallPaths)
|
||||
|
||||
def __init__(self):
|
||||
super(WindowsOs, self).__init__('Windows10', '10')
|
||||
|
||||
Reference in New Issue
Block a user