diff options
Diffstat (limited to 'waflib/Tools/ifort.py')
m--------- | waflib | 0 | ||||
-rw-r--r-- | waflib/Tools/ifort.py | 413 |
2 files changed, 0 insertions, 413 deletions
diff --git a/waflib b/waflib new file mode 160000 +Subproject 2314e236ca6e7d94a26c3c17091da0f25f5867f diff --git a/waflib/Tools/ifort.py b/waflib/Tools/ifort.py deleted file mode 100644 index 17d3052..0000000 --- a/waflib/Tools/ifort.py +++ /dev/null @@ -1,413 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# DC 2008 -# Thomas Nagy 2016-2018 (ita) - -import os, re, traceback -from waflib import Utils, Logs, Errors -from waflib.Tools import fc, fc_config, fc_scan, ar, ccroot -from waflib.Configure import conf -from waflib.TaskGen import after_method, feature - -@conf -def find_ifort(conf): - fc = conf.find_program('ifort', var='FC') - conf.get_ifort_version(fc) - conf.env.FC_NAME = 'IFORT' - -@conf -def ifort_modifier_win32(self): - v = self.env - v.IFORT_WIN32 = True - v.FCSTLIB_MARKER = '' - v.FCSHLIB_MARKER = '' - - v.FCLIB_ST = v.FCSTLIB_ST = '%s.lib' - v.FCLIBPATH_ST = v.STLIBPATH_ST = '/LIBPATH:%s' - v.FCINCPATH_ST = '/I%s' - v.FCDEFINES_ST = '/D%s' - - v.fcprogram_PATTERN = v.fcprogram_test_PATTERN = '%s.exe' - v.fcshlib_PATTERN = '%s.dll' - v.fcstlib_PATTERN = v.implib_PATTERN = '%s.lib' - - v.FCLNK_TGT_F = '/out:' - v.FC_TGT_F = ['/c', '/o', ''] - v.FCFLAGS_fcshlib = '' - v.LINKFLAGS_fcshlib = '/DLL' - v.AR_TGT_F = '/out:' - v.IMPLIB_ST = '/IMPLIB:%s' - - v.append_value('LINKFLAGS', '/subsystem:console') - if v.IFORT_MANIFEST: - v.append_value('LINKFLAGS', ['/MANIFEST']) - -@conf -def ifort_modifier_darwin(conf): - fc_config.fortran_modifier_darwin(conf) - -@conf -def ifort_modifier_platform(conf): - dest_os = conf.env.DEST_OS or Utils.unversioned_sys_platform() - ifort_modifier_func = getattr(conf, 'ifort_modifier_' + dest_os, None) - if ifort_modifier_func: - ifort_modifier_func() - -@conf -def get_ifort_version(conf, fc): - """ - Detects the compiler version and sets ``conf.env.FC_VERSION`` - """ - version_re = re.compile(r"\bIntel\b.*\bVersion\s*(?P<major>\d*)\.(?P<minor>\d*)",re.I).search - if Utils.is_win32: - cmd = fc - else: - cmd = fc + ['-logo'] - - out, err = fc_config.getoutput(conf, cmd, stdin=False) - match = version_re(out) or version_re(err) - if not match: - conf.fatal('cannot determine ifort version.') - k = match.groupdict() - conf.env.FC_VERSION = (k['major'], k['minor']) - -def configure(conf): - """ - Detects the Intel Fortran compilers - """ - if Utils.is_win32: - compiler, version, path, includes, libdirs, arch = conf.detect_ifort() - v = conf.env - v.DEST_CPU = arch - v.PATH = path - v.INCLUDES = includes - v.LIBPATH = libdirs - v.MSVC_COMPILER = compiler - try: - v.MSVC_VERSION = float(version) - except ValueError: - v.MSVC_VERSION = float(version[:-3]) - - conf.find_ifort_win32() - conf.ifort_modifier_win32() - else: - conf.find_ifort() - conf.find_program('xiar', var='AR') - conf.find_ar() - conf.fc_flags() - conf.fc_add_flags() - conf.ifort_modifier_platform() - - -all_ifort_platforms = [ ('intel64', 'amd64'), ('em64t', 'amd64'), ('ia32', 'x86'), ('Itanium', 'ia64')] -"""List of icl platforms""" - -@conf -def gather_ifort_versions(conf, versions): - """ - List compiler versions by looking up registry keys - """ - version_pattern = re.compile(r'^...?.?\....?.?') - try: - all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Intel\\Compilers\\Fortran') - except OSError: - try: - all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Intel\\Compilers\\Fortran') - except OSError: - return - index = 0 - while 1: - try: - version = Utils.winreg.EnumKey(all_versions, index) - except OSError: - break - index += 1 - if not version_pattern.match(version): - continue - targets = {} - for target,arch in all_ifort_platforms: - if target=='intel64': - targetDir='EM64T_NATIVE' - else: - targetDir=target - try: - Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir) - icl_version=Utils.winreg.OpenKey(all_versions,version) - path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') - except OSError: - pass - else: - batch_file=os.path.join(path,'bin','ifortvars.bat') - if os.path.isfile(batch_file): - targets[target] = target_compiler(conf, 'intel', arch, version, target, batch_file) - - for target,arch in all_ifort_platforms: - try: - icl_version = Utils.winreg.OpenKey(all_versions, version+'\\'+target) - path,type = Utils.winreg.QueryValueEx(icl_version,'ProductDir') - except OSError: - continue - else: - batch_file=os.path.join(path,'bin','ifortvars.bat') - if os.path.isfile(batch_file): - targets[target] = target_compiler(conf, 'intel', arch, version, target, batch_file) - major = version[0:2] - versions['intel ' + major] = targets - -@conf -def setup_ifort(conf, versiondict): - """ - Checks installed compilers and targets and returns the first combination from the user's - options, env, or the global supported lists that checks. - - :param versiondict: dict(platform -> dict(architecture -> configuration)) - :type versiondict: dict(string -> dict(string -> target_compiler) - :return: the compiler, revision, path, include dirs, library paths and target architecture - :rtype: tuple of strings - """ - platforms = Utils.to_list(conf.env.MSVC_TARGETS) or [i for i,j in all_ifort_platforms] - desired_versions = conf.env.MSVC_VERSIONS or list(reversed(list(versiondict.keys()))) - for version in desired_versions: - try: - targets = versiondict[version] - except KeyError: - continue - for arch in platforms: - try: - cfg = targets[arch] - except KeyError: - continue - cfg.evaluate() - if cfg.is_valid: - compiler,revision = version.rsplit(' ', 1) - return compiler,revision,cfg.bindirs,cfg.incdirs,cfg.libdirs,cfg.cpu - conf.fatal('ifort: Impossible to find a valid architecture for building %r - %r' % (desired_versions, list(versiondict.keys()))) - -@conf -def get_ifort_version_win32(conf, compiler, version, target, vcvars): - # FIXME hack - try: - conf.msvc_cnt += 1 - except AttributeError: - conf.msvc_cnt = 1 - batfile = conf.bldnode.make_node('waf-print-msvc-%d.bat' % conf.msvc_cnt) - batfile.write("""@echo off -set INCLUDE= -set LIB= -call "%s" %s -echo PATH=%%PATH%% -echo INCLUDE=%%INCLUDE%% -echo LIB=%%LIB%%;%%LIBPATH%% -""" % (vcvars,target)) - sout = conf.cmd_and_log(['cmd.exe', '/E:on', '/V:on', '/C', batfile.abspath()]) - batfile.delete() - lines = sout.splitlines() - - if not lines[0]: - lines.pop(0) - - MSVC_PATH = MSVC_INCDIR = MSVC_LIBDIR = None - for line in lines: - if line.startswith('PATH='): - path = line[5:] - MSVC_PATH = path.split(';') - elif line.startswith('INCLUDE='): - MSVC_INCDIR = [i for i in line[8:].split(';') if i] - elif line.startswith('LIB='): - MSVC_LIBDIR = [i for i in line[4:].split(';') if i] - if None in (MSVC_PATH, MSVC_INCDIR, MSVC_LIBDIR): - conf.fatal('ifort: Could not find a valid architecture for building (get_ifort_version_win32)') - - # Check if the compiler is usable at all. - # The detection may return 64-bit versions even on 32-bit systems, and these would fail to run. - env = dict(os.environ) - env.update(PATH = path) - compiler_name, linker_name, lib_name = _get_prog_names(conf, compiler) - fc = conf.find_program(compiler_name, path_list=MSVC_PATH) - - # delete CL if exists. because it could contain parameters which can change cl's behaviour rather catastrophically. - if 'CL' in env: - del(env['CL']) - - try: - conf.cmd_and_log(fc + ['/help'], env=env) - except UnicodeError: - st = traceback.format_exc() - if conf.logger: - conf.logger.error(st) - conf.fatal('ifort: Unicode error - check the code page?') - except Exception as e: - Logs.debug('ifort: get_ifort_version: %r %r %r -> failure %s', compiler, version, target, str(e)) - conf.fatal('ifort: cannot run the compiler in get_ifort_version (run with -v to display errors)') - else: - Logs.debug('ifort: get_ifort_version: %r %r %r -> OK', compiler, version, target) - finally: - conf.env[compiler_name] = '' - - return (MSVC_PATH, MSVC_INCDIR, MSVC_LIBDIR) - -class target_compiler(object): - """ - Wraps a compiler configuration; call evaluate() to determine - whether the configuration is usable. - """ - def __init__(self, ctx, compiler, cpu, version, bat_target, bat, callback=None): - """ - :param ctx: configuration context to use to eventually get the version environment - :param compiler: compiler name - :param cpu: target cpu - :param version: compiler version number - :param bat_target: ? - :param bat: path to the batch file to run - :param callback: optional function to take the realized environment variables tup and map it (e.g. to combine other constant paths) - """ - self.conf = ctx - self.name = None - self.is_valid = False - self.is_done = False - - self.compiler = compiler - self.cpu = cpu - self.version = version - self.bat_target = bat_target - self.bat = bat - self.callback = callback - - def evaluate(self): - if self.is_done: - return - self.is_done = True - try: - vs = self.conf.get_ifort_version_win32(self.compiler, self.version, self.bat_target, self.bat) - except Errors.ConfigurationError: - self.is_valid = False - return - if self.callback: - vs = self.callback(self, vs) - self.is_valid = True - (self.bindirs, self.incdirs, self.libdirs) = vs - - def __str__(self): - return str((self.bindirs, self.incdirs, self.libdirs)) - - def __repr__(self): - return repr((self.bindirs, self.incdirs, self.libdirs)) - -@conf -def detect_ifort(self): - return self.setup_ifort(self.get_ifort_versions(False)) - -@conf -def get_ifort_versions(self, eval_and_save=True): - """ - :return: platforms to compiler configurations - :rtype: dict - """ - dct = {} - self.gather_ifort_versions(dct) - return dct - -def _get_prog_names(self, compiler): - if compiler=='intel': - compiler_name = 'ifort' - linker_name = 'XILINK' - lib_name = 'XILIB' - else: - # assumes CL.exe - compiler_name = 'CL' - linker_name = 'LINK' - lib_name = 'LIB' - return compiler_name, linker_name, lib_name - -@conf -def find_ifort_win32(conf): - # the autodetection is supposed to be performed before entering in this method - v = conf.env - path = v.PATH - compiler = v.MSVC_COMPILER - version = v.MSVC_VERSION - - compiler_name, linker_name, lib_name = _get_prog_names(conf, compiler) - v.IFORT_MANIFEST = (compiler == 'intel' and version >= 11) - - # compiler - fc = conf.find_program(compiler_name, var='FC', path_list=path) - - # before setting anything, check if the compiler is really intel fortran - env = dict(conf.environ) - if path: - env.update(PATH = ';'.join(path)) - if not conf.cmd_and_log(fc + ['/nologo', '/help'], env=env): - conf.fatal('not intel fortran compiler could not be identified') - - v.FC_NAME = 'IFORT' - - if not v.LINK_FC: - conf.find_program(linker_name, var='LINK_FC', path_list=path, mandatory=True) - - if not v.AR: - conf.find_program(lib_name, path_list=path, var='AR', mandatory=True) - v.ARFLAGS = ['/nologo'] - - # manifest tool. Not required for VS 2003 and below. Must have for VS 2005 and later - if v.IFORT_MANIFEST: - conf.find_program('MT', path_list=path, var='MT') - v.MTFLAGS = ['/nologo'] - - try: - conf.load('winres') - except Errors.WafError: - Logs.warn('Resource compiler not found. Compiling resource file is disabled') - -####################################################################################################### -##### conf above, build below - -@after_method('apply_link') -@feature('fc') -def apply_flags_ifort(self): - """ - Adds additional flags implied by msvc, such as subsystems and pdb files:: - - def build(bld): - bld.stlib(source='main.c', target='bar', subsystem='gruik') - """ - if not self.env.IFORT_WIN32 or not getattr(self, 'link_task', None): - return - - is_static = isinstance(self.link_task, ccroot.stlink_task) - - subsystem = getattr(self, 'subsystem', '') - if subsystem: - subsystem = '/subsystem:%s' % subsystem - flags = is_static and 'ARFLAGS' or 'LINKFLAGS' - self.env.append_value(flags, subsystem) - - if not is_static: - for f in self.env.LINKFLAGS: - d = f.lower() - if d[1:] == 'debug': - pdbnode = self.link_task.outputs[0].change_ext('.pdb') - self.link_task.outputs.append(pdbnode) - - if getattr(self, 'install_task', None): - self.pdb_install_task = self.add_install_files(install_to=self.install_task.install_to, install_from=pdbnode) - - break - -@feature('fcprogram', 'fcshlib', 'fcprogram_test') -@after_method('apply_link') -def apply_manifest_ifort(self): - """ - Enables manifest embedding in Fortran DLLs when using ifort on Windows - See: http://msdn2.microsoft.com/en-us/library/ms235542(VS.80).aspx - """ - if self.env.IFORT_WIN32 and getattr(self, 'link_task', None): - # it seems ifort.exe cannot be called for linking - self.link_task.env.FC = self.env.LINK_FC - - if self.env.IFORT_WIN32 and self.env.IFORT_MANIFEST and getattr(self, 'link_task', None): - out_node = self.link_task.outputs[0] - man_node = out_node.parent.find_or_declare(out_node.name + '.manifest') - self.link_task.outputs.append(man_node) - self.env.DO_MANIFEST = True - |