Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CMake WRFPLUS #2089

Open
wants to merge 13 commits into
base: release-v4.6.1
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
647 changes: 431 additions & 216 deletions CMakeLists.txt

Large diffs are not rendered by default.

63 changes: 13 additions & 50 deletions arch/configure_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
osAndArchAlt = re.compile( r"^ARCH[ ]+(\w+)[ ]+(\w+)", re.I )

referenceVar = re.compile( r"[$]([(])?(\w+)(?(1)[)])", re.I )
compileObject = re.compile( r"(\W)-c(\W)" )
compileObject = re.compile( r"(\W|^)-c(\W|$)" )
configureRepl = re.compile( r"(\W|^)CONFIGURE_\w+(\W|$)" )

class Stanza():

Expand Down Expand Up @@ -160,52 +161,9 @@ def sanitize( self ) :
self.dereference( "FCBASEOPTS" )

# Remove rogue compile commands that should *NOT* even be here
keysToSanitize = [
"ARFLAGS","ARFLAGS",
"CC",
"CFLAGS_LOCAL",
"CFLAGS",
"COMPRESSION_INC",
"COMPRESSION_LIBS",
"CPP",
"CPPFLAGS",
"DM_CC",
"DM_FC",
"ESMF_LDFLAG",
"F77FLAGS",
"FC",
"FCBASEOPTS_NO_G",
"FCBASEOPTS",
"FCOPTIM",
"FCSUFFIX",
"FDEFS",
"FFLAGS",
"FNGFLAGS",
"FORMAT_FIXED",
"FORMAT_FREE",
"LD",
"LDFLAGS_LOCAL",
"LDFLAGS",
"MODULE_SRCH_FLAG",
"RLFLAGS",
"SCC",
"SFC",
"TRADFLAG",
]

for keyToSan in keysToSanitize :
if keyToSan in self.kvPairs_ :
self.kvPairs_[ keyToSan ] = self.kvPairs_[ keyToSan ].replace( "CONFIGURE_COMP_L", "" )
self.kvPairs_[ keyToSan ] = self.kvPairs_[ keyToSan ].replace( "CONFIGURE_COMP_I", "" )
self.kvPairs_[ keyToSan ] = self.kvPairs_[ keyToSan ].replace( "CONFIGURE_FC", "" )
self.kvPairs_[ keyToSan ] = self.kvPairs_[ keyToSan ].replace( "CONFIGURE_CC", "" )
self.kvPairs_[ keyToSan ] = self.kvPairs_[ keyToSan ].replace( "CONFIGURE_FDEFS", "" )
self.kvPairs_[ keyToSan ] = self.kvPairs_[ keyToSan ].replace( "CONFIGURE_MPI", "" )
self.kvPairs_[ keyToSan ] = self.kvPairs_[ keyToSan ].replace( "CONFIGURE_COMPAT_FLAGS", "" )
self.kvPairs_[ keyToSan ] = self.kvPairs_[ keyToSan ].replace( "CONFIGURE_CPPFLAGS", "" )
self.kvPairs_[ keyToSan ] = self.kvPairs_[ keyToSan ].replace( "CONFIGURE_TRADFLAG", "" )

self.kvPairs_[ keyToSan ] = compileObject.sub( r"\1\2", self.kvPairs_[ keyToSan ] ).strip()
for keyToSan in self.kvPairs_.keys() :
self.kvPairs_[ keyToSan ] = configureRepl.sub( r"\1\2", self.kvPairs_[ keyToSan ] ).strip()
self.kvPairs_[ keyToSan ] = compileObject.sub( r"\1\2", self.kvPairs_[ keyToSan ] ).strip()


