summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Cowan <benc@txcorp.com>2021-02-01 07:26:47 -0700
committerPeter Scheibel <scheibel1@llnl.gov>2022-03-17 09:01:01 -0700
commit81bc00d61fd9872514e5e25b4af405e6d3c9202e (patch)
treeecd03063fbad9a0cf4b9fa3a9c0e1b29f0489f32
parentb26b3bebb4f44009f1e452b983b8fedb2e4e17ef (diff)
downloadspack-81bc00d61fd9872514e5e25b4af405e6d3c9202e.tar.gz
spack-81bc00d61fd9872514e5e25b4af405e6d3c9202e.tar.bz2
spack-81bc00d61fd9872514e5e25b4af405e6d3c9202e.tar.xz
spack-81bc00d61fd9872514e5e25b4af405e6d3c9202e.zip
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'
-rwxr-xr-xlib/spack/env/cc2
-rw-r--r--lib/spack/llnl/util/tty/log.py5
-rw-r--r--lib/spack/spack/compilers/msvc.py35
-rwxr-xr-xlib/spack/spack/operating_systems/windows_os.py29
-rwxr-xr-xlib/spack/spack/platforms/windows.py40
-rw-r--r--lib/spack/spack/util/debug.py30
6 files changed, 138 insertions, 3 deletions
diff --git a/lib/spack/env/cc b/lib/spack/env/cc
index 1a52f2c612..9fd0e4dfbc 100755
--- a/lib/spack/env/cc
+++ b/lib/spack/env/cc
@@ -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"
diff --git a/lib/spack/llnl/util/tty/log.py b/lib/spack/llnl/util/tty/log.py
index 1a93b570a5..566d180645 100644
--- a/lib/spack/llnl/util/tty/log.py
+++ b/lib/spack/llnl/util/tty/log.py
@@ -564,7 +564,7 @@ class log_output(object):
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
diff --git a/lib/spack/spack/compilers/msvc.py b/lib/spack/spack/compilers/msvc.py
new file mode 100644
index 0000000000..ac5da84705
--- /dev/null
+++ b/lib/spack/spack/compilers/msvc.py
@@ -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 ""
diff --git a/lib/spack/spack/operating_systems/windows_os.py b/lib/spack/spack/operating_systems/windows_os.py
new file mode 100755
index 0000000000..c4f8fa7f84
--- /dev/null
+++ b/lib/spack/spack/operating_systems/windows_os.py
@@ -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
diff --git a/lib/spack/spack/platforms/windows.py b/lib/spack/spack/platforms/windows.py
new file mode 100755
index 0000000000..7c9ed1443d
--- /dev/null
+++ b/lib/spack/spack/platforms/windows.py
@@ -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
diff --git a/lib/spack/spack/util/debug.py b/lib/spack/spack/util/debug.py
index 0cae1ef58a..8a15b76f16 100644
--- a/lib/spack/spack/util/debug.py
+++ b/lib/spack/spack/util/debug.py
@@ -13,6 +13,8 @@ import code
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