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:
Jared Popelar
2021-05-17 14:56:42 -06:00
committed by Peter Scheibel
parent 012758c179
commit 15ef85e161
11 changed files with 295 additions and 121 deletions

View File

@@ -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))

View File

@@ -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:

View File

@@ -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):

View File

@@ -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)

View File

@@ -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 = {}

View File

@@ -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')