Skip to content
Merged
Show file tree
Hide file tree
Changes from 96 commits
Commits
Show all changes
185 commits
Select commit Hold shift + click to select a range
8f5bc53
Modifying #ifdef structure for cmake syntax
islas May 4, 2023
4cee02d
Modifying #ifdef structure for cmake syntax
islas May 4, 2023
ae7e647
Ignoring _build directory
islas May 4, 2023
a7ce282
Adding some helper cmake modules
islas May 4, 2023
2dd8305
Fairly confident this was a bug
islas May 4, 2023
a254e82
Adding nonzero macro check for function returns rather than failing s…
islas May 4, 2023
ed596dd
Current state of cmake build
islas May 4, 2023
5977e85
Rename to reflect c preprocessing
islas May 9, 2023
2fed911
Making registry work in out of source build
islas May 9, 2023
f8f35b3
Splitting out helper macro for definition expansion
islas May 10, 2023
b62817b
Simplifying #if[n]defs
islas May 10, 2023
4fa4b99
Adding missing &
islas May 10, 2023
713cc58
Making registry runner take known defs
islas May 10, 2023
29df3b5
Adding folders to build
islas May 10, 2023
7ecc386
Preprocessing into f90
islas May 10, 2023
65e54fa
Various helper or missing modules
islas May 10, 2023
3bd942c
Runner for configure checks
islas May 10, 2023
c2442cf
Noting how it might eventually be done
islas May 10, 2023
808b126
I believe this was a bug, no idea how it was even working before
islas May 10, 2023
888a68c
Compiling the rest of grib2 io
islas May 10, 2023
b8612c6
Switching io_int/intio tags to #defines
islas May 10, 2023
3c755bd
Adjusting for new ioint tags
islas May 10, 2023
bd029ae
Compiling io_int
islas May 10, 2023
60b47ea
No longer needed with set policy, might need to reinstate for older v…
islas May 10, 2023
f4c77a6
Outputting nl_* routines as f90, and processing md_calls with m4
islas May 10, 2023
326b799
Adding many missing defines, linking and option selections
islas May 10, 2023
8ebc808
Adjusting regex to handle generator expressions better
islas May 10, 2023
e99b7e7
Output options selected
islas May 10, 2023
7373479
Closing the gap in differences between make and cmake builds
islas May 10, 2023
cd18dcf
Removing redundant files
islas May 17, 2023
23b5f9b
Updating [p]netCDF find capabilities
islas May 17, 2023
b452ed5
Adding main to compilation
islas May 17, 2023
34c5e44
New cmake modules to help ease building
islas May 17, 2023
c4e92b9
Script to facilitate cleaning cmake build
islas May 17, 2023
a81ae42
Removing dead comments
islas May 17, 2023
b2ce015
Reworking external/ build
islas May 17, 2023
a70da4c
Fully compiling
islas May 17, 2023
06b3d22
Adding install rules for em_real
islas May 17, 2023
09ee8e9
Adding runtime generated files to ignore list
islas May 23, 2023
e923a63
Adding libdir and prefix to created variables
islas May 23, 2023
0971f3c
Building pnetcdf io lib and re-enabling macro
islas May 23, 2023
dcbda56
Adding in source file swap for MPI comms using RSL LITE
islas May 23, 2023
074f514
Compilation scheme using arch/configure.defaults now working
islas May 23, 2023
577bddb
Fixing syntax for generator expression
islas May 24, 2023
33c7e80
Removing lingering unprotected link library
islas May 24, 2023
9c0979e
Cleaning up
islas May 24, 2023
c59908c
Adding double fp64 link data
islas May 24, 2023
588fa40
Symlinks for all test cases except for esmf coupling
islas May 24, 2023
a271b3f
Adding cmake package config template
islas Jun 12, 2023
b5b0c8c
Grabbing version from README
islas Jun 12, 2023
6859ab3
Better message output
islas Jun 12, 2023
be1f37d
Fixing link installs
islas Jun 12, 2023
7401b96
Adding externals to export targets
islas Jun 12, 2023
b4cc8e5
Clean up and setting install files
islas Jun 12, 2023
c4cc7a6
Clean up
islas Jun 12, 2023
d0d4963
Setting up export namespace and cmake package
islas Jun 12, 2023
b32d0e4
Fixing indentation
islas Jun 24, 2023
a1c598b
Cleaning up cmake modules
islas Jun 24, 2023
91b28cd
Adding key sanitization and option string output
islas Jun 24, 2023
c66b531
Reinstating old c preproc then m4 processing since gfortran is unable to
islas Jun 24, 2023
c95e94d
Make Jasper optional for grib2
islas Jun 24, 2023
f2ede49
Add flags specific for GNU builds
islas Jun 24, 2023
be71c8e
Adding share files
islas Jun 24, 2023
5c3a283
Removing double WRF
islas Jun 28, 2023
472246e
Switching to official toolchain *_INIT options
islas Jun 28, 2023
5cbdbce
Minor fixes to build commands
islas Jun 28, 2023
505d53b
This probably follows original cmake finding order but to be safe reo…
islas Jun 28, 2023
05ec5e8
Fixing symlink creation for second passes
islas Jun 29, 2023
33f5c30
Final touches to linking and include files
islas Jun 29, 2023
1609176
Adding base includes to install
islas Jun 30, 2023
d74021d
Setting message out to smaller names
islas Jun 30, 2023
5eab6f1
Removing old prefix
islas Jun 30, 2023
52e8d4c
Resurrecting nl_set/get routines to maintain old makefile system
islas Jul 3, 2023
db73d7f
Removing these to reinstate the old stubs to support makefile build
islas Jul 6, 2023
cad26c6
Adjusting include paths for removal of redundant code
islas Jul 6, 2023
cb108d8
Using original stub file names
islas Jul 6, 2023
73bc589
Adding check for large file support
islas Jul 6, 2023
cf4ecaa
Typo in adding definitions
islas Jul 6, 2023
ad0620d
Sanitizing in situ code compile/run checks
islas Jul 6, 2023
8dedc47
Adding proper logic for large file support and nc4 features
islas Jul 6, 2023
22fe732
Removing or commenting obsolete code
islas Jul 6, 2023
632130e
Merge branch 'develop' of https://github.com/wrf-model/WRF into cmake…
islas Jul 6, 2023
633c6c7
Fixing variable typo
islas Jul 6, 2023
1907754
Exporting module directory and adding that to include path for WRF_Core
islas Jul 7, 2023
eaa9f4d
Don't make cxx lib required for netcdf
islas Jul 7, 2023
8849b86
Don't use RSL_LITE if no MPI
islas Jul 7, 2023
478cea3
Using a more shell-agnostic redirection
islas Jul 8, 2023
f5617fb
Only linking to RSL_LITE if available
islas Jul 8, 2023
0c03b43
Using a separate module folder for each exec to not conflict on paral…
islas Jul 8, 2023
1f0aa9f
Adding correct settings for nesting without MPI enabled
islas Jul 10, 2023
a893f52
Accounting for config-set variables
islas Jul 12, 2023
9a89eeb
Allow selection of suboptions procedurally
islas Jul 12, 2023
38dde8d
Proper creation of WRF target
islas Jul 12, 2023
42ff2ba
Logic and fixes to allow for double precision compilation
islas Jul 12, 2023
2d1cefa
Rolling back to older cmake process to allow version checking to work
islas Jul 14, 2023
4aea7ee
Version check for GNU flags
islas Jul 14, 2023
091b2fe
Modifying #ifdef structure for cmake syntax
islas May 4, 2023
82ed6c1
Modifying #ifdef structure for cmake syntax
islas May 4, 2023
8f252f8
Ignoring _build directory
islas May 4, 2023
a6676c4
Fairly confident this was a bug
islas May 4, 2023
6497be3
Adding nonzero macro check for function returns rather than failing s…
islas May 4, 2023
3998795
Making registry work in out of source build
islas May 9, 2023
3eb5cb6
Simplifying #if[n]defs
islas May 10, 2023
af7f3a4
Adding missing &
islas May 10, 2023
f2b882a
I believe this was a bug, no idea how it was even working before
islas May 10, 2023
d541360
Switching io_int/intio tags to #defines
islas May 10, 2023
db27276
Adjusting for new ioint tags
islas May 10, 2023
5a9d615
Removing redundant files
islas May 17, 2023
051e229
Reworking external/ build
islas May 17, 2023
96c9353
Adding runtime generated files to ignore list
islas May 23, 2023
5539455
Building pnetcdf io lib and re-enabling macro
islas May 23, 2023
7ff2f7e
Reinstating old c preproc then m4 processing since gfortran is unable to
islas Jun 24, 2023
0396669
Adjusting include paths for removal of redundant code
islas Jul 6, 2023
9a76186
Logic and fixes to allow for double precision compilation
islas Jul 12, 2023
5eaa938
Remove all references to idx tags autogen file
islas Jul 17, 2023
d102f6d
Removing dimspec check since some configurations fail silently
islas Jul 19, 2023
5c5a106
Better logic for presenting configurations
islas Jul 28, 2023
e44fab2
Making sure to cd back
islas Jul 31, 2023
547bac1
Aligning with WPS configure_reader.py
islas Jul 31, 2023
b85a5e1
Synchronizing separated commits from build cleanup
islas Jul 31, 2023
864b6a9
Fix bug where string compare fails when values not defined
islas Aug 17, 2023
177d95b
Allow stanza selection and direct option pass-through without user pr…
islas Aug 17, 2023
ad11946
Changing visibility of linked omp lib as that can cause netcdf linked…
islas Aug 22, 2023
7341c8e
Print build type
islas Aug 22, 2023
4d82c75
Setting preproc macros to suppress further automatic processing to av…
islas Aug 22, 2023
73f71f5
Find omp/mpi if finding wrf and was built with said options
islas Aug 22, 2023
d453c43
Applying m4 flags
islas Aug 22, 2023
558d9d1
Using cpp instead of fortran compiler for more standardized flag usage
islas Sep 6, 2023
8c64748
sh compliant
islas Sep 6, 2023
bc3a808
Remove non-existent fortran module dirs
islas Sep 6, 2023
5079720
Fixing fseek tests
islas Sep 6, 2023
a4c5cce
Fixing bad syntax
islas Sep 6, 2023
8e19a34
IPO control and per-file optimization set
islas Sep 6, 2023
df258c2
Wrapping build type in quotes for when not set
islas Sep 29, 2023
2b8dc1b
Fixing missing symbols due to MPI wrapper forcing IPO usage even when…
islas Sep 29, 2023
9d473f0
Finally deducing the true nature of nesting logic requiring stubbed m…
islas Sep 29, 2023
0439324
Allow control of build and install directories
islas Dec 28, 2023
2958e9c
Split netCDF and netCDF-Fortran finding into two separate modules
islas Dec 28, 2023
59fad14
Adjust to split netCDF packages
islas Dec 28, 2023
ba79d5f
Adding library path to package finds to allow rpath automated generat…
islas Jan 2, 2024
f65b612
Full support for out-of-source build and installs
islas Jan 2, 2024
73e17f2
Setup em_real to do out-of-source install
islas Jan 2, 2024
bcd8bde
Setup ideal cases to do out-of-source installs
islas Jan 2, 2024
bf1f546
First draft of ideal tests for cmake
islas Jan 2, 2024
2437541
Compilation of multiple tests at the same time for cmake now works
islas Jan 2, 2024
95acd4d
Fix builds to work correctly when not mpi
islas Jan 2, 2024
4364f9a
Adding version checking to JASPER as selected version is very important
islas Jan 8, 2024
94ed78c
Add stand-in code for native netCDF[-Fortran] cmake builds
islas Jan 8, 2024
1003f72
Make optional packages default off and must be requested on
islas Jan 9, 2024
d91185d
Use installed binary location rather than specifying it manually
islas Jan 12, 2024
54e9e0f
Fix em_real install path
islas Jan 12, 2024
7abfaeb
Fix typo in argpack
islas Jan 12, 2024
a7117e1
Get ideal tests now working within same repo directory simultaneously
islas Jan 15, 2024
d1b1bab
Merge upstream develop
islas Jan 15, 2024
331d416
Adding correct logic for CLM
islas Jan 22, 2024
4b79242
Using new ccpp kind file
islas Jan 22, 2024
06be911
Merge upstream/develop
islas Jan 22, 2024
17e8905
Revert "Making registry work in out of source build"
islas Jan 22, 2024
7743a35
Removing unofficial tests
islas Jan 25, 2024
8ba0eef
Add missing traditional flag to cpp
islas Jan 25, 2024
46182a9
Revert syntax changes due to traditional flag now in place
islas Jan 25, 2024
6684d46
Missed one single backslash
islas Jan 25, 2024
5a91180
Note that -c is the default clean option
islas Jan 31, 2024
4b61b40
Update command descriptions to reflect actual shell command execution
islas Jan 31, 2024
25f7104
Remove clean links as no softlinks are created now
islas Jan 31, 2024
ceea17d
Add documentation on new build method
islas Jan 31, 2024
bac485c
Noting default values more concisely and improving printing of options
islas Jan 31, 2024
62b0e93
Correctly installing cmake config files so other projects can link ag…
islas Feb 1, 2024
67ac1a0
Set default build type to release if not specified
islas Feb 1, 2024
2c7c396
Set MPI to default on if available
islas Feb 1, 2024
c454589
Add ability to set default option selection for string options based …
islas Feb 1, 2024
b09c6c5
Set default WRF_NESTING value to 1/BASIC
islas Feb 1, 2024
b60bd7e
Change Darwin configurations to include architecture before (MACOS) s…
islas Feb 7, 2024
983f82a
Use arm64 as architecture string rather than aarch64 for Darwin
islas Feb 8, 2024
7fa4005
Merge branch 'develop' of github.com:wrf-model/WRF into cmakeBuild
islas Feb 13, 2024
8c42cca
Add shared physics files to cmake compilation
islas Feb 13, 2024
f7f6fcb
Fix install location of tables and data
islas Feb 13, 2024
b04996b
Set p3 tables to newer correct values
islas Feb 14, 2024
464f539
Remove COAMPS option
islas Feb 14, 2024
33fb761
Set correct location for MPTABLE.TBL
islas Feb 14, 2024
f6da85a
Move install namelist.input files up one to match other installs
islas Feb 15, 2024
759df03
Use install location so links don't rely on build location and add .e…
islas Feb 15, 2024
981aafa
Switch to symlinks for binaries
islas Feb 15, 2024
31e07db
Create analogous run/ directory in install/
islas Feb 15, 2024
7895715
Change install of mixing_ratio to link to better identify where it is…
islas Feb 15, 2024
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
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,17 @@
configure.wrf*
*.backup
*.f90
_build/
# New (and old) things we should ignore
wrf_config.cmake
*.nc
rsl.out.*
rsl.error.*
ndown
real
tc
ideal
wrf
wrfbdy_d*
wrfinput_d*
wrfout_d*
797 changes: 797 additions & 0 deletions CMakeLists.txt

