ce0bc10c8ef3e638190f46780e61f433f7046254
[platform/upstream/cmake.git] / Modules / FortranCInterface / CMakeLists.txt
1 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2 # file Copyright.txt or https://cmake.org/licensing for details.
3
4 cmake_minimum_required(VERSION ${CMAKE_VERSION})
5 project(FortranCInterface C Fortran)
6 include(${FortranCInterface_BINARY_DIR}/Input.cmake OPTIONAL)
7
8 # Check if the C compiler supports '$' in identifiers.
9 include(CheckCSourceCompiles)
10 check_c_source_compiles("
11 extern int dollar$(void);
12 int main() { return 0; }
13 " C_SUPPORTS_DOLLAR)
14
15 # List manglings of global symbol names to try.
16 set(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   )
26 list(REMOVE_DUPLICATES global_symbols)
27
28 # List manglings of module symbol names to try.
29 set(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   )
48 list(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.
55 if(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)
59 else()
60   set(module_symbols)
61 endif()
62
63 # Generate C symbol sources.
64 set(symbol_sources)
65 if(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)
74 endif()
75 foreach(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()
88 endforeach()
89
90 # Provide symbols through Fortran.
91 add_library(myfort STATIC mysub.f my_sub.f ${myfort_modules})
92
93 # Provide symbols through C but fall back to Fortran.
94 add_library(symbols STATIC ${symbol_sources})
95 target_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.
99 set_property(TARGET symbols PROPERTY POSITION_INDEPENDENT_CODE 1)
100
101 # Require symbols through Fortran.
102 add_executable(FortranCInterface main.F call_sub.f ${call_mod})
103 target_link_libraries(FortranCInterface PUBLIC symbols)
104
105 # If IPO is enabled here, GCC gfortran >= 12.0 will obfuscate
106 # the strings of the return values in the compiled executable,
107 # which we use to regex match against later.
108 # The static libraries must be build with IPO and non-IPO objects,
109 # as that will ensure the verify step will operate on IPO objects,
110 # if requested by the system compiler flags.
111 if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" AND
112   CMAKE_Fortran_COMPILER_VERSION VERSION_GREATER_EQUAL 12)
113   target_compile_options(FortranCInterface PRIVATE "-fno-lto")
114   target_compile_options(myfort PRIVATE "-flto=auto" "-ffat-lto-objects")
115   target_compile_options(symbols PRIVATE "-flto=auto" "-ffat-lto-objects")
116 endif()
117
118 file(GENERATE OUTPUT exe-$<CONFIG>.cmake CONTENT [[
119 set(FortranCInterface_EXE "$<TARGET_FILE:FortranCInterface>")
120 ]])