File: stdlib.cmake

package info (click to toggle)
fortran-stdlib 0.8.1-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 34,008 kB
  • sloc: f90: 24,178; ansic: 1,244; cpp: 623; python: 119; makefile: 13
file content (136 lines) | stat: -rw-r--r-- 5,198 bytes parent folder | download
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
134
135
136
# Preprocesses a list of files with given preprocessor and preprocessor options
#
# Args:
#     preproc [in]: Preprocessor program
#     preprocopts [in]: Preprocessor options
#     srcext [in]: File extension of the source files
#     trgext [in]: File extension of the target files
#     srcfiles [in]: List of the source files
#     trgfiles [out]: Contains the list of the preprocessed files on exit
#
function(preprocess preproc preprocopts srcext trgext srcfiles trgfiles)

  set(_trgfiles)
  foreach(srcfile IN LISTS srcfiles)
    get_filename_component(filename ${srcfile} NAME)
    string(REGEX REPLACE "\\.${srcext}$" ".${trgext}" trgfile ${filename})
    add_custom_command(
      OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${trgfile}
      COMMAND ${preproc} ${preprocopts} ${CMAKE_CURRENT_SOURCE_DIR}/${srcfile} ${CMAKE_CURRENT_BINARY_DIR}/${trgfile}
      MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/${srcfile})
    list(APPEND _trgfiles ${CMAKE_CURRENT_BINARY_DIR}/${trgfile})
  endforeach()
  set(${trgfiles} ${_trgfiles} PARENT_SCOPE)

endfunction()



# Preprocesses fortran files with fypp.
#
# It assumes that source files have the ".fypp" extension. Target files will be
# created with the extension ".f90". The FYPP variable must contain the path to
# the fypp-preprocessor.
#
# Args:
#     fyppopts [in]: Options to pass to fypp.
#     fyppfiles [in]: Files to be processed by fypp
#     f90files [out]: List of created f90 files on exit
#
function (fypp_f90 fyppopts fyppfiles f90files)
  preprocess("${FYPP}" "${fyppopts}" "fypp" "f90" "${fyppfiles}" _f90files)
  set(${f90files} ${_f90files} PARENT_SCOPE)
endfunction()

# For fortran sources that contain C preprocessor flags: create ".F90" files 
function (fypp_f90pp fyppopts fyppfiles F90files)
  preprocess("${FYPP}" "${fyppopts}" "fypp" "F90" "${fyppfiles}" _F90files)
  set(${F90files} ${_F90files} PARENT_SCOPE)
endfunction()

# Helper function to configure stdlib targets
#
# It preprocesses the given fypp and fypp+cpp files, combines them with the
# regular Fortran files, and creates a library target with the given name.
# Args:
#     target_name [in]: Name of the library target to create
#     regular_sources_var [in]: Regular Fortran sources
#     fypp_files_var [in]: Sources to be preprocessed with fypp
#     cpp_files_var [in]: Sources to be preprocessed with fypp and cpp
#
function(configure_stdlib_target target_name regular_sources_var fypp_files_var cpp_files_var)
    #### Pre-process: .fpp -> .f90 via Fypp
    fypp_f90("${fyppFlags}" "${${fypp_files_var}}" ${target_name}_fypp_outFiles)
    #### Pre-process: .fypp -> .F90 via Fypp (for C preprocessor directives)
    fypp_f90pp("${fyppFlags}" "${${cpp_files_var}}" ${target_name}_cpp_outFiles)

    list(APPEND all_sources ${${target_name}_fypp_outFiles})
    list(APPEND all_sources ${${target_name}_cpp_outFiles})
    list(APPEND all_sources ${${regular_sources_var}})

    add_library(${target_name} ${all_sources})
    add_library(${PROJECT_NAME}::${target_name} ALIAS ${target_name})

    set_target_properties(
      ${target_name}
      PROPERTIES
      POSITION_INDEPENDENT_CODE ON
      WINDOWS_EXPORT_ALL_SYMBOLS ON
    )

    if(CMAKE_Fortran_COMPILER_ID STREQUAL GNU AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 10.0)
        target_compile_options(
          ${target_name}
          PRIVATE
          $<$<COMPILE_LANGUAGE:Fortran>:-fno-range-check>
        )
    endif()

    set(LIB_MOD_DIR ${CMAKE_CURRENT_BINARY_DIR}/mod_files/${target_name}/)
    #set(INSTALL_MOD_DIR "${CMAKE_INSTALL_MODULEDIR}/${target_name}")
    set(INSTALL_MOD_DIR "${CMAKE_INSTALL_MODULEDIR}")
    # We need the module directory before we finish the configure stage since the
    # build interface might resolve before the module directory is generated by CMake
    if(NOT EXISTS "${LIB_MOD_DIR}")
      file(MAKE_DIRECTORY "${LIB_MOD_DIR}")
    endif()

    set_target_properties(${target_name} PROPERTIES
        Fortran_MODULE_DIRECTORY ${LIB_MOD_DIR}
    )
    target_include_directories(${target_name} PUBLIC
        $<BUILD_INTERFACE:${LIB_MOD_DIR}>
        $<INSTALL_INTERFACE:${CMAKE_INSTALL_MODULEDIR}>
    )

    install(TARGETS ${target_name}
            EXPORT ${PROJECT_NAME}-targets
            RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
            ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
            LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
    )
    install(DIRECTORY ${LIB_MOD_DIR} DESTINATION "${INSTALL_MOD_DIR}")
endfunction()

# Determine if a module will be compiled
#
# Defines a CMake function that creates an ON/OFF option for a given stdlib module,
#sets a compile definition accordingly, and prints its enabled/disabled status.
#
# Args:
#     module [in]: Name of the module to be compiled
#
function(check_modular module)
    string(TOUPPER "${module}" umodule)

    option(STDLIB_${umodule} "Compile STDLIB ${umodule}" ON)

    if(STDLIB_${umodule})
        message(STATUS "Enable stdlib module ${umodule}")
        add_compile_definitions(STDLIB_${umodule}=1)
    else()
        message(STATUS "Disable stdlib module ${umodule}")
        add_compile_definitions(STDLIB_${umodule}=0)
    endif()

endfunction()