CMake/Modules/FortranCInterface/CMakeLists.txt

101 lines
3.4 KiB
CMake

# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
cmake_minimum_required(VERSION ${CMAKE_VERSION})
project(FortranCInterface C Fortran)
include(${FortranCInterface_BINARY_DIR}/Input.cmake OPTIONAL)
# Check if the C compiler supports '$' in identifiers.
include(CheckCSourceCompiles)
check_c_source_compiles("
extern int dollar$(void);
int main() { return 0; }
" C_SUPPORTS_DOLLAR)
# List manglings of global symbol names to try.
set(global_symbols
my_sub # VisualAge
my_sub_ # GNU, Intel, HP, SunPro, MIPSpro
my_sub__ # GNU g77
MY_SUB # Intel on Windows
mysub # VisualAge
mysub_ # GNU, Intel, HP, SunPro, MIPSpro
MYSUB # Intel on Windows
${FortranCInterface_GLOBAL_SYMBOLS}
)
list(REMOVE_DUPLICATES global_symbols)
# List manglings of module symbol names to try.
set(module_symbols
__my_module_MOD_my_sub # GNU 4.3
__my_module_NMOD_my_sub # VisualAge
__my_module__my_sub # GNU 4.2
__mymodule_MOD_mysub # GNU 4.3
__mymodule_NMOD_mysub # VisualAge
__mymodule__mysub # GNU 4.2
my_module$my_sub # HP
my_module_mp_my_sub_ # Intel
MY_MODULE_mp_MY_SUB # Intel on Windows
my_module_my_sub_ # PGI
my_module_MP_my_sub # NAG
mymodule$mysub # HP
mymodule_mp_mysub_ # Intel
MYMODULE_mp_MYSUB # Intel on Windows
mymodule_mysub_ # PGI
mymodule_MP_mysub # NAG
${FortranCInterface_MODULE_SYMBOLS}
)
list(REMOVE_DUPLICATES module_symbols)
# Note that some compiler manglings cannot be invoked from C:
# MIPSpro uses "MY_SUB.in.MY_MODULE"
# SunPro uses "my_module.my_sub_"
# PathScale uses "MY_SUB.in.MY_MODULE"
# Add module symbols only with Fortran90.
if(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
set(myfort_modules mymodule.f90 my_module.f90)
set(call_mod call_mod.f90)
set_property(SOURCE main.F PROPERTY COMPILE_DEFINITIONS CALL_MOD)
else()
set(module_symbols)
endif()
# Generate C symbol sources.
set(symbol_sources)
if(NOT CMAKE_Fortran_COMPILER_ID MATCHES "^(PathScale|Cray)$")
# Provide mymodule_ and my_module_ init symbols because:
# - PGI Fortran uses module init symbols
# but not for:
# - PathScale Fortran uses module init symbols but module symbols
# use '.in.' so we cannot provide them anyway.
# - Cray Fortran >= 7.3.2 uses module init symbols but module symbols
# use 'mysub$mymodule_' so we cannot provide them anyway.
list(APPEND symbol_sources mymodule_.c my_module_.c)
endif()
foreach(symbol IN LISTS global_symbols module_symbols)
# Skip symbols with '$' if C cannot handle them.
if(C_SUPPORTS_DOLLAR OR NOT "${symbol}" MATCHES "\\$")
if("${symbol}" MATCHES "SUB")
set(upper "-UPPER")
else()
set(upper)
endif()
string(REPLACE "$" "S" name "${symbol}")
set(source ${CMAKE_CURRENT_BINARY_DIR}/symbols/${name}${upper}.c)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/symbol.c.in ${source} @ONLY)
list(APPEND symbol_sources ${source})
endif()
endforeach()
# Provide symbols through Fortran.
add_library(myfort STATIC mysub.f my_sub.f ${myfort_modules})
# Provide symbols through C but fall back to Fortran.
add_library(symbols STATIC ${symbol_sources})
target_link_libraries(symbols myfort)
# Require symbols through Fortran.
add_executable(FortranCInterface main.F call_sub.f ${call_mod})
target_link_libraries(FortranCInterface symbols)