Large diffs are not rendered by default.

366 changes: 366 additions & 0 deletions arch/configure_reader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,366 @@
#!/usr/bin/env python3

import sys
import re
import inspect
import platform

archBlock = re.compile( r"(?:#[ ]*)(ARCH(?:.*\n)*?)(?:#{5,})", re.I )
kvPair = re.compile( r"^(\w+)(?:[ \t]*=[ \t]*)(.*?)$", re.I | re.M )
# Make this gnarly and complicated since configure.defaults has no standard formatting
# v start v OS V typical v MACOS
osAndArch = re.compile( r"^ARCH[ ]+(\w+)[ ]+((?:\w+.*?),|(?:[(].*?[)]))", re.I )
# Just grab the first two words, thats what you get
osAndArchAlt = re.compile( r"^ARCH[ ]+(\w+)[ ]+(\w+)", re.I )

referenceVar = re.compile( r"[$][(](\w+)[)]", re.I )

class Stanza():

def __init__( self, lines ) :
self.lines_ = lines
self.os_ = None
self.archs_ = []
self.kvPairs_ = {}

def parse( self ) :
# First get os & archs
osarchMatch = osAndArch.match( self.lines_ )

if osarchMatch is None :
osarchMatch = osAndArchAlt.match( self.lines_ )
if osarchMatch is None :
print( "Could not find OS and architecture info in " + self.lines_.partition("\n")[0] )

