CMake netCDF Compatibility with WPS (#2121)
[WRF.git] / cmake / m4_preproc.cmake
blob4158795578ace2b3ba70661165551dc7033496a0
1 # WRF Macro for m4 preprocessing F files
2 macro( wrf_m4_preproc_fortran )
4   set( options        )
5   set( oneValueArgs   TARGET_NAME SUFFIX PREFIX EXTENSION OUTPUT_DIR M4_PROGRAM )
6   set( multiValueArgs DEPENDENCIES SOURCES FLAGS TARGET_SCOPE )
8   cmake_parse_arguments(
9                         WRF_PP_M4
10                         "${options}"  "${oneValueArgs}"  "${multiValueArgs}"
11                         ${ARGN}
12                         )
13   set( WRF_PP_M4_PROGRAM_TO_USE m4 )
14   if ( DEFINED WRF_PP_M4_PROGRAM )
15     set( WRF_PP_M4_PROGRAM_TO_USE ${WRF_PP_M4_PROGRAM} )
16   endif()
18   # Santitize input
19   if ( DEFINED WRF_PP_M4_TARGET_SCOPE )
20     set( WRF_PP_M4_TARGET_DIRECTORY TARGET_DIRECTORY ${WRF_PP_M4_TARGET_SCOPE} )
21   endif()
23   # Generate compile command and file outputs
24   set( WRF_PP_M4_OUTPUT   )
25   set( WRF_PP_M4_COMMANDS )
26   foreach( WRF_PP_M4_SOURCE_FILE  ${WRF_PP_M4_SOURCES} )
27     get_filename_component( WRF_PP_M4_INPUT_SOURCE           ${WRF_PP_M4_SOURCE_FILE} REALPATH )
28     get_filename_component( WRF_PP_M4_INPUT_SOURCE_FILE_ONLY ${WRF_PP_M4_SOURCE_FILE} NAME     )
30     if ( ${WRF_PP_M4_EXTENSION} MATCHES "^[.][a-z0-9]+$" )
31       string( REGEX REPLACE "[.].*$" "${WRF_PP_M4_EXTENSION}" WRF_PP_M4_OUTPUT_FILE ${WRF_PP_M4_INPUT_SOURCE_FILE_ONLY} )
32     else()
33       # Default extension
34       string( REGEX REPLACE "[.].*$" ".i" WRF_PP_M4_OUTPUT_FILE ${WRF_PP_M4_INPUT_SOURCE_FILE_ONLY} )
35     endif()
37     set( WRF_PP_M4_OUTPUT_FILE ${WRF_PP_M4_OUTPUT_DIR}/${WRF_PP_M4_PREFIX}${WRF_PP_M4_OUTPUT_FILE}${WRF_PP_M4_SUFFIX} )
38     
39     list( 
40           APPEND WRF_PP_M4_COMMANDS 
41           COMMAND ${WRF_PP_M4_PROGRAM_TO_USE} ${WRF_PP_M4_FLAGS} ${WRF_PP_M4_INPUT_SOURCE} > ${WRF_PP_M4_OUTPUT_FILE}
42           # Force check that they were made
43           COMMAND ${CMAKE_COMMAND} -E compare_files ${WRF_PP_M4_OUTPUT_FILE} ${WRF_PP_M4_OUTPUT_FILE}
44           )
45     list( 
46           APPEND WRF_PP_M4_OUTPUT
47           ${WRF_PP_M4_OUTPUT_FILE}
48           )
49     
50     # # Tell all targets that eventually use this file that it is generated - this is useful if this macro is used in a
51     # # different directory than where the target dependency is set
52     # # 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
53     # # and https://samthursfield.wordpress.com/2015/11/21/cmake-dependencies-between-targets-and-files-and-custom-commands/
54     # # It keeps getting better lol
55     # # https://gitlab.kitware.com/cmake/cmake/-/issues/18399
56     # # We could use cmake 3.20+ and CMP0118, but this allows usage from 3.18.6+
57     # TL;DR - This doesn't work despite all documentation stating otherwise, need to use CMP0118
58     # set_source_files_properties(
59     #                             ${WRF_PP_M4_OUTPUT_FILE}
60     #                             ${WRF_PP_M4_TARGET_DIRECTORY}
61     #                             PROPERTIES
62     #                               GENERATED TRUE
63     #                             )
64     set_source_files_properties(
65                                 ${WRF_PP_M4_OUTPUT_FILE}
66                                 DIRECTORY ${PROJECT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
67                                 ${WRF_PP_M4_TARGET_DIRECTORY}
68                                 PROPERTIES
69                                   Fortran_PREPROCESS OFF
70                                 )
71     # message( STATUS "File ${WRF_PP_M4_SOURCE_FILE} will be preprocessed into ${WRF_PP_M4_OUTPUT_FILE}" )
73   endforeach()
75   # Preprocess sources into a custom target
76   add_custom_command(
77                       OUTPUT ${WRF_PP_M4_OUTPUT}
78                       COMMAND ${CMAKE_COMMAND} -E  make_directory ${WRF_PP_M4_OUTPUT_DIR}
79                       ${WRF_PP_M4_COMMANDS}
80                       COMMENT "Preprocessing ${WRF_PP_M4_TARGET_NAME}"
81                       DEPENDS ${WRF_PP_M4_DEPENDENCIES}
82                       )
84   add_custom_target(
85                     ${WRF_PP_M4_TARGET_NAME}
86                     DEPENDS ${WRF_PP_M4_OUTPUT}
87                     )
88 endmacro()