1 # WRF Macro for C preprocessing F files that are just... bad ifdef usage to say the least
2 macro( wrf_c_preproc_fortran )
5 set( oneValueArgs TARGET_NAME SUFFIX PREFIX EXTENSION OUTPUT_DIR )
6 set( multiValueArgs DEPENDENCIES INCLUDES SOURCES DEFINITIONS TARGET_SCOPE )
10 "${options}" "${oneValueArgs}" "${multiValueArgs}"
15 if ( DEFINED WRF_PP_F_TARGET_SCOPE )
16 set( WRF_PP_F_TARGET_DIRECTORY TARGET_DIRECTORY ${WRF_PP_F_TARGET_SCOPE} )
19 set( WRF_PP_F_INCLUDES_FLAGS )
20 foreach( WRF_PP_F_INC ${WRF_PP_F_INCLUDES} )
21 list( APPEND WRF_PP_F_INCLUDES_FLAGS -I${WRF_PP_F_INC} )
24 wrf_expand_definitions(
25 RESULT_VAR WRF_PP_F_DEFS
26 DEFINITIONS ${WRF_PP_F_DEFINITIONS}
29 # Generate compile command and file outputs
30 set( WRF_PP_F_OUTPUT )
31 set( WRF_PP_F_COMMANDS )
32 foreach( WRF_PP_F_SOURCE_FILE ${WRF_PP_F_SOURCES} )
33 get_filename_component( WRF_PP_F_INPUT_SOURCE ${WRF_PP_F_SOURCE_FILE} REALPATH )
34 get_filename_component( WRF_PP_F_INPUT_SOURCE_FILE_ONLY ${WRF_PP_F_SOURCE_FILE} NAME )
36 if ( ${WRF_PP_F_EXTENSION} MATCHES "^[.][a-z0-9]+$" )
37 string( REGEX REPLACE "[.].*$" "${WRF_PP_F_EXTENSION}" WRF_PP_F_OUTPUT_FILE ${WRF_PP_F_INPUT_SOURCE_FILE_ONLY} )
40 string( REGEX REPLACE "[.].*$" ".i" WRF_PP_F_OUTPUT_FILE ${WRF_PP_F_INPUT_SOURCE_FILE_ONLY} )
43 set( WRF_PP_F_OUTPUT_FILE ${WRF_PP_F_OUTPUT_DIR}/${WRF_PP_F_PREFIX}${WRF_PP_F_OUTPUT_FILE}${WRF_PP_F_SUFFIX} )
46 APPEND WRF_PP_F_COMMANDS
47 COMMAND ${CMAKE_C_PREPROCESSOR} ${CMAKE_C_PREPROCESSOR_FLAGS} ${WRF_PP_F_INPUT_SOURCE} ${WRF_PP_F_DEFS} ${WRF_PP_F_INCLUDES_FLAGS} > ${WRF_PP_F_OUTPUT_FILE}
48 # Force check that they were made
49 COMMAND ${CMAKE_COMMAND} -E compare_files ${WRF_PP_F_OUTPUT_FILE} ${WRF_PP_F_OUTPUT_FILE}
52 APPEND WRF_PP_F_OUTPUT
53 ${WRF_PP_F_OUTPUT_FILE}
56 # # Tell all targets that eventually use this file that it is generated - this is useful if this macro is used in a
57 # # different directory than where the target dependency is set
58 # # Thanks to https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#how-can-i-add-a-dependency-to-a-source-file-which-is-generated-in-a-subdirectory
59 # # and https://samthursfield.wordpress.com/2015/11/21/cmake-dependencies-between-targets-and-files-and-custom-commands/
60 # # It keeps getting better lol
61 # # https://gitlab.kitware.com/cmake/cmake/-/issues/18399
62 # # We could use cmake 3.20+ and CMP0118, but this allows usage from 3.18.6+
63 # TL;DR - This doesn't work despite all documentation stating otherwise, need to use CMP0118
64 # set_source_files_properties(
65 # ${WRF_PP_F_OUTPUT_FILE}
66 # ${WRF_PP_F_TARGET_DIRECTORY}
70 set_source_files_properties(
71 ${WRF_PP_F_OUTPUT_FILE}
72 DIRECTORY ${PROJECT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
73 ${WRF_PP_F_TARGET_DIRECTORY}
75 Fortran_PREPROCESS OFF
77 # message( STATUS "File ${WRF_PP_F_SOURCE_FILE} will be preprocessed into ${WRF_PP_F_OUTPUT_FILE}" )
81 # Preprocess sources into a custom target
83 OUTPUT ${WRF_PP_F_OUTPUT}
84 COMMAND ${CMAKE_COMMAND} -E make_directory ${WRF_PP_F_OUTPUT_DIR}
86 COMMENT "Preprocessing ${WRF_PP_F_TARGET_NAME}"
87 DEPENDS ${WRF_PP_F_DEPENDENCIES}
91 ${WRF_PP_F_TARGET_NAME}
92 COMMENT "Building ${WRF_PP_F_TARGET_NAME}"
93 DEPENDS ${WRF_PP_F_OUTPUT}
98 # Helper macro to take current defintions and santize them with -D, compatible with generator expressions
99 # for use when definitions are needed at generation time for custom commands
100 macro( wrf_expand_definitions )
102 set( oneValueArgs RESULT_VAR )
103 set( multiValueArgs DEFINITIONS )
105 cmake_parse_arguments(
107 "${options}" "${oneValueArgs}" "${multiValueArgs}"
112 foreach( WRF_EXP_DEF ${WRF_EXP_DEFINITIONS} )
113 if ( NOT ${WRF_EXP_DEF} MATCHES ".*-D.*" )
114 # We have a generator expression, error! no way we can evaluate this correctly
115 if ( ${WRF_EXP_DEF} MATCHES "^[$]<" )
116 message( FATAL_ERROR "Generator expressions not allowed in preprocessing defines" )
118 list( APPEND WRF_EXP_DEFS -D${WRF_EXP_DEF} )
121 # Just add it normally
122 list( APPEND WRF_EXP_DEFS ${WRF_EXP_DEF} )
127 set( ${WRF_EXP_RESULT_VAR} ${WRF_EXP_DEFS} )