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()
|