44# SPDX-License-Identifier: (Apache-2.0 OR MIT)
55
66import os
7+ import re
78import subprocess
89import sys
9- from typing import List # novm
10+ from distutils .version import StrictVersion
11+ from typing import Dict , List , Set # novm
1012
1113import spack .operating_systems .windows_os
1214import spack .util .executable
1315from spack .compiler import Compiler
16+ from spack .error import SpackError
17+
18+ avail_fc_version = set () # type: Set[str]
19+ fc_path = dict () # type: Dict[str, str]
20+
21+ fortran_mapping = {
22+ '2021.3.0' : '19.29.30133' ,
23+ '2021.2.1' : '19.28.29913' ,
24+ '2021.2.0' : '19.28.29334' ,
25+ '2021.1.0' : '19.28.29333' ,
26+ }
27+
28+
29+ def get_valid_fortran_pth (comp_ver ):
30+ cl_ver = str (comp_ver ).split ('@' )[1 ]
31+ sort_fn = lambda fc_ver : StrictVersion (fc_ver )
32+ sort_fc_ver = sorted (list (avail_fc_version ), key = sort_fn )
33+ for ver in sort_fc_ver :
34+ if ver in fortran_mapping :
35+ if StrictVersion (cl_ver ) <= StrictVersion (fortran_mapping [ver ]):
36+ return fc_path [ver ]
37+ return None
1438
1539
1640class Msvc (Compiler ):
@@ -46,6 +70,8 @@ class Msvc(Compiler):
4670 # file based on compiler executable path.
4771
4872 def __init__ (self , * args , ** kwargs ):
73+ new_pth = [pth if pth else get_valid_fortran_pth (args [0 ]) for pth in args [3 ]]
74+ args [3 ][:] = new_pth
4975 super (Msvc , self ).__init__ (* args , ** kwargs )
5076 if os .getenv ("ONEAPI_ROOT" ):
5177 # If this found, it sets all the vars
@@ -65,6 +91,12 @@ def verbose_flag(self):
6591 def pic_flag (self ):
6692 return ""
6793
94+ @property
95+ def msvc_version (self ):
96+ ver = re .search (Msvc .version_regex , self .cc ).group (1 )
97+ ver = "" .join (ver .split ('.' )[:2 ])[:- 1 ]
98+ return "MSVC" + ver
99+
68100 def setup_custom_environment (self , pkg , env ):
69101 """Set environment variables for MSVC using the
70102 Microsoft-provided script."""
@@ -81,44 +113,40 @@ def setup_custom_environment(self, pkg, env):
81113 if sys .version_info [0 ] >= 3 :
82114 out = out .decode ('utf-16le' , errors = 'replace' ) # novermin
83115
84- int_env = { # novermin
85- key .lower (): value
86- for key , _ , value in
87- (line .partition ('=' ) for line in out .splitlines ())
88- if key and value
89- }
116+ int_env = dict ((key .lower (), value ) for key , _ , value in
117+ (line .partition ('=' ) for line in out .splitlines ())
118+ if key and value )
90119
91120 if 'path' in int_env :
92121 env .set_path ('PATH' , int_env ['path' ].split (';' ))
93122 env .set_path ('INCLUDE' , int_env .get ('include' , '' ).split (';' ))
94123 env .set_path ('LIB' , int_env .get ('lib' , '' ).split (';' ))
124+
125+ env .set ('CC' , self .cc )
126+ env .set ('CXX' , self .cxx )
127+ env .set ('FC' , self .fc )
128+ env .set ('F77' , self .f77 )
95129 else :
96130 # Should not this be an exception?
97131 print ("Cannot pull msvc compiler information in Python 2.6 or below" )
98132
99- # fc_version only loads the ifx compiler into the first MSVC stanza;
100- # if there are other versions of Microsoft VS installed and detected, they
101- # will only have cl.exe as the C/C++ compiler
102-
103133 @classmethod
104134 def fc_version (cls , fc ):
105135 # We're using intel for the Fortran compilers, which exist if
106136 # ONEAPI_ROOT is a meaningful variable
137+ fc_ver = cls .default_version (fc )
138+ avail_fc_version .add (fc_ver )
139+ fc_path [fc_ver ] = fc
107140 if os .getenv ("ONEAPI_ROOT" ):
108141 try :
109142 sps = spack .operating_systems .windows_os .WindowsOs .compiler_search_paths
110- except Exception :
111- print ("sps not found." )
112- raise
113- try :
114- clp = spack .util .executable .which_string ("cl" , path = sps )
115- except Exception :
116- print ("cl not found." )
117- raise
143+ except AttributeError :
144+ raise SpackError ("Windows compiler search paths not established" )
145+ clp = spack .util .executable .which_string ("cl" , path = sps )
118146 ver = cls .default_version (clp )
119- return ver
120147 else :
121- return cls .default_version (fc )
148+ ver = fc_ver
149+ return ver
122150
123151 @classmethod
124152 def f77_version (cls , f77 ):
0 commit comments