@@ -7,7 +7,7 @@ create the cam library
77# pylint: disable=unused-wildcard-import, bad-whitespace, too-many-locals
88# pylint: disable=invalid-name
99import sys , os , filecmp , shutil
10-
10+ from glob import glob
1111
1212_CIMEROOT = os .environ .get ("CIMEROOT" )
1313if _CIMEROOT is None :
@@ -27,7 +27,7 @@ logger = logging.getLogger(__name__)
2727
2828###############################################################################
2929def _build_fms (caseroot , libroot , bldroot ):
30- ###############################################################################
30+ ###############################################################################
3131
3232 with Case (caseroot ) as case :
3333
@@ -71,7 +71,7 @@ def _build_fms(caseroot, libroot, bldroot):
7171
7272###############################################################################
7373def _build_cam (caseroot , libroot , bldroot ):
74- ###############################################################################
74+ ###############################################################################
7575
7676 with Case (caseroot , read_only = False ) as case :
7777
@@ -157,12 +157,157 @@ def _build_cam(caseroot, libroot, bldroot):
157157 logger .info ("%s: \n \n output:\n %s \n \n err:\n \n %s\n " , cmd , out , err )
158158 expect (rc == 0 , "Command %s failed with rc=%s" % (cmd , rc ))
159159
160+ ###############################################################################
161+ def _run_cmd (command , working_dir ):
162+ ###############################################################################
163+
164+ rc , out , err = run_cmd (command , from_dir = working_dir , verbose = True )
165+ expect (rc == 0 , f"Command { command } failed with rc={ rc } out={ out } err={ err } " )
166+
167+ ###############################################################################
168+ def _cmake_default_args (caseroot ):
169+ ###############################################################################
170+ # Returns a dictionary of CMake variables based on the Macros.cmake file for
171+ # the build.
172+
173+ with Case (caseroot ) as case :
174+ macro_path = os .path .abspath (os .path .join (caseroot , "cmake_macros" , "" ))
175+ args = "-DCONVERT_TO_MAKE=ON "
176+ args += f"-DCASEROOT={ caseroot } "
177+ args += f"-DCOMPILER={ case .get_value ('COMPILER' )} "
178+ args += f"-DOS={ case .get_value ('OS' )} "
179+ args += f"-DMACH={ case .get_value ('MACH' )} "
180+ args += "-DCMAKE_C_COMPILER_WORKS=1 "
181+ args += "-DCMAKE_Fortran_COMPILER_WORKS=1 "
182+ args += "-DCMAKE_CXX_COMPILER_WORKS=1 "
183+ args += f"-DDEBUG={ case .get_value ('DEBUG' )} "
184+ cmd = f"cmake { args } ."
185+ rc , out , err = run_cmd (cmd , combine_output = True , from_dir = macro_path )
186+ expect (rc == 0 , f"Command { cmd } failed with rc={ rc } out={ out } err={ err } " )
187+
188+ arg_dict = {}
189+ for line in out .splitlines ():
190+ if ":=" in line :
191+ key , val = line .split (":=" )
192+ arg_dict [key .replace ('CIME_SET_MAKEFILE_VAR' ,'' ).strip ()] = val .strip ()
193+
194+ return arg_dict
195+
196+ ###############################################################################
197+ def _build_tuvx (caseroot , libroot , bldroot ):
198+ ###############################################################################
199+ # Builds the TUV-x library and updates the case variables used to set the
200+ # include paths and linked libraries
201+
202+ with Case (caseroot ) as case :
203+ bldpath = os .path .join (bldroot , "tuv-x" )
204+ if not os .path .exists (bldpath ):
205+ os .makedirs (bldpath )
206+ srcpath = os .path .abspath (os .path .join (case .get_value ("COMP_ROOT_DIR_ATM" ), \
207+ "libraries" , "tuv-x" , "" ))
208+ logger .info ("Building TUV-x in {} from source in {}\n " .format (bldpath , srcpath ))
209+
210+ arg_dict = _cmake_default_args (caseroot )
211+ cmake_args = "-DCMAKE_VERBOSE_MAKEFILE=ON "
212+ if case .get_value ("MPILIB" ) != "mpi-serial" :
213+ cmake_args += "-DTUVX_ENABLE_MPI:BOOL=TRUE "
214+ cmake_args += "-DCMAKE_BUILD_TYPE=Debug "
215+ cmake_args += "-DCMAKE_Fortran_COMPILER=mpif90 "
216+ cmake_args += "-DCMAKE_C_COMPILER=mpicc "
217+ cmake_args += "-DCMAKE_CXX_COMPILER=mpicxx "
218+ cmake_args += "-DCMAKE_Fortran_COMPILER_WORKS=1 "
219+ cmake_args += "-DCMAKE_C_COMPILER_WORKS=1 "
220+ cmake_args += "-DCMAKE_CXX_COMPILER_WORKS=1 "
221+ if (case .get_value ("MACH" ) == "izumi" ) :
222+ cmake_args += f"-DCMAKE_PREFIX_PATH={ arg_dict ['NETCDF_PATH' ]} "
223+ cmake_args += f"-DCMAKE_IGNORE_PATH={ os .environ .get ('PYTHONHOME' )} "
224+ if (case .get_value ("MACH" ) == "izumi" ) and (case .get_value ('COMPILER' ) == "nag" ) :
225+ cmake_args += "-DCMAKE_Fortran_FLAGS='-C=all -g ' "
226+ else :
227+ cmake_args += f"-DCMAKE_Fortran_FLAGS='{ arg_dict ['FFLAGS' ]} ' "
228+ cmake_args += f"-DCMAKE_INSTALL_PREFIX='{ libroot } ' "
229+ cmake_args += "-DTUVX_ENABLE_TESTS=OFF "
230+ cmake_args += "-DTUVX_ENABLE_COVERAGE=OFF "
231+ cmake_args += "-DTUVX_BUILD_CLI=OFF "
232+ cmake_args += f"-DTUVX_INSTALL_INCLUDE_DIR='{ _tuvx_include_dir (libroot )} ' "
233+ cmake_args += f"-DTUVX_INSTALL_MOD_DIR='{ _tuvx_include_dir (libroot )} ' "
234+ cmake_args += srcpath
235+
236+ _run_cmd (f"cmake { cmake_args } " , bldpath )
237+ _run_cmd (case .get_value ('GMAKE' ), bldpath )
238+ _run_cmd (f"{ case .get_value ('GMAKE' )} install" , bldpath )
239+
240+ # add TUV-x to include paths
241+ incldir = os .environ .get ('USER_INCLDIR' )
242+ if incldir is None :
243+ incldir = ''
244+ os .environ ['USER_INCLDIR' ] = incldir + \
245+ f" -I{ _tuvx_include_dir (libroot )} "
246+
247+ # create symlink to library in folder CIME expects libraries to be in
248+ dst = os .path .join (libroot , "libtuvx.a" )
249+ if os .path .isfile (dst ):
250+ os .remove (dst )
251+ os .symlink (_tuvx_lib_path (libroot ), dst )
252+ dst = os .path .join (libroot , "libyaml-cpp.a" )
253+ if os .path .isfile (dst ):
254+ os .remove (dst )
255+ os .symlink (_yaml_cpp_lib_path (libroot ), dst )
256+
257+ ###############################################################################
258+ def _tuvx_include_dir (libroot ):
259+ ###############################################################################
260+ # Returns the path to the TUV-x include directory
261+
262+ coreinc = os .path .join (libroot , "include" )
263+ expect (os .path .exists (coreinc ), f"TUV-x include directory not found at { coreinc } " )
264+
265+ return coreinc
266+
267+ ###############################################################################
268+ def _yaml_cpp_lib_path (libroot ):
269+ ###############################################################################
270+ # Returns the path to the yaml-cpp library
271+
272+ corelib = os .path .join (libroot , "lib64" , "libyaml-cpp.a" )
273+ if not os .path .exists (corelib ):
274+ corelib = os .path .join (libroot , "lib64" , "libyaml-cppd.a" )
275+ if not os .path .exists (corelib ):
276+ corelib = os .path .join (libroot , "lib" , "libyaml-cpp.a" )
277+ expect (os .path .exists (corelib ), f"yaml-cpp library not found at { corelib } " )
278+
279+ return corelib
280+
281+ ###############################################################################
282+ def _tuvx_lib_path (libroot ):
283+ ###############################################################################
284+ # Returns the path to the TUV-x library
285+
286+ corelib = os .path .join (_tuvx_install_dir (libroot ), "lib64" , "libtuvx.a" )
287+ if not os .path .exists (corelib ):
288+ corelib = os .path .join (_tuvx_install_dir (libroot ), "lib" , "libtuvx.a" )
289+ expect (os .path .exists (corelib ), f"TUV-x library not found at { corelib } " )
290+
291+ return corelib
292+
293+ ###############################################################################
294+ def _tuvx_install_dir (libroot ):
295+ ###############################################################################
296+ # Returns the path to the TUV-x install directory
297+
298+ corepaths = glob (os .path .join (libroot , "tuvx*" ))
299+ expect (len (corepaths )> 0 , f"TUV-x not found at { libroot } " )
300+ expect (len (corepaths )< 2 , f"Multiple TUV-x versions found at { libroot } " )
301+ expect (os .path .exists (corepaths [0 ]), f"TUV-x install directory not found at { corepaths [0 ]} " )
302+
303+ return corepaths [0 ]
160304
161305###############################################################################
162306
163307
164308def _main_func ():
165309 caseroot , libroot , bldroot = parse_input (sys .argv )
310+ _build_tuvx (caseroot , libroot , bldroot )
166311 _build_fms (caseroot , libroot , bldroot )
167312 _build_cam (caseroot , libroot , bldroot )
168313
0 commit comments