# Now fix certain ones that are mixing programs with flags all mashed into one option
Expand Down Expand Up @@ -546,6 +504,7 @@ def generateCMakeToolChainFile( cmakeToolChainTemplate, output, stanza, optionsD

configStanza = cmakeToolChainTemplateLines.format(
ARCH_LOCAL=stanza.kvPairs_["ARCH_LOCAL"],
LDFLAGS_LOCAL=stanza.kvPairs_["LDFLAGS_LOCAL"],
BYTESWAPIO=stanza.kvPairs_["BYTESWAPIO"],
CFLAGS_LOCAL=stanza.kvPairs_["CFLAGS_LOCAL"],
DM_CC=stanza.kvPairs_["DM_CC"],
Expand Down Expand Up @@ -575,8 +534,12 @@ def generateCMakeToolChainFile( cmakeToolChainTemplate, output, stanza, optionsD

def projectSpecificOptions( options, stanzaCfg ) :
coreOption = getStringOptionSelection( options.sourceCMakeFile, "WRF_CORE_OPTIONS", "WRF_CORE" )
nestingOption = getStringOptionSelection( options.sourceCMakeFile, "WRF_NESTING_OPTIONS", "WRF_NESTING", 1 )
caseOption = getStringOptionSelection( options.sourceCMakeFile, "WRF_CASE_OPTIONS", "WRF_CASE" )
if coreOption == "ARW" :
nestingOption = getStringOptionSelection( options.sourceCMakeFile, "WRF_NESTING_OPTIONS", "WRF_NESTING", 1 )
caseOption = getStringOptionSelection( options.sourceCMakeFile, "WRF_CASE_OPTIONS", "WRF_CASE" )
else :
nestingOption = "NONE"
caseOption = "NONE"

# These are yes
yesValues = [ "yes", "y", "true", "1" ]
Expand Down Expand Up @@ -625,4 +588,4 @@ def projectSpecificOptions( options, stanzaCfg ) :
return additionalOptions

if __name__ == '__main__' :
main()
main()
15 changes: 14 additions & 1 deletion chem/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -223,4 +223,17 @@ target_link_libraries(
convert_emiss
PRIVATE
${PROJECT_NAME}_Core
)
)

target_compile_options(
convert_emiss
PRIVATE
${PROJECT_COMPILE_OPTIONS}
)


target_compile_definitions(
convert_emiss
PRIVATE
${PROJECT_COMPILE_DEFINITIONS}
)
12 changes: 5 additions & 7 deletions cmake/c_preproc.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -111,17 +111,15 @@ macro( wrf_expand_definitions )
set( WRF_EXP_DEFS )
foreach( WRF_EXP_DEF ${WRF_EXP_DEFINITIONS} )
if ( NOT ${WRF_EXP_DEF} MATCHES ".*-D.*" )
# We have a generator expression, inject the -D correctly
# THIS SHOULD ONLY BE USED FOR CONDITIONALLY APPLIED DEFINITIONS
# We have a generator expression, error! no way we can evaluate this correctly
if ( ${WRF_EXP_DEF} MATCHES "^[$]<" )
# Take advantage of the fact that a define is most likely not an expanded variable (i.e. starts with a-zA-Z, adjust if not)
# preceeded by the defining generator expression syntax $<<condition>>:var or <condition>,var
# Yes this is fragile but is probably more robust than the current code if you're relying on this macro :D
string( REGEX REPLACE "(>:|,)([a-zA-Z])" "\\1-D\\2" WRF_EXP_DEF_SANITIZED ${WRF_EXP_DEF} )
list( APPEND WRF_EXP_DEFS ${WRF_EXP_DEF_SANITIZED} )
message( FATAL_ERROR "Generator expressions not allowed in preprocessing defines" )
else()
list( APPEND WRF_EXP_DEFS -D${WRF_EXP_DEF} )
endif()
else()
# Just add it normally
list( APPEND WRF_EXP_DEFS ${WRF_EXP_DEF} )
endif()

endforeach()
Expand Down
142 changes: 142 additions & 0 deletions cmake/target_source_properties.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
#
# These two functions together allow greater control of propagating flags within
# a target on a per-source basis with the ability to "inherit" those properties
# from the target if not set. This allows a target to defing its own flags, but
# then if a file needs different settings those can be directly overridden without
# relying on compiler-specific flag order precedence. Additionally this allows a
# project to organize grouping of flags within a target
#
# Note that for compile defines on source files they are not used in the autogen
# dependency scanning. See :
# https://gitlab.kitware.com/cmake/cmake/-/issues/22519
# and
# https://gitlab.kitware.com/cmake/cmake/-/blob/master/Source/cmDependsFortran.cxx#L84
# functions cmDependsFortran::cmDependsFortran() and cmDependsFortran::WriteDependencies()
#
# The solution is to either use Ninja or preprocess the files (what Ninja internally does)
# This is probably the way to go as well since CMake native preprocessor directive
# parsing is... subpar and simplified :
# https://gitlab.kitware.com/cmake/cmake/-/issues/17398
#
# Alternatively, set critical flags at the target level
#



#
# A simple function to create properties for targets and sources quickly
#
function( define_target_source_properties )
set( options )
set( oneValueArgs )
set( multiValueArgs PROPERTIES )

cmake_parse_arguments(
FUNC_PROP
"${options}" "${oneValueArgs}" "${multiValueArgs}"
${ARGN}
)

foreach( PROPERTY ${FUNC_PROP_PROPERTIES} )
define_property(
SOURCE
PROPERTY ${PROPERTY}
# INHERITED # they will be "inherited" via target to source
)

define_property(
TARGET
PROPERTY ${PROPERTY}
# INHERITED # they will be "inherited" via target to source
)
endforeach()
endfunction()


#
# The bulk of the functionality exists in this function. It will loop over each
# provided target, gathering sources and their respective properties listed, using
# the target's property if not defined for this source else nothing, and finally
# applies it to that source.
#
function( apply_target_source_properties )
set( options DISCARD_PREVIOUS DEBUG )
set( oneValueArgs AS_PROPERTY )
set( multiValueArgs TARGETS PROPERTIES )

cmake_parse_arguments(
FUNC_PROP
"${options}" "${oneValueArgs}" "${multiValueArgs}"
${ARGN}
)

foreach( TARGET ${FUNC_PROP_TARGETS} )
# get target sources
get_target_property( TARGET_SOURCES ${TARGET} SOURCES )

# get default "inherited" value from target
foreach( PROPERTY ${FUNC_PROP_PROPERTIES} )
get_target_property( TARGET_PROPERTY_${PROPERTY} ${TARGET} ${PROPERTY} )
if ( "${TARGET_PROPERTY_${PROPERTY}}" STREQUAL "TARGET_PROPERTY_${PROPERTY}-NOTFOUND" )
# unset it
set( TARGET_PROPERTY_${PROPERTY} )
endif()
endforeach()

foreach( SOURCE ${TARGET_SOURCES} )

# We need to accumulate properties since a call to set property will
# override what was there before
set( SOURCE_PROPERTY_ALL )

foreach( PROPERTY ${FUNC_PROP_PROPERTIES} )
# first try source
get_source_file_property(
SOURCE_PROPERTY_${PROPERTY}
${SOURCE}
TARGET_DIRECTORY ${TARGET}
${PROPERTY}
)
if ( "${SOURCE_PROPERTY_${PROPERTY}}" STREQUAL "NOTFOUND" )
# use target
set( SOURCE_PROPERTY_${PROPERTY} ${TARGET_PROPERTY_${PROPERTY}} )
endif()

# Now apply these as prop
if ( NOT "${SOURCE_PROPERTY_${PROPERTY}}" STREQUAL "" )
if ( ${FUNC_PROP_DEBUG} )
message( STATUS "DEBUG : Adding '${SOURCE_PROPERTY_${PROPERTY}}' as SOURCE_PROPERTY_${PROPERTY}")
endif()
list( APPEND SOURCE_PROPERTY_ALL ${SOURCE_PROPERTY_${PROPERTY}} )
endif()
endforeach() # properties

# Apply properties to source
if ( NOT "${SOURCE_PROPERTY_ALL}" STREQUAL "" )
if ( NOT ${FUNC_PROP_DISCARD_PREVIOUS} )
# get old value and append
get_source_file_property(
SOURCE_PROPERTY_ORIG
${SOURCE}
TARGET_DIRECTORY ${TARGET}
${FUNC_PROP_AS_PROPERTY}
)
if ( "${SOURCE_PROPERTY_ORIG}" STREQUAL "NOTFOUND" )
set( SOURCE_PROPERTY_ORIG )
endif()
endif()

if ( ${FUNC_PROP_DEBUG} )
message( STATUS "DEBUG : ${FUNC_PROP_AS_PROPERTY} being set to '${SOURCE_PROPERTY_ORIG} ${SOURCE_PROPERTY_ALL}'")
endif()

set_source_files_properties(
${SOURCE}
TARGET_DIRECTORY ${TARGET}
PROPERTIES
${FUNC_PROP_AS_PROPERTY} "${SOURCE_PROPERTY_ORIG};${SOURCE_PROPERTY_ALL}"
)
endif()
endforeach() # sources
endforeach() # targets
endfunction()
21 changes: 11 additions & 10 deletions cmake/template/arch_config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@ set( CMAKE_Fortran_FLAGS_INIT "{SFC_FLAGS} {FCBASEOPTS} {BYTESWAPIO}" )
set( CMAKE_C_FLAGS_INIT "{SCC_FLAGS} {CFLAGS_LOCAL}" )

# https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_FLAGS_CONFIG_INIT.html
set( CMAKE_Fortran_FLAGS_DEBUG_INIT "{FCDEBUG}" )
set( CMAKE_Fortran_FLAGS_RELEASE_INIT "" )
set( CMAKE_C_FLAGS_DEBUG_INIT "" )
set( CMAKE_C_FLAGS_RELEASE_INIT "" )
set( CMAKE_Fortran_FLAGS_Debug_INIT "{FCDEBUG}" )
set( CMAKE_Fortran_FLAGS_Release_INIT "" )
set( CMAKE_C_FLAGS_Debug_INIT "" )
set( CMAKE_C_FLAGS_Release_INIT "" )

# Project specifics now
set( WRF_MPI_Fortran_FLAGS "{DM_FC_FLAGS}" )
set( WRF_MPI_C_FLAGS "{DM_CC_FLAGS}" )
set( WRF_ARCH_LOCAL "{ARCH_LOCAL}" )
set( WRF_M4_FLAGS "{M4_FLAGS}" )
set( WRF_FCOPTIM "{FCOPTIM}" )
set( WRF_FCNOOPT "{FCNOOPT}" )
set( WRF_MPI_Fortran_FLAGS "{DM_FC_FLAGS}" )
set( WRF_MPI_C_FLAGS "{DM_CC_FLAGS}" )
set( WRF_ARCH_LOCAL "{ARCH_LOCAL}" )
set( WRF_M4_FLAGS "{M4_FLAGS}" )
set( WRF_FCOPTIM "{FCOPTIM}" )
set( WRF_FCNOOPT "{FCNOOPT}" )
set( WRF_LINK_FLAGS "{LDFLAGS_LOCAL}" )
45 changes: 45 additions & 0 deletions cmake/wrf_case_setup.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,51 @@ macro( wrf_setup_targets )

endmacro()

# WRF Macro for adding target symlinks/copies to be run after internal install() code
# this allows for alternate naming
macro( wrf_setup_target_new_name )

set( options USE_SYMLINKS )
set( oneValueArgs TARGET DEST_PATH NEW_NAME )
set( multiValueArgs )

cmake_parse_arguments(
WRF_SETUP
"${options}" "${oneValueArgs}" "${multiValueArgs}"
${ARGN}
)
set( WRF_SETUP_CMD copy_if_different )
if ( ${WRF_SETUP_USE_SYMLINKS} )
set( WRF_SETUP_CMD create_symlink )
endif()

# Generate install code for each target
# https://stackoverflow.com/a/56528615
#!TODO Do we *need* the rm for symlinks beforehand?
# get_filename_component( WRF_SETUP_FILE_ONLY $<TARGET_FILE:${WRF_SETUP_TARGET}> NAME

# If we ever wanted to link or copy things other than binaries we could change this
set( WRF_SETUP_INSTALL_LOCATION ${CMAKE_INSTALL_PREFIX}/bin )

install(
CODE "
message( STATUS \"Setting up $<TARGET_FILE_NAME:${WRF_SETUP_TARGET}> via ${WRF_SETUP_CMD} as ${WRF_SETUP_NEW_NAME}\" )
execute_process( COMMAND ${CMAKE_COMMAND} -E ${WRF_SETUP_CMD} ${WRF_SETUP_INSTALL_LOCATION}/$<TARGET_FILE_NAME:${WRF_SETUP_TARGET}> ${WRF_SETUP_DEST_PATH}/${WRF_SETUP_NEW_NAME} )
"
COMPONENT setup
)

# Add .exe link as well
install(
CODE "
message( STATUS \"Creating symlink for ${WRF_SETUP_NEW_NAME}.exe\" )
execute_process( COMMAND ${CMAKE_COMMAND} -E create_symlink ${WRF_SETUP_DEST_PATH}/${WRF_SETUP_NEW_NAME} ${WRF_SETUP_DEST_PATH}/${WRF_SETUP_NEW_NAME}.exe )
"
COMPONENT setup
)

endmacro()

# WRF Macro for adding file symlinks/copies to be run after internal install() code
macro( wrf_setup_files )

Expand Down
4 changes: 4 additions & 0 deletions external/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@

# Always build

# Suffice it to say everything under this is WRF-specific while also being external
add_compile_options ( "${PROJECT_COMPILE_OPTIONS}" )
add_compile_definitions( "${PROJECT_COMPILE_DEFINITIONS}" )

add_subdirectory( io_int )
add_subdirectory( io_grib1 )
add_subdirectory( io_grib_share )
Expand Down
3 changes: 1 addition & 2 deletions external/io_adios2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,13 @@ target_include_directories( ${FOLDER_COMPILE_TARGET}


# First preprocess
get_directory_property( DIR_DEFS DIRECTORY ${CMAKE_SOURCE_DIR} COMPILE_DEFINITIONS )
get_target_property ( FOLDER_COMPILE_TARGET_INCLUDES ${FOLDER_COMPILE_TARGET} INCLUDE_DIRECTORIES )
wrf_c_preproc_fortran(
TARGET_NAME ${FOLDER_COMPILE_TARGET}_c_preproc_wrf_io
OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/preproc/
EXTENSION ".f90"
INCLUDES ${FOLDER_COMPILE_TARGET_INCLUDES}
DEFINITIONS ${DIR_DEFS}
DEFINITIONS ${PROJECT_COMPILE_DEFINITIONS}
SOURCES wrf_io.F90
)

Expand Down
Loading