self.os_ = osarchMatch.group(1)
self.archs_ = osarchMatch.group(2).strip(",").split( " " )

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This RE breaks on macOS, because it reads the (MACOS) comment from the configure.defaults file. You could either make a special-case check here, or, update configure.defaults with something like this:

diff --git a/arch/configure.defaults b/arch/configure.defaults
index 36ca1b6e..34038a87 100644
--- a/arch/configure.defaults
+++ b/arch/configure.defaults
@@ -1000,7 +1000,7 @@ CC_TOOLS        =      $(SCC)
 NETCDFPAR_BUILD        =      CONFIGURE_NETCDFPAR_BUILD
 
 ###########################################################
-#ARCH    Darwin (MACOS) gfortran with gcc #serial smpar dmpar dm+sm
+#ARCH    Darwin x86_64, aarch64 (MACOS) gfortran with gcc #serial smpar dmpar dm+sm
 #
 DESCRIPTION     =       GNU ($SFC/$SCC)
 DMPARALLEL      =       # 1
@@ -1045,7 +1045,7 @@ CC_TOOLS        =      $(SCC)
 NETCDFPAR_BUILD        =      CONFIGURE_NETCDFPAR_BUILD
 
 ###########################################################
-#ARCH    Darwin (MACOS) gfortran with clang #serial smpar dmpar dm+sm
+#ARCH    Darwin x86_64, aarch64 (MACOS) gfortran with clang #serial smpar dmpar dm+sm
 #
 DESCRIPTION     =       GNU ($SFC/clang)
 DMPARALLEL      =       # 1

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I follow. The osAndArch regex properly catches the lines you mentioned in my tests when enabling (via changing the skip logic) cross-platform stanza selection. The last bit of the regex has a non-capture group for the (...) to deal with (MACOS)

