TriBITS icon indicating copy to clipboard operation
TriBITS copied to clipboard

EPIC: Refactoring TriBITS Core and TriBITS-based CMake projects to conform to modern CMake

Open bartlettroscoe opened this issue 4 years ago • 3 comments

Blocked by::

  • #367
  • trilinos/Trilinos#10355

Description

An initial version of TriBITS was created back in 2008 when CMake was on version 2.6.z (prior to 2.8, when CMake was still using even numbers for releases). There was a lot missing in those early versions of CMake needed to create a portable, scalable, build system for something like Trilinos. Therefore, a lot of features had to be added to TriBITS in those early days and in the next few years to address development, testing, and deployment challenges of Trilinos and other projects. That CMake build system was split out of Trilinos and named "TriBITS" around 2011 as part of the CASL project and was reused in several other projects (where it is still used today) and the majority of the development work for what is now TriBITS was completed by around 2014 (around the time that CMake 3.0 was released).

Around CMake 3.0 (which was not released until 2014), great improvements started to be made in CMake and the idioms for its usage, and the usage of CMake steadily improved across the computational and scientific and engineering community. In the 12 years since TriBITS was first created and especially in the last 7 years since CMake 3.0 and future releases of CMake 3.Y have come out, a lot of the functionality that was added to TriBITS has since been added to CMake proper and has been slowly adopted by the larger software development community using CMake. While reading the book "Professional CMake: 10th Edition", I have come to realize just how much of the functionality that we had to add to TriBITS ourselves has now been added to CMake proper. (And reading that book one realizes just how much functionality has been added to CMake in general since CMake 3.0 to address so many difficult cross-platform issues.)

It is in the best interest of Trilinos and all of the projects that use TriBITS to refactor their CMake build systems (and TriBITS itself) to switch over to the newer native CMake implementations of these features and to remove these features from TriBITS. In this process, TriBITS should be reduced the its smallest useful essence that provides value and does not stand in the way of adopting future CMake features as those are added in future CMake releases.

However, these changes need to be made incrementally against the develop branch of Trilinos and the master branch of TriBITS with frequent/numerous topic branches and frequent integrations to smooth the transitions with Trilinos developers and users.

This epic will list some of the areas where TriBITS, Trilinos, and other projects using TriBITS should be refactored to use native modern CMake features and idoms:

  • Switch from using deprecated find_package(PythonInterp) to find_package(Python3) to accommodate python3 installations (see #610). [Major break in backward comparability] [Done]

  • Use the standard CMake FortranCInterface.cmake module to handle Fortran/C name mangling. (This will replace a module copied into TriBITS back in 2007 that does this manually at configure time.) [Minor break in backward comparability]

  • Require standard install locations defined by the standard GNUInstallDirs.cmake module and vars CMAKE_INSTALL_<XXX> for BINDIR, LIBDIR, LIBDIR, INCLUDEDIR and replace TriBITS-defined locations <Project>_INSTALL_INCLUDE_DIR, <Project>_INSTALL_LIB_DIR, <Project>_INSTALL_RUNTIME_DIR. (NOTE: GNUInstallDirs.cmake has no equivalent for <Project>_INSTALL_EXAMPLE_DIR.) [Minor break in backward comparability]

  • Replace and remove old TriBITS General Utility Macros and Functions that have native implementations in newer versions of raw CMake. (E.g., append_string_var() => string(APPEND ...), append_string_var_with_sep() => string(JOIN ...), concat_strings() => string(CONCAT ...), join() => string(JOIN ...), multiline_set() => string(CONCAT ...), etc.)

  • Revise how RPATH is handled with TriBITS according to new RPATH variables and target properties for more flexibility and to better support relocatable installs (i.e. set set(CMAKE_INSTALL_RPATH $ORIGIN $ORIGIN${relBinToLibDir}) by default) . (Or, strip out RPATH handling altogether from TriBITS and leave raw CMake behavior for projects to deal with themselves.) [Minor break in backward comparability]

  • Use correct CamelCase for CMAKE_BULD_TYPE (see #131) [Minor break in backward comparability]

  • Support multi-configuration generators (e.g. Ninja and Visual Code), which requires not relying on CMAKE_BULD_TYPE and instead using generator expressions

  • TriBITS stop setting/manipulating compiler options:

    • Remove TriBITS overriding defaults for CMAKE_<LANG>_<CONFIG> (See CMAKE_<LANG>_<CONFIG>_OVERRIDE). (TriBITS should get out of the business of manipulating compiler options if possible.) [Minor break in backward comparability]

    • Don't set options for strong warnings. Let the project do that itself if it wants to. [Minor break in backward comparability]

    • Have TriBITS use find_package(OpenMP) and link against OpenMP::OpenMP_<lang> to handle compiler options (see https://github.com/kokkos/kokkos/issues/5514#issuecomment-1271617638). [Minor break in backward comparability]

    • ???

  • Switch deprecated code macros to the deprecation macros with the GenerateExportHeader.cmake module and the generate_export_header() function. [Minor break in backward comparability]

  • Switch from manual include guards to include_guard().

  • Move numerous checks for things like time.h, stdinit.h, inittypes.h, checks for isnan(), isinf(), etc., checks for doxygen, out of TriBITS env probing (individual projects or even individual packages should be doing that). [Minor break in backward comparability]

  • Consider switching to using find_package(MPI) (and the standard CMake FindMPI.cmake module) (see #628) [Major break in backward comparability?]

  • ???

Completed refactorings

  • Allow TriBITS packages to use raw CMake to define library and executable targets as long as they conform to the basic requirements for TriBITS-Compliant Packages and generate <Pacakge>Config.cmake files that are TriBITS-Compliant External Packages. (This will allow incorporating external raw CMake projects as TriBITS packages with little work and few changes.) [Done]
    • See #63 and #576

Child Issues

  • #429
  • #610

bartlettroscoe avatar Aug 30 '21 21:08 bartlettroscoe

FYI, the non-usage of the standard CMake FindMPI.cmake is an issue that should be addressed as well. See:

  • https://github.com/sandialabs/Albany/issues/985#issuecomment-1738020649

bartlettroscoe avatar Sep 27 '23 20:09 bartlettroscoe

FYI: It is amazing the shockwaves that have been produced in switching Trilinos to just use GNUInstallDirs.cmake by default on even just the local the Trilinos user community. See:

  • Albany: https://github.com/sandialabs/Albany/issues/985
  • Nalu: https://github.com/trilinos/Trilinos/issues/1232
  • Sierra: https://github.com/trilinos/Trilinos/issues/12306#issuecomment-1737844074
  • EMPIRE: Private email with Roger P.

SIDENOTE: It is amazing how much of a shockwave this one seemingly small non-backward compatible change to adopt one modern CMake practice has made on even just the local the Trilinos user community. This does not bode well for all of the changes to switch to modern CMake listed above ☹️.

bartlettroscoe avatar Sep 28 '23 14:09 bartlettroscoe

CC: @sebrowne, @ccober6

NOTE: The TriBITS module TribitsFindPythonInterp.cmake (created by Bill Spotz back in the day?) currently calls find_package(PythonInterp) which uses the module FindPythonInterp.cmake. According to:

  • https://cmake.org/cmake/help/v3.23/module/FindPythonInterp.html

the FindPythonInterp.cmake module has been deprecated since CMake 3.12! This should be updated to use FindPython.cmake or FindPython3.cmake.

See:

  • #610

bartlettroscoe avatar Jul 26 '24 16:07 bartlettroscoe