@ -12,14 +12,13 @@
# See the License for the specific language governing permissions and
# See the License for the specific language governing permissions and
# limitations under the License.
# limitations under the License.
import configparser , os , platform , re , sys , shlex , shutil , subprocess
import os , platform , re , sys , shlex , shutil , subprocess
import typing
from . import coredata
from . import coredata
from . linkers import ArLinker , ArmarLinker , VisualStudioLinker , DLinker , CcrxLinker
from . linkers import ArLinker , ArmarLinker , VisualStudioLinker , DLinker , CcrxLinker
from . import mesonlib
from . import mesonlib
from . mesonlib import (
from . mesonlib import (
MesonException , EnvironmentException , MachineChoice , PerMachine , P open_safe ,
MesonException , EnvironmentException , MachineChoice , Popen_safe ,
)
)
from . import mlog
from . import mlog
@ -38,7 +37,6 @@ from .compilers import (
is_source ,
is_source ,
)
)
from . compilers import (
from . compilers import (
Compiler ,
ArmCCompiler ,
ArmCCompiler ,
ArmCPPCompiler ,
ArmCPPCompiler ,
ArmclangCCompiler ,
ArmclangCCompiler ,
@ -62,6 +60,8 @@ from .compilers import (
IntelCCompiler ,
IntelCCompiler ,
IntelCPPCompiler ,
IntelCPPCompiler ,
IntelFortranCompiler ,
IntelFortranCompiler ,
IntelClCCompiler ,
IntelClCPPCompiler ,
JavaCompiler ,
JavaCompiler ,
MonoCompiler ,
MonoCompiler ,
CudaCompiler ,
CudaCompiler ,
@ -455,11 +455,13 @@ class Environment:
# List of potential compilers.
# List of potential compilers.
if mesonlib . is_windows ( ) :
if mesonlib . is_windows ( ) :
self . default_c = [ ' cl ' , ' cc ' , ' gcc ' , ' clang ' , ' clang-cl ' , ' pgcc ' ]
# Intel C and C++ compiler is icl on Windows, but icc and icpc elsewhere.
self . default_cpp = [ ' cl ' , ' c++ ' , ' g++ ' , ' clang++ ' , ' clang-cl ' , ' pgc++ ' ]
self . default_c = [ ' cl ' , ' cc ' , ' gcc ' , ' clang ' , ' clang-cl ' , ' pgcc ' , ' icl ' ]
# There is currently no pgc++ for Windows, only for Mac and Linux.
self . default_cpp = [ ' cl ' , ' c++ ' , ' g++ ' , ' clang++ ' , ' clang-cl ' , ' icl ' ]
else :
else :
self . default_c = [ ' cc ' , ' gcc ' , ' clang ' , ' pgcc ' ]
self . default_c = [ ' cc ' , ' gcc ' , ' clang ' , ' pgcc ' , ' icc ' ]
self . default_cpp = [ ' c++ ' , ' g++ ' , ' clang++ ' , ' pgc++ ' ]
self . default_cpp = [ ' c++ ' , ' g++ ' , ' clang++ ' , ' pgc++ ' , ' icpc ' ]
if mesonlib . is_windows ( ) :
if mesonlib . is_windows ( ) :
self . default_cs = [ ' csc ' , ' mcs ' ]
self . default_cs = [ ' csc ' , ' mcs ' ]
else :
else :
@ -467,7 +469,7 @@ class Environment:
self . default_objc = [ ' cc ' ]
self . default_objc = [ ' cc ' ]
self . default_objcpp = [ ' c++ ' ]
self . default_objcpp = [ ' c++ ' ]
self . default_d = [ ' ldc2 ' , ' ldc ' , ' gdc ' , ' dmd ' ]
self . default_d = [ ' ldc2 ' , ' ldc ' , ' gdc ' , ' dmd ' ]
self . default_fortran = [ ' gfortran ' , ' g95 ' , ' f95 ' , ' f90 ' , ' f77 ' , ' ifort ' , ' pgfortran ' ]
self . default_fortran = [ ' gfortran ' , ' flang ' , ' pgfortran ' , ' ifort ' , ' g95 ' ]
self . default_java = [ ' javac ' ]
self . default_java = [ ' javac ' ]
self . default_cuda = [ ' nvcc ' ]
self . default_cuda = [ ' nvcc ' ]
self . default_rust = [ ' rustc ' ]
self . default_rust = [ ' rustc ' ]
@ -676,6 +678,7 @@ class Environment:
arg = ' -v '
arg = ' -v '
else :
else :
arg = ' --version '
arg = ' --version '
try :
try :
p , out , err = Popen_safe ( compiler + [ arg ] )
p , out , err = Popen_safe ( compiler + [ arg ] )
except OSError as e :
except OSError as e :
@ -684,6 +687,11 @@ class Environment:
if ' ccrx ' in compiler [ 0 ] :
if ' ccrx ' in compiler [ 0 ] :
out = err
out = err
if ' icl ' in compiler [ 0 ] :
# https://software.intel.com/en-us/cpp-compiler-developer-guide-and-reference-alphabetical-list-of-compiler-options
# https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-logo
# most consistent way for ICL is to just let compiler error and tell version
out = err
full_version = out . split ( ' \n ' , 1 ) [ 0 ]
full_version = out . split ( ' \n ' , 1 ) [ 0 ]
version = search_version ( out )
version = search_version ( out )
@ -769,19 +777,29 @@ class Environment:
target = ' x86 '
target = ' x86 '
cls = VisualStudioCCompiler if lang == ' c ' else VisualStudioCPPCompiler
cls = VisualStudioCCompiler if lang == ' c ' else VisualStudioCPPCompiler
return cls ( compiler , version , is_cross , exe_wrap , target )
return cls ( compiler , version , is_cross , exe_wrap , target )
if ' PGI Compilers ' in out :
if ' PGI Compilers ' in out :
if mesonlib . for_darwin ( is_cross , self ) :
compiler_type = CompilerType . PGI_OSX
elif mesonlib . for_windows ( is_cross , self ) :
compiler_type = CompilerType . PGI_WIN
else :
compiler_type = CompilerType . PGI_STANDARD
cls = PGICCompiler if lang == ' c ' else PGICPPCompiler
cls = PGICCompiler if lang == ' c ' else PGICPPCompiler
return cls ( ccache + compiler , version , is_cross , exe_wrap )
return cls ( ccache + compiler , version , compiler_type , is_cross , exe_wrap )
if ' (ICC) ' in out :
if ' (ICC) ' in out :
if mesonlib . for_darwin ( want_cross , self ) :
if mesonlib . for_darwin ( want_cross , self ) :
compiler_type = CompilerType . ICC_OSX
compiler_type = CompilerType . ICC_OSX
elif mesonlib . for_windows ( want_cross , self ) :
elif mesonlib . for_windows ( want_cross , self ) :
# TODO: fix ICC on Windows
raise EnvironmentException ( ' At the time of authoring, there was no ICC for Windows ' )
compiler_type = CompilerType . ICC_WIN
else :
else :
compiler_type = CompilerType . ICC_STANDARD
compiler_type = CompilerType . ICC_STANDARD
cls = IntelCCompiler if lang == ' c ' else IntelCPPCompiler
cls = IntelCCompiler if lang == ' c ' else IntelCPPCompiler
return cls ( ccache + compiler , version , compiler_type , is_cross , exe_wrap , full_version = full_version )
return cls ( ccache + compiler , version , compiler_type , is_cross , exe_wrap , full_version = full_version )
if out . startswith ( ' Intel(R) C++ ' ) and mesonlib . for_windows ( want_cross , self ) :
cls = IntelClCCompiler if lang == ' c ' else IntelClCPPCompiler
target = ' x64 ' if ' Intel(R) 64 Compiler ' in out else ' x86 '
return cls ( compiler , version , is_cross , exe_wrap , target )
if ' ARM ' in out :
if ' ARM ' in out :
compiler_type = CompilerType . ARM_WIN
compiler_type = CompilerType . ARM_WIN
cls = ArmCCompiler if lang == ' c ' else ArmCPPCompiler
cls = ArmCCompiler if lang == ' c ' else ArmCPPCompiler
@ -846,6 +864,13 @@ class Environment:
popen_exceptions [ ' ' . join ( compiler + [ arg ] ) ] = e
popen_exceptions [ ' ' . join ( compiler + [ arg ] ) ] = e
continue
continue
if mesonlib . for_windows ( is_cross , self ) :
if ' ifort ' in compiler [ 0 ] :
# https://software.intel.com/en-us/cpp-compiler-developer-guide-and-reference-alphabetical-list-of-compiler-options
# https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-logo
# most consistent way for ICL is to just let compiler error and tell version
out = err
version = search_version ( out )
version = search_version ( out )
full_version = out . split ( ' \n ' , 1 ) [ 0 ]
full_version = out . split ( ' \n ' , 1 ) [ 0 ]
@ -876,14 +901,20 @@ class Environment:
version = search_version ( err )
version = search_version ( err )
return SunFortranCompiler ( compiler , version , is_cross , exe_wrap , full_version = full_version )
return SunFortranCompiler ( compiler , version , is_cross , exe_wrap , full_version = full_version )
if ' ifort (IFORT) ' in out :
if ' ifort (IFORT) ' in out or out . startswith ( ' Intel(R) Visual Fortran ' ) :
return IntelFortranCompiler ( compiler , version , is_cross , exe_wrap , full_version = full_version )
return IntelFortranCompiler ( compiler , version , is_cross , exe_wrap , full_version = full_version )
if ' PathScale EKOPath(tm) ' in err :
if ' PathScale EKOPath(tm) ' in err :
return PathScaleFortranCompiler ( compiler , version , is_cross , exe_wrap , full_version = full_version )
return PathScaleFortranCompiler ( compiler , version , is_cross , exe_wrap , full_version = full_version )
if ' PGI Compilers ' in out :
if ' PGI Compilers ' in out :
return PGIFortranCompiler ( compiler , version , is_cross , exe_wrap , full_version = full_version )
if mesonlib . for_darwin ( is_cross , self ) :
compiler_type = CompilerType . PGI_OSX
elif mesonlib . for_windows ( is_cross , self ) :
compiler_type = CompilerType . PGI_WIN
else :
compiler_type = CompilerType . PGI_STANDARD
return PGIFortranCompiler ( compiler , version , compiler_type , is_cross , exe_wrap , full_version = full_version )
if ' flang ' in out or ' clang ' in out :
if ' flang ' in out or ' clang ' in out :
return FlangFortranCompiler ( compiler , version , is_cross , exe_wrap , full_version = full_version )
return FlangFortranCompiler ( compiler , version , is_cross , exe_wrap , full_version = full_version )
@ -1039,7 +1070,8 @@ class Environment:
# up to date language version at time (2016).
# up to date language version at time (2016).
if exelist is not None :
if exelist is not None :
if os . path . basename ( exelist [ - 1 ] ) . startswith ( ( ' ldmd ' , ' gdmd ' ) ) :
if os . path . basename ( exelist [ - 1 ] ) . startswith ( ( ' ldmd ' , ' gdmd ' ) ) :
raise EnvironmentException ( ' Meson doesn \' t support %s as it \' s only a DMD frontend for another compiler. Please provide a valid value for DC or unset it so that Meson can resolve the compiler by itself. ' % exelist [ - 1 ] )
raise EnvironmentException ( ' Meson does not support {} as it is only a DMD frontend for another compiler. '
' Please provide a valid value for DC or unset it so that Meson can resolve the compiler by itself. ' . format ( exelist [ - 1 ] ) )
else :
else :
for d in self . default_d :
for d in self . default_d :
if shutil . which ( d ) :
if shutil . which ( d ) :