It would be nice though to not have to deal with special cases for all the inconsistent formatting in comments/descriptions of things in configure.defaults

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On my MacBook Pro, the script failed to find any stanzas until I manually added the architectures to the configure.defaults file. Printing out the Stanza.archs_ variable is how I found that it was capturing the (MACOS) token. I did not try using the cross-platform flag.

I also found that using the gfortran/clang stanza failed as well because the -fallow-argument-mismatch flag was being passed to both gfortran and clang (where it's an invalid argument). Using gcc/gfortran worked fine after the edits to the configure file. I'll dig into that clang issue and post another comment when I determine the underlying issue.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. I think I was focused on simply getting the regex to capture something, but that something is eventually compared to platform.machine() in python. I think a change would be best.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried again but got the same result (no stanzas) when building on a M1 Mac -- as it turns out, macOS uses arm64 as an architecture identifier vs aarch64 that Linux uses. My patch worked on a Intel Mac but not Arm-based. My apologies; I should have double-checked that.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just double checking, adding arm64 to the list of archs in the line does properly show the modified stanza?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just double checking, adding arm64 to the list of archs in the line does properly show the modified stanza?

Yes, but I would change aarch64 to arm64 for the Darwin stanzas vs. adding it. The macOS reports it only as arm64 or x86_64 from the uname() call (which is what Python is using under the hood).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, should be fixed now


for kvPairMatch in kvPair.finditer( self.lines_ ) :
self.kvPairs_[ kvPairMatch.group(1) ] = kvPairMatch.group(2)
self.removeComments( kvPairMatch.group(1) )

# Now sanitize
self.sanitize()

def dereference( self, field, fatal=False ) :
if field in self.kvPairs_ :
prevField = self.kvPairs_[field]

for refVarIter in referenceVar.finditer( prevField ) :
if refVarIter is not None :
# Grab group 1 and check that it is in our kv pairs
refVar = refVarIter.group(1)
if refVar not in self.kvPairs_ :
if fatal :
print( "Could not rereference : " + refVar )
exit(1)
else:
continue

# Recursively deref
self.dereference( refVar, fatal )

# Replace in original
self.kvPairs_[field] = self.kvPairs_[field].replace(
"$({var})".format( var=refVar ),
self.kvPairs_[refVar]
)

def removeReferences( self, field, specifics=[] ) :
if field in self.kvPairs_ :
if specifics :
for specific in specifics :
self.kvPairs_[ field ] = self.kvPairs_[ field ].replace(
"$({var})".format( var=specific ),
""
)
else :
self.kvPairs_[ field ] = referenceVar.sub( "", self.kvPairs_[ field ] )


def removeComments( self, field ) :
if field in self.kvPairs_ :
self.kvPairs_[ field ] = self.kvPairs_[ field ].split( "#", 1 )[0]

def splitIntoFieldAndFlags( self, field ) :
# Fix flags being mixed with programs
if field in self.kvPairs_ :
fieldValue = self.kvPairs_[ field ]

self.kvPairs_[field] = fieldValue.partition(" ")[0]
self.kvPairs_[field + "_FLAGS"] = fieldValue.partition(" ")[1]

def sanitize( self ) :
# Fix problematic variables
self.dereference( "DM_FC" )
self.dereference( "DM_CC" )
self.removeReferences( "FCBASEOPTS_NO_G" )
# Get rid of all these mixed up flags, these are handled by cmake natively or
# just in the wrong place
self.removeReferences( "FCBASEOPTS", [ "FCDEBUG", "FORMAT_FREE", "BYTESWAPIO", ] )
# Now deref
self.dereference( "FCBASEOPTS" )

# Now fix certain ones that are mixing programs with flags all mashed into one option
self.splitIntoFieldAndFlags( "DM_FC" )
self.splitIntoFieldAndFlags( "DM_CC" )
self.splitIntoFieldAndFlags( "M4" )

# Remove rogue compile commands that should *NOT* even be here
keysToSanitize = [
"ARFLAGS",
"CFLAGS_LOCAL",
"CPP",
"ESMF_LDFLAG",
"LDFLAGS_LOCAL",
"MODULE_SRCH_FLAG",
"RLFLAGS",
"TRADFLAG",
"FCBASEOPTS",
"FCBASEOPTS_NO_G",
"FCOPTIM",
"FORMAT_FIXED",
"FORMAT_FREE"
]

for keyToSan in keysToSanitize :
if keyToSan in self.kvPairs_ :
self.kvPairs_[ keyToSan ] = self.kvPairs_[ keyToSan ].replace( "-c", "" )



# Now deref all the rest
for key in self.kvPairs_ :
self.dereference( key )
# And for final measure strip
self.kvPairs_[ key ] = self.kvPairs_[ key ].strip()

def __str__( self ):
# base = """OS {os:<8} ARCHITECTURES {archs:<20}
# >> SFC = {SFC:<12}
# >> SCC = {SCC:<12}
# >> CCOMP = {CCOMP:<12}
# >> DM_FC = {DM_FC:<12}
# >> DM_CC = {DM_CC:<12}
# """
base = """{rec} {os:<10} {SFC:<11} / {SCC:<11} / {CCOMP:<11} / {DM_FC:<11} / {DM_CC:<11}"""
text = inspect.cleandoc( base ).format(
os=str(self.os_),
rec=( "!!" if platform.system().lower() != self.os_.lower() else "Ok" ),
# archs=str(self.archs_),
SFC=str( self.kvPairs_["SFC"].partition(" ")[0] ),
SCC=str( self.kvPairs_["SCC"].partition(" ")[0] ),
CCOMP=str( self.kvPairs_["CCOMP"].partition(" ")[0] ),
DM_FC=str( self.kvPairs_["DM_FC"].partition(" ")[0] ),
DM_CC=str( self.kvPairs_["DM_CC"].partition(" ")[0] )
)
# text += "\n" + "\n".join( [ "{key:<18} = {value}".format( key=key, value=value) for key, value in self.kvPairs_.items() ] )
return text

@staticmethod
def findFirstDifference( rhStanza, lhStanza, maxLength=32 ) :
diff = False
value = ""
valuesToCheck = [
"ARCH_LOCAL",
"BYTESWAPIO",
"CFLAGS_LOCAL",
"DM_CC",
"DM_FC",
"DM_FC_FLAGS",
"DM_CC_FLAGS",
"FCBASEOPTS",
"FCDEBUG",
"FCNOOPT",
"FCOPTIM",
"M4_FLAGS",
"SCC",
"SFC"
]
for rhKey, rhValue in rhStanza.kvPairs_.items() :
if rhKey in valuesToCheck and rhKey in lhStanza.kvPairs_ :
# Qualifies for difference
if rhValue != lhStanza.kvPairs_[rhKey] :
diff = True
value = "{key:<12} = {value}".format( key=rhKey, value=lhStanza.kvPairs_[rhKey] )

# Truncate
value = ( value[:maxLength] + "..." ) if len( value ) > maxLength else value

return diff, value


def getStringOptionSelection( topLevelCmake, searchString ) :
topLevelCmakeFP = open( topLevelCmake, "r" )
topLevelCmakeLines = topLevelCmakeFP.read()
topLevelCmakeFP.close()

stringOptionsMatch = re.search(
r"set\s*[(]\s*" + searchString + r"\s*(.*?)[)]",
topLevelCmakeLines,
re.I | re.S | re.M
)
if stringOptionsMatch is None :
print( "Syntax error in parsing " + searchString + " from " + topLevelCmake )
exit(1)

options = [ option.split( "#", 1 )[0].strip() for option in stringOptionsMatch.group(1).split( "\n" ) ]
# Weed out empties
options = [ option for option in options if option ]

optionsFmt = ", ".join( [ "{idx} : {opt}".format( idx=options.index( opt ), opt=opt ) for opt in options ] )
selection = int( input( "Select option from {optionsStr} [0-{max}] ({opts}) : ".format( optionsStr=searchString, max=len(options)-1, opts=optionsFmt ) ) )

if selection < 0 or selection > len(options) :
print( "Invalid option selection for " + searchString + "!" )
exit(1)

return options[selection]

def getSubOptions( topLevelCmake, ignoreOptions ) :
topLevelCmakeFP = open( topLevelCmake, "r" )
topLevelCmakeLines = topLevelCmakeFP.read()
topLevelCmakeFP.close()

stringOptionsMatch = re.finditer(
r"set\s*[(]\s*(\w+)\s*(ON|OFF)\s*CACHE\s*BOOL\s*\"(.*?)\"\s*[)]",
topLevelCmakeLines,
re.I | re.M
)
# Remove commented ones and ones that don't follow pattern set( <OPT> ON|OFF CACHE BOOL "<OPT>" )
options = [ [ option.group( 1 ), option.group( 2 ) ] for option in stringOptionsMatch if option.group( 1 ) == option.group( 3 ) and option.group(0).split( "#", 1 )[0].strip() ]

# Remove ignore options
options = [ option for option in options if option[0] not in ignoreOptions ]
subOptions = {}

if options :
subOptionQuit = False
optionToggleIdx = -1

# Print menu
optionStr = "{idx:<3} {option:<24} : {value:<5}"
print( optionStr.format( idx="ID", option="Option", value="Default" ) )
for opt in options :
print( optionStr.format( idx=options.index(opt), option=opt[0], value=opt[1] ) )

print( "Enter ID to toggle option on or off, q to quit : " )
# Loop until q, toggle from default not current value
while not subOptionQuit :
optionToggleIdx = input()
try:
optionToggleIdx = int( optionToggleIdx )
if optionToggleIdx < 0 or optionToggleIdx >= len( options ) :
print( "Not a valid index" )
else:
subOptions[ options[optionToggleIdx][0] ] = "ON" if not ( options[optionToggleIdx][1] == "ON" ) else "OFF"
print( "Set {option} to {value}".format( option=options[optionToggleIdx][0], value=subOptions[ options[optionToggleIdx][0] ] ) )
except ValueError as err :
subOptionQuit = optionToggleIdx.lower() == "q"

return subOptions

def generateCMakeToolChainFile( cmakeToolChainTemplate, output, stanza, optionsDict={} ) :
cmakeToolChainTemplateFP = open( cmakeToolChainTemplate, "r" )
cmakeToolChainTemplateLines = cmakeToolChainTemplateFP.read()
cmakeToolChainTemplateFP.close()

configStanza = cmakeToolChainTemplateLines.format(
ARCH_LOCAL=stanza.kvPairs_["ARCH_LOCAL"],
BYTESWAPIO=stanza.kvPairs_["BYTESWAPIO"],
CFLAGS_LOCAL=stanza.kvPairs_["CFLAGS_LOCAL"],
DM_CC=stanza.kvPairs_["DM_CC"],
DM_FC=stanza.kvPairs_["DM_FC"],
DM_FC_FLAGS=stanza.kvPairs_["DM_FC_FLAGS"],
DM_CC_FLAGS=stanza.kvPairs_["DM_CC_FLAGS"],
FCBASEOPTS=stanza.kvPairs_["FCBASEOPTS"],
FCDEBUG=stanza.kvPairs_["FCDEBUG"],
FCNOOPT=stanza.kvPairs_["FCNOOPT"],
FCOPTIM=stanza.kvPairs_["FCOPTIM"],
M4_FLAGS=stanza.kvPairs_["M4_FLAGS"],
SCC=stanza.kvPairs_["SCC"],
SFC=stanza.kvPairs_["SFC"]
)

# Extra stufff not from stanza but options
fmtOption = "set( {opt:<32} {value:<12} CACHE STRING \"Set by configuration\" FORCE )"
configStanza += "\n" + "\n".join( [ fmtOption.format( opt=key, value=value ) for key, value in optionsDict.items() ] )

outputFP = open( output, "w" )
outputFP.write( configStanza )
outputFP.close()

def main() :
configFile = sys.argv[1]
cmakeTemplateFile = sys.argv[2]
cmakeConfigFile = sys.argv[3]
cmakeFile = sys.argv[4]

coreOption = getStringOptionSelection( cmakeFile, "WRF_CORE_OPTIONS" )
nestingOption = getStringOptionSelection( cmakeFile, "WRF_NESTING_OPTIONS" )
caseOption = getStringOptionSelection( cmakeFile, "WRF_CASE_OPTIONS" )

# These are yes
yesValues = [ "yes", "y", "true", "1" ]

#!TODO Expand this for all wrf options
useMPI = input( "[DM] Use MPI? [Y/n] : " ).lower() in yesValues
useOpenMP = input( "[SM] Use OpenMP? [Y/n] : " ).lower() in yesValues

alreadyAsked = [ "USE_MPI", "USE_OPENMP" ]

doSuboptionMenu = input( "Configure additional options? [Y/n] : " ).lower() in yesValues
subOptions = {}
if doSuboptionMenu :
subOptions = getSubOptions( cmakeFile, alreadyAsked )


fp = open( configFile, 'r' )
lines = fp.read()
fp.close()

# Now grab the blocks and parse
stanzas = []
uniqueConfigs = {}
stanzaIdx = 0
for stanzaBlock in archBlock.finditer( lines ) :
stanza = Stanza( stanzaBlock.group(1) )
stanza.parse()

stanzas.append( stanza )
stanzaConfig = str( stanza )
stanzaId = "{idx:<3} ".format( idx=stanzaIdx )
if stanzaConfig not in uniqueConfigs :
uniqueConfigs[ stanzaConfig ] = { "stanza" : stanza, "idx" : stanzaIdx }
print( stanzaId + stanzaConfig + "[first entry]" )
else :
diff, value = Stanza.findFirstDifference( uniqueConfigs[ stanzaConfig ]["stanza"], stanza )
if diff :
print( stanzaId + stanzaConfig + "@{idx} diff => {value}".format( idx=uniqueConfigs[ stanzaConfig ][ "idx" ], value=value ) )
else :
print( stanzaId + stanzaConfig + "[no difference]" )
stanzaIdx += 1

print( "!! - Not recommended for your system" )

idxSelection = int( input( "Select configuration [0-{stop}] (note !!) : ".format( stop=( stanzaIdx-1) ) ) )
if idxSelection < 0 or idxSelection > stanzaIdx - 1 :
print( "Invalid configuration selection!" )
exit(1)

additionalOptions = {
"WRF_CORE" : coreOption,
"WRF_NESTING" : nestingOption,
"WRF_CASE" : caseOption,
"USE_MPI" : "ON" if useMPI else "OFF",
"USE_OPENMP" : "ON" if useOpenMP else "OFF",
}
additionalOptions.update( subOptions )
generateCMakeToolChainFile( cmakeTemplateFile, cmakeConfigFile, stanzas[idxSelection], additionalOptions )




if __name__ == '__main__' :
main()

Loading