-
Notifications
You must be signed in to change notification settings - Fork 371
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
E3SM CMake Build System V2! #5943
Comments
@jonbob , GH wouldn't let me assign you. I think it tops out at 10 assignees. I think you might be interested in this as well. I think the MPAS cmake is in decent shape and probably will only require minor mods. |
I strongly support this effort. Having e3sm follow state-of-the-art (and relatively well known) patterns will make life MUCH easier for future code maintainers onboarding, as well as for debugging or adding features. I have a branch that tries to make scorpio a cmake installable package. I was trying to do it to use scorpio inside another lib I am working on, which needs to be installed as a cmake pkg (and therefore must have all its deps as cmake pkgs). I can revive it, if that helps with getting sharedlibs to the standard we need. I am not sure how to do this incrementally, while keeping (some) bwd compatibility. I fear that we will have to break bwd compatibility almost right off the bat. But maybe I'm wrong.
Can we just add a test mod with shell_commands that sets an env var? Or does the CCS run shell_commands in a subshell, hence losing any env mod it may do? |
@bartgol , I was more speaking of where to put the test itself rather than how to test it. I think the "how" is pretty easy, just set PACKAGE_ROOT and then scan the log to make sure it used it. |
Thanks @jgfouca -- I'll keep an eye on it, but I know it's in good hands |
@grnydawn FYI, in case this impacts how you are doing CMake setup for Omega in E3SM-Project#31 |
What would backward compatibility mean for this? |
@rljacob , we don't want the semantics of the build to change, we just want a cleaner cmake driving it. |
Rob, I guess stuff like the content of |
@rljacob could you take a glance at the Optional TPL list and let me know if you see anything that we don't use anymore? |
@jgfouca As we develop Omega (YAKL-based) and as other codes may potentially migrate the C++ way... some TPLs like yaml-cpp and spdlog will be used across components too. These are currently buried under ekat/extern. It would be great to promote these (YAKL, sdplog, yaml-cpp) to the shared libs level and treated the same. Looking forward to a better Cmake build. |
What are "MKL" and "FMS" TPLs? I can't remember why SAMXX, RTMGPXX and COSP are treated like TPLs and if we want to keep doing that. |
@rljacob , MKL is the intel Math Kernel Library. I have no idea what FMS is; I was hoping you knew. |
There are very few references to FMS in E3SM or CIME. I think it's almost certain we aren't using it. The best clue I got is this python code: CIME/build.py:
driver-mct/cime_config/buildexe:
|
Ok then it refers to Flexible Modeling System, a GFDL coupling layer. mom and fv3 are GFDL models. Probably can't remove that from cime/CIME but the E3SM-owned code doesn't need it. |
@philipwjones on my to-do list I have the task of making ekat use pre-built TPLs (if available) via find_package, and only proceed to build them if not found. I also want to switch to a |
IIRC, @jonbob advocated for backwards compatibility when cmake was first introduced but I don't recall why. Something about MPAS standalone build? |
Oh yeah the Intel MKL. I think thats optional because its not useful/available on all platforms. Plenty of machines in config_machines are loading the mkl module. |
@rljacob -- yes, the old build system gave us some different information and capabilities when the MPAS components were all separate submodules. But that's no longer an issue |
@jgfouca We should add a nano cmake task: change the On my laptop (ok, I get it, it's my laptop, but the problem may appear somewhere else too), I have a netcdf installed in the system, which gets picked up before the one I manually installed. The system one does not have the The issue is that in
but the fact that one is searched before default paths, and the other is searched after is, in my opinion, a massive difference, to the point that it's the only thing that matters... As I mentioned above, another solution is to add |
Background
I've been meaning to do this for a long time and a few tickets have motivated me to finally launch this effort:
E3SM-Project/scorpio#543
#5786
ESMCI/cime#4308
ESMCI/cime#3050
Our current build system has a lot of technical debt due to the way it evolved from perl+Makefiles to python+CMake. During the transition from Makefile to CMake, I think it made sense to keep as much backwards compatibility as possible in order to minimize disruption. Now that the CMake system has been in place for years, I think we can and should start thinking of refactoring the build system to be more like an industry-standard CMake system.
Dependency Management
I think the worst part of the current system is how we handle our external dependencies. These dependencies fall into two categories, the "TPLs" (things we expect to be installed on the machine and most likely in a loaded env module), and the "sharedlibs" (things we build during the SHAREDLIB phase, these are TPLs that we build ourselves). Here's a list of changes I think we should implement regarding dependency management:
find_package
, using$PACKAGE_ROOT
to find it, and we should usetarget_link_libraries
to express the dependency.$package-config.cmake
files. We should strive to make these as CMake-3 style as possible, target-oriented. If the package is very far from being a modern cmake package, we can write our ownFind$package.cmake
module.target_link_libraries(eam ${GPTL_LIBRARIES})
$PACKAGE_ROOT
env var IF it's not already set. Something like this:<env name="NETCDF_ROOT">$SHELL{RESULT=${NETCDF_ROOT:-$DEFAULT_VALUE} echo $RESULT}}</env>
Where
DEFAULT_VALUE
is either hardcoded or references some env var from a module. If the module file itself sets$PACKAGE_ROOT
then this may break this approach. I don't know if any of them actually do that.$PACKAGE_ROOT
s are set correctly.$SHAREDLIB_ROOT
already exists and is populated, the build system should not try to rebuild it.common_setup.cmake
, which means it's run for every component. This is means a lot of the processing is repeated many times. We should factor this out and put it somewhere else so it runs only once.SLIBS
should almost entirely go away.Other considerations
CMAKE_C_FLAGS
instead ofCFLAGS
. This is tricky because some of the non-cmake sharedlibs expect the old Makefile-style names.common_setup.cmake
and, to a lesser extent,build_model.cmake
. This legacy stuff should be removed or refactored.bld/cmake-bld
instead of justbld
.Approach
An incremental approach is always preferable if possible. I think we should be able to move the dependencies, one-by-one, over to the new style.
Dependency list:
TPLs:
Sharedlibs:
Optional TPLs
Updating Sharedlibs to not require CIME/Tools/Makefile so we can change our cmake macros to use cmake names
Testing
We have to be very careful when refactoring the build system to not change the core semantics of how things get built. I used to have a script, way back in the initial cmake effort, that parsed the build log and created a map of targets and flags. This map could be compared against maps from other logs to do a global compare to ensure flags are identical or at least semantically identical. I'd also like to set up some tests for various use case, for example, ensuring that a user can use a custom
PACKAGE_ROOT
. I'm not sure the best way to do this yet... perhaps I can do this as an e3sm-specific part of the CIME regression suite or I can make a new test suite.Related PRs
#5948
#5950
#5959
ESMCI/cime#4492
#5964
#5972
#5975
#5976
#5990
#5993
#5995
#5997
#5998
#6005
#6009
#6025
#6028
#6014
#6069
The text was updated successfully, but these errors were encountered: