def before_registration(cls): r"""Operations that should be performed to modify class attributes prior to registration including things like platform dependent properties and checking environment variables for default settings. """ # if cls.default_compiler is None: # if platform._is_linux or platform._is_mac: # cls.default_compiler = 'gfortran' # elif platform._is_win: # pragma: windows # cls.default_compiler = 'flang' CompiledModelDriver.before_registration(cls) cxx_orig = cls.external_libraries.pop('cxx', None) if cxx_orig is not None: if platform._is_mac: cxx_lib = 'c++' else: cxx_lib = 'stdc++' if cxx_lib not in cls.external_libraries: cls.external_libraries[cxx_lib] = cxx_orig.copy() cls.internal_libraries['fygg']['external_dependencies'].append( cxx_lib) # if platform._is_win: # pragma: windows # cls.external_libraries[cxx_lib]['libtype'] = 'windows_import' if platform._is_win: # pragma: windows cl_compiler = get_compilation_tool('compiler', 'cl') if not cl_compiler.is_installed(): # pragma: debug logger.info( "The MSVC compiler could not be located. The Python C API " "assumes the MSVC CRT will be used on windows so there may " "be errors when accessing some behavior of the Python C API. " "In particular, segfaults are known to occur when trying to " "call display_python due to differences in the internal " "structure of FILE* objects between MSVC and other " "standards.")
def update_compiler_kwargs(cls, **kwargs): r"""Update keyword arguments supplied to the compiler get_flags method for various options. Args: **kwargs: Additional keyword arguments are passed to the parent class's method. Returns: dict: Keyword arguments for a get_flags method providing compiler flags. """ if platform._is_win and (kwargs.get('target_compiler', None) in [ 'gcc', 'g++', 'gfortran' ]): # pragma: windows # Remove sh from path for compilation when the rtools # version of sh is on the path, but the gnu compiler being # used is not part of that installation. gcc = get_compilation_tool('compiler', kwargs['target_compiler'], None) if gcc: path = kwargs['env']['PATH'] gcc_path = gcc.get_executable(full_path=True) sh_path = shutil.which('sh', path=path) while sh_path: for k in ['rtools', 'git']: if k in sh_path.lower(): break else: # pragma: debug break if k not in gcc_path.lower(): paths = path.split(os.pathsep) paths.remove(os.path.dirname(sh_path)) path = os.pathsep.join(paths) else: # pragma: debug break sh_path = shutil.which('sh', path=path) kwargs['env']['PATH'] = path if not sh_path: kwargs.setdefault('generator', 'MinGW Makefiles') # This is not currently tested # else: # kwargs.setdefault('generator', 'MSYS Makefiles') out = super(CMakeModelDriver, cls).update_compiler_kwargs(**kwargs) if CModelDriver._osx_sysroot is not None: out.setdefault('definitions', []) out['definitions'].append('CMAKE_OSX_SYSROOT=%s' % CModelDriver._osx_sysroot) if os.environ.get('MACOSX_DEPLOYMENT_TARGET', None): out['definitions'].append( 'CMAKE_OSX_DEPLOYMENT_TARGET=%s' % os.environ['MACOSX_DEPLOYMENT_TARGET']) return out
def update_compiler_kwargs(cls, **kwargs): r"""Update keyword arguments supplied to the compiler get_flags method for various options. Args: **kwargs: Additional keyword arguments are passed to the parent class's method. Returns: dict: Keyword arguments for a get_flags method providing compiler flags. """ if platform._is_win and (kwargs.get('target_compiler', None) in ['gcc', 'g++', 'gfortran']): # pragma: windows gcc = get_compilation_tool('compiler', kwargs['target_compiler'], None) if gcc: path = cls.prune_sh_gcc( kwargs['env']['PATH'], gcc.get_executable(full_path=True)) kwargs['env']['PATH'] = path if not shutil.which('sh', path=path): # pragma: appveyor # This will not be run on Github actions where # the shell is always set kwargs.setdefault('generator', 'MinGW Makefiles') elif shutil.which('make', path=path): kwargs.setdefault('generator', 'Unix Makefiles') # This is not currently tested # else: # kwargs.setdefault('generator', 'MSYS Makefiles') out = super(CMakeModelDriver, cls).update_compiler_kwargs(**kwargs) out.setdefault('definitions', []) out['definitions'].append('PYTHON_EXECUTABLE=%s' % sys.executable) if CModelDriver._osx_sysroot is not None: out.setdefault('definitions', []) out['definitions'].append( 'CMAKE_OSX_SYSROOT=%s' % CModelDriver._osx_sysroot) if os.environ.get('MACOSX_DEPLOYMENT_TARGET', None): out['definitions'].append( 'CMAKE_OSX_DEPLOYMENT_TARGET=%s' % os.environ['MACOSX_DEPLOYMENT_TARGET']) return out
def get_flags(cls, sourcedir='.', builddir=None, target_compiler=None, **kwargs): r"""Get a list of configuration/generation flags. Args: sourcedir (str, optional): Directory containing the source files to be compiled and the target CMakeLists.txt file. Defaults to '.' (the current working directory). builddir (str, optional): Directory that will contain the build tree. Defaults to '.' (this current working directory). target_compiler(str, optional): Compiler that should be used by cmake. Defaults to None and the default for the target language will be used. **kwargs: Additional keyword arguments are passed to the parent class's method. Returns: list: Compiler flags. Raises: RuntimeError: If dont_link is True and the provide outfile and builddir keyword arguments point to conflicting paths. ValueError: If 'include_dirs' is set ('sourcedir' should be used for cmake to specify the location of the source). """ if kwargs.get('dont_link', False): if builddir is None: outfile = kwargs.get('outfile', None) if outfile is None: builddir = os.path.normpath(os.path.join(sourcedir, cls.default_builddir)) else: builddir = outfile # Pop target (used for build stage file name, but not for any other # part of the build stage) kwargs.pop('target', None) # Add env prefix # for iprefix in cls.get_env_prefixes(): # kwargs.setdefault('definitions', []) # kwargs['definitions'].append('CMAKE_PREFIX_PATH=%s' # % os.path.join(iprefix, 'lib')) # kwargs['definitions'].append('CMAKE_LIBRARY_PATH=%s' # % os.path.join(iprefix, 'lib')) out = super(CMakeConfigure, cls).get_flags(sourcedir=sourcedir, builddir=builddir, **kwargs) if platform._is_win and ('platform' not in kwargs): # pragma: windows generator = kwargs.get('generator', None) if generator is None: generator = cls.generator() if (((generator is not None) and generator.startswith('Visual') and (not generator.endswith(('Win64', 'ARM'))) and platform._is_64bit)): out.append('-DCMAKE_GENERATOR_PLATFORM=x64') if target_compiler is not None: compiler = get_compilation_tool('compiler', target_compiler) cmake_vars = {'c_compiler': 'CMAKE_C_COMPILER', 'c_flags': 'CMAKE_C_FLAGS', 'c++_compiler': 'CMAKE_CXX_COMPILER', 'c++_flags': 'CMAKE_CXX_FLAGS', 'fortran_compiler': 'CMAKE_Fortran_COMPILER', 'fortran_flags': 'CMAKE_Fortran_FLAGS'} for k in ['c', 'c++', 'fortran']: try: itool = get_compatible_tool(compiler, 'compiler', k) except ValueError: continue if itool.default_executable_env is None: out.append('-D%s=%s' % (cmake_vars['%s_compiler' % k], itool.toolname)) if itool.default_flags_env is None: out.append('-D%s=%s' % (cmake_vars['%s_flags' % k], '')) return out