Adding basic Windows features (#21259)

* Snapshot of some MSVC infrastructure added during experiments a while ago.  Rebasing from spack/develop.

* Added platform and OS definitions for Windows.

* Updated Windows platform file to conform to new archspec use.

* Added Windows as a platform; introduced some debugging code.

* Added type annotations.

* Fixed copyright.

* Removed print statements.

* Ensure `spack arch` returns correctly on Windows (#21428)

* Correctly identify windows as 'windows-Windows10-AMD64'
This commit is contained in:
Ben Cowan 2021-02-01 07:26:47 -07:00 committed by Peter Scheibel
parent b26b3bebb4
commit 81bc00d61f
6 changed files with 138 additions and 3 deletions

2
lib/spack/env/cc vendored
View File

@ -241,7 +241,7 @@ case "$command" in
mode=cpp
debug_flags="-g"
;;
cc|c89|c99|gcc|clang|armclang|icc|icx|pgcc|nvc|xlc|xlc_r|fcc|amdclang)
cc|c89|c99|gcc|clang|armclang|icc|icx|pgcc|nvc|xlc|xlc_r|fcc|amdclang|cl.exe)
command="$SPACK_CC"
language="C"
comp="CC"

View File

@ -564,7 +564,7 @@ def __enter__(self):
sys.stdout.flush()
sys.stderr.flush()
# Now do the actual output rediction.
# Now do the actual output redirection.
self.use_fds = _file_descriptors_work(sys.stdout, sys.stderr)
if self.use_fds:
# We try first to use OS-level file descriptors, as this
@ -725,7 +725,8 @@ def _writer_daemon(stdin_multiprocess_fd, read_multiprocess_fd, write_fd, echo,
# write_fd to terminate the reading loop, so we close the file descriptor
# here. Forking is the process spawning method everywhere except Mac OS
# for Python >= 3.8 and on Windows
if sys.version_info < (3, 8) or sys.platform != 'darwin':
if sys.version_info < (3, 8) \
or sys.platform not in ['darwin', 'cygwin']:
os.close(write_fd)
# Use line buffering (3rd param = 1) since Python 3 has a bug

View File

@ -0,0 +1,35 @@
# Copyright 2013-2020 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
from typing import List # novm
from spack.compiler import Compiler
class Msvc(Compiler):
# Subclasses use possible names of C compiler
cc_names = ['cl.exe']
# Subclasses use possible names of C++ compiler
cxx_names = ['cl.exe']
# Subclasses use possible names of Fortran 77 compiler
f77_names = [] # type: List[str]
# Subclasses use possible names of Fortran 90 compiler
fc_names = [] # type: List[str]
# Named wrapper links within build_env_path
link_paths = {'cc': 'msvc/cl.exe',
'cxx': 'msvc/cl.exe',
'f77': '',
'fc': ''}
@property
def verbose_flag(self):
return ""
@property
def pic_flag(self):
return ""

View File

@ -0,0 +1,29 @@
# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
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():
"""temporary workaround to return a Windows version as a Version object
"""
return Version('10')
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.
"""
def __init__(self):
super(WindowsOs, self).__init__('Windows10', '10')
def __str__(self):
return self.name

View File

@ -0,0 +1,40 @@
# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import platform
import archspec.cpu
from spack.architecture import Platform, Target
from spack.operating_systems.windows_os import WindowsOs
class Windows(Platform):
priority = 101
# binary_formats = ['macho']
def __init__(self):
super(Windows, self).__init__('windows')
for name in archspec.cpu.TARGETS:
self.add_target(name, Target(name))
self.default = archspec.cpu.host().name
self.front_end = self.default
self.back_end = self.default
windows_os = WindowsOs()
self.default_os = str(windows_os)
self.front_os = str(windows_os)
self.back_os = str(windows_os)
self.add_operating_system(str(windows_os), windows_os)
@classmethod
def detect(cls):
plat = platform.system().lower()
return 'cygwin' in plat or 'win32' in plat or 'windows' in plat

View File

@ -13,6 +13,8 @@
import os
import signal
import traceback
import sys
import pdb
def debug_handler(sig, frame):
@ -32,3 +34,31 @@ def debug_handler(sig, frame):
def register_interrupt_handler():
"""Print traceback and enter an interpreter on Ctrl-C"""
signal.signal(signal.SIGINT, debug_handler)
# Subclass of the debugger to keep readline working. See
# https://stackoverflow.com/questions/4716533/how-to-attach-debugger-to-a-python-subproccess/23654936
class ForkablePdb(pdb.Pdb):
_original_stdin_fd = sys.stdin.fileno()
_original_stdin = None
def __init__(self, stdout_fd=None, stderr_fd=None):
pdb.Pdb.__init__(self, nosigint=True)
self._stdout_fd = stdout_fd
self._stderr_fd = stderr_fd
def _cmdloop(self):
current_stdin = sys.stdin
try:
if not self._original_stdin:
self._original_stdin = os.fdopen(self._original_stdin_fd)
sys.stdin = self._original_stdin
if self._stdout_fd is not None:
os.dup2(self._stdout_fd, sys.stdout.fileno())
os.dup2(self._stdout_fd, self.stdout.fileno())
if self._stderr_fd is not None:
os.dup2(self._stderr_fd, sys.stderr.fileno())
self.cmdloop()
finally:
sys.stdin = current_stdin