1# Distributed under the OSI-approved BSD 3-Clause License. See accompanying 2# file Copyright.txt or https://cmake.org/licensing for details. 3 4cmake_minimum_required(VERSION ${CMAKE_VERSION}) 5project(FortranCInterface C Fortran) 6include(${FortranCInterface_BINARY_DIR}/Input.cmake OPTIONAL) 7 8# Check if the C compiler supports '$' in identifiers. 9include(CheckCSourceCompiles) 10check_c_source_compiles(" 11extern int dollar$(void); 12int main() { return 0; } 13" C_SUPPORTS_DOLLAR) 14 15# List manglings of global symbol names to try. 16set(global_symbols 17 my_sub # VisualAge 18 my_sub_ # GNU, Intel, HP, SunPro, PGI 19 my_sub__ # GNU g77 20 MY_SUB # Intel on Windows 21 mysub # VisualAge 22 mysub_ # GNU, Intel, HP, SunPro, PGI 23 MYSUB # Intel on Windows 24 ${FortranCInterface_GLOBAL_SYMBOLS} 25 ) 26list(REMOVE_DUPLICATES global_symbols) 27 28# List manglings of module symbol names to try. 29set(module_symbols 30 __my_module_MOD_my_sub # GNU 4.3 31 __my_module_NMOD_my_sub # VisualAge 32 __my_module__my_sub # GNU 4.2 33 __mymodule_MOD_mysub # GNU 4.3 34 __mymodule_NMOD_mysub # VisualAge 35 __mymodule__mysub # GNU 4.2 36 my_module$my_sub # HP 37 my_module_mp_my_sub_ # Intel 38 MY_MODULE_mp_MY_SUB # Intel on Windows 39 my_module_my_sub_ # PGI 40 my_module_MP_my_sub # NAG 41 mymodule$mysub # HP 42 mymodule_mp_mysub_ # Intel 43 MYMODULE_mp_MYSUB # Intel on Windows 44 mymodule_mysub_ # PGI 45 mymodule_MP_mysub # NAG 46 ${FortranCInterface_MODULE_SYMBOLS} 47 ) 48list(REMOVE_DUPLICATES module_symbols) 49 50# Note that some compiler manglings cannot be invoked from C: 51# SunPro uses "my_module.my_sub_" 52# PathScale uses "MY_SUB.in.MY_MODULE" 53 54# Add module symbols only with Fortran90. 55if(CMAKE_Fortran_COMPILER_SUPPORTS_F90) 56 set(myfort_modules mymodule.f90 my_module.f90) 57 set(call_mod call_mod.f90) 58 set_property(SOURCE main.F PROPERTY COMPILE_DEFINITIONS CALL_MOD) 59else() 60 set(module_symbols) 61endif() 62 63# Generate C symbol sources. 64set(symbol_sources) 65if(NOT CMAKE_Fortran_COMPILER_ID MATCHES "^(PathScale|Cray)$") 66 # Provide mymodule_ and my_module_ init symbols because: 67 # - PGI Fortran uses module init symbols 68 # but not for: 69 # - PathScale Fortran uses module init symbols but module symbols 70 # use '.in.' so we cannot provide them anyway. 71 # - Cray Fortran >= 7.3.2 uses module init symbols but module symbols 72 # use 'mysub$mymodule_' so we cannot provide them anyway. 73 list(APPEND symbol_sources mymodule_.c my_module_.c MY_MODULE.c MYMODULE.c) 74endif() 75foreach(symbol IN LISTS global_symbols module_symbols) 76 # Skip symbols with '$' if C cannot handle them. 77 if(C_SUPPORTS_DOLLAR OR NOT "${symbol}" MATCHES "\\$") 78 if("${symbol}" MATCHES "SUB") 79 set(upper "-UPPER") 80 else() 81 set(upper) 82 endif() 83 string(REPLACE "$" "S" name "${symbol}") 84 set(source ${CMAKE_CURRENT_BINARY_DIR}/symbols/${name}${upper}.c) 85 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/symbol.c.in ${source} @ONLY) 86 list(APPEND symbol_sources ${source}) 87 endif() 88endforeach() 89 90# Provide symbols through Fortran. 91add_library(myfort STATIC mysub.f my_sub.f ${myfort_modules}) 92 93# Provide symbols through C but fall back to Fortran. 94add_library(symbols STATIC ${symbol_sources}) 95target_link_libraries(symbols PUBLIC myfort) 96 97# In case the Fortran compiler produces PIC by default make sure 98# the C compiler produces PIC even if it is not its default. 99set_property(TARGET symbols PROPERTY POSITION_INDEPENDENT_CODE 1) 100 101# Require symbols through Fortran. 102add_executable(FortranCInterface main.F call_sub.f ${call_mod}) 103target_link_libraries(FortranCInterface PUBLIC symbols) 104 105file(GENERATE OUTPUT exe-$<CONFIG>.cmake CONTENT [[ 106set(FortranCInterface_EXE "$<TARGET_FILE:FortranCInterface>") 107]]) 108