Skip to content

Commit

Permalink
Control linker language via class attribute
Browse files Browse the repository at this point in the history
Link fortran as C++
Add standard libraries for fortran compilation based on the linking language
  • Loading branch information
langmm committed Feb 23, 2024
1 parent d7f01b4 commit 478ebe0
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 22 deletions.
10 changes: 8 additions & 2 deletions yggdrasil/drivers/CompiledModelDriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -1489,7 +1489,10 @@ def linker(cls):
linker = getattr(cls, '_linker', cls.default_linker)
linker_flags = getattr(cls, '_linker_flags', cls.default_linker_flags)
if linker is None:
linker = find_compilation_tool('linker', cls.languages[0])
linker_language = getattr(cls, 'default_linker_language', None)
if linker_language is None:
linker_language = cls.languages[0]
linker = find_compilation_tool('linker', linker_language)
if linker:
out = get_compilation_tool('linker', linker,
return_instance=True,
Expand All @@ -1511,7 +1514,10 @@ def archiver(cls):
archiver = getattr(cls, '_archiver', cls.default_archiver)
archiver_flags = getattr(cls, '_archiver_flags', cls.default_archiver_flags)
if archiver is None:
archiver = find_compilation_tool('archiver', cls.languages[0])
archiver_language = getattr(cls, 'default_archiver_language', None)
if archiver_language is None:
archiver_language = cls.languages[0]
archiver = find_compilation_tool('archiver', archiver_language)
out = archiver
if archiver:
out = get_compilation_tool('archiver', archiver,
Expand Down
46 changes: 26 additions & 20 deletions yggdrasil/drivers/FortranModelDriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,16 @@ class FortranCompilerBase(CompilerBase):
default_executable = None
default_archiver = None
product_exts = ['.mod']
default_linker_language = 'c++'

@classmethod
def call(cls, args, **kwargs):
r"""Call the compiler with the provided arguments. For |yggdrasil| C
models will always be linked using the C++ linker since some parts of
the interface library are written in C++."""
if not kwargs.get('dont_link', False):
kwargs.setdefault('linker_language', 'c++')
if (((not kwargs.get('dont_link', False))
and cls.default_linker_language is not None)):
kwargs.setdefault('linker_language', cls.default_linker_language)
return super(FortranCompilerBase, cls).call(args, **kwargs)

@classmethod
Expand Down Expand Up @@ -170,7 +172,7 @@ class FortranModelDriver(CompiledModelDriver):
zmq={'libraries': [('c', x) for x in
CModelDriver.CModelDriver.supported_comm_options[
'zmq']['libraries']]})
standard_libraries = ['c', 'gfortran']
standard_libraries = []
external_libraries = {'cxx': {'include': 'stdlib.h',
'libtype': 'shared',
'language': 'c'}}
Expand All @@ -184,8 +186,7 @@ class FortranModelDriver(CompiledModelDriver):
[('c', 'ygg'), 'c_wrappers']),
'external_dependencies': (
[('c', x) for x in
_c_internal_libs['ygg']['external_dependencies']]
+ ['c', 'gfortran']),
_c_internal_libs['ygg']['external_dependencies']]),
'include_dirs': (
_c_internal_libs['ygg']['include_dirs'])},
c_wrappers={'source': os.path.join(_incl_interface,
Expand Down Expand Up @@ -431,28 +432,33 @@ def before_registration(cls):
# 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:
orig_standards = {}
orig_standards['c++'] = cls.external_libraries.pop('cxx', None)
add_standard_libraries = {}
if FortranCompilerBase.default_linker_language == 'c++':
if cls.default_compiler == 'gfortran':
add_standard_libraries['fortran'] = 'gfortran'
elif orig_standards['c++'] is not None:
# add_standard_libraries['c'] = 'c'
c_compilers = get_compilation_tool_registry(
'compiler', init_languages=['c++'])['by_language'].get('c++', {})
add_cxx_lib = None
for k, v in c_compilers.items():
if not v.is_installed():
continue
if k == 'clang++':
if not add_cxx_lib:
add_cxx_lib = 'c++'
if not add_standard_libraries.get('c++', None):
add_standard_libraries['c++'] = 'c++'
else:
# GNU takes precedence when present
add_cxx_lib = 'stdc++'
if add_cxx_lib and (add_cxx_lib not in cls.standard_libraries):
cls.standard_libraries.append(add_cxx_lib)
cls.internal_libraries['fygg']['external_dependencies'].append(
add_cxx_lib)
# if add_cxx_lib and (add_cxx_lib not in cls.external_libraries):
# cls.external_libraries[add_cxx_lib] = copy.deepcopy(cxx_orig)
# cls.internal_libraries['fygg']['external_dependencies'].append(
# add_cxx_lib)
# GNU takes precedence when present even if already
# set from clang
add_standard_libraries['c++'] = 'stdc++'
for k, v in add_standard_libraries.items():
# if v not in cls.external_libraries:
# cls.external_libraries[v] = copy.deepcopy(orig_standards.get(k, v))
# cls.internal_libraries['fygg']['external_dependencies'].append(v)
if v not in cls.standard_libraries:
cls.standard_libraries.append(v)
cls.internal_libraries['fygg']['external_dependencies'].append(v)
if platform._is_win: # pragma: windows
cl_compiler = get_compilation_tool('compiler', 'cl')
if not cl_compiler.is_installed(): # pragma: debug
Expand Down

0 comments on commit 478ebe0

Please sign in to comment.