• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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