File: CMakeLists.txt

package info (click to toggle)
cmake 3.31.6-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 142,992 kB
  • sloc: ansic: 393,437; cpp: 288,767; sh: 3,958; yacc: 3,240; python: 3,015; lex: 1,337; asm: 438; f90: 429; lisp: 375; cs: 270; java: 266; perl: 217; objc: 212; xml: 198; fortran: 137; makefile: 96; javascript: 83; pascal: 63; tcl: 55; php: 25; ruby: 22
file content (133 lines) | stat: -rw-r--r-- 4,805 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# 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(CheckSourceCompiles)
check_source_compiles(C
"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, PGI
  my_sub__  # GNU g77
  MY_SUB    # Intel on Windows
  mysub     # VisualAge
  mysub_    # GNU, Intel, HP, SunPro, PGI
  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
  _QMmy_modulePmy_sub     # LLVMFlang
  _QMmymodulePmysub       # LLVMFlang
  ${FortranCInterface_MODULE_SYMBOLS}
  )
list(REMOVE_DUPLICATES module_symbols)

# Note that some compiler manglings cannot be invoked from C:
#   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 MY_MODULE.c MYMODULE.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 PUBLIC myfort)

# In case the Fortran compiler produces PIC by default make sure
# the C compiler produces PIC even if it is not its default.
set_property(TARGET symbols PROPERTY POSITION_INDEPENDENT_CODE 1)

if(CMAKE_Fortran_COMPILER_ID STREQUAL "LFortran")
  add_compile_options(--implicit-interface --generate-object-code)
endif()

# Require symbols through Fortran.
add_executable(FortranCInterface main.F call_sub.f ${call_mod})
target_link_libraries(FortranCInterface PUBLIC symbols)

# If IPO is enabled here, GCC gfortran >= 12.0 will obfuscate
# the strings of the return values in the compiled executable,
# which we use to regex match against later.
# The static libraries must be build with IPO and non-IPO objects,
# as that will ensure the verify step will operate on IPO objects,
# if requested by the system compiler flags.
if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" AND
  CMAKE_Fortran_COMPILER_VERSION VERSION_GREATER_EQUAL 12)
  target_compile_options(FortranCInterface PRIVATE "-fno-lto")
  if(NOT APPLE)
    target_compile_options(myfort PRIVATE "-flto=auto" "-ffat-lto-objects")
  endif()
endif()
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND
  CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12)
  if(NOT APPLE)
    target_compile_options(symbols PRIVATE "-flto=auto" "-ffat-lto-objects")
  endif()
endif()

file(GENERATE OUTPUT exe-$<CONFIG>.cmake CONTENT [[
set(FortranCInterface_EXE "$<TARGET_FILE:FortranCInterface>")
]])