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:
		
				
					committed by
					
						
						Peter Scheibel
					
				
			
			
				
	
			
			
			
						parent
						
							b26b3bebb4
						
					
				
				
					commit
					81bc00d61f
				
			
							
								
								
									
										2
									
								
								lib/spack/env/cc
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								lib/spack/env/cc
									
									
									
									
										vendored
									
									
								
							@@ -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"
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										35
									
								
								lib/spack/spack/compilers/msvc.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								lib/spack/spack/compilers/msvc.py
									
									
									
									
									
										Normal 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 ""
 | 
			
		||||
							
								
								
									
										29
									
								
								lib/spack/spack/operating_systems/windows_os.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										29
									
								
								lib/spack/spack/operating_systems/windows_os.py
									
									
									
									
									
										Executable 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
 | 
			
		||||
							
								
								
									
										40
									
								
								lib/spack/spack/platforms/windows.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										40
									
								
								lib/spack/spack/platforms/windows.py
									
									
									
									
									
										Executable 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
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user