diff --git a/trilinos_source16/cmake/tribits/doc/build_ref/.gitignore b/trilinos_source16/cmake/tribits/doc/build_ref/.gitignore new file mode 100644 index 0000000000..1b38cb9c07 --- /dev/null +++ b/trilinos_source16/cmake/tribits/doc/build_ref/.gitignore @@ -0,0 +1,6 @@ +# Ignore generated files +/TribitsBuildReference.html +/TribitsBuildReference.pdf +/TribitsBuildReference.rst +/TribitsGitVersion.txt +/TribitsGitVersion.txt.tmp diff --git a/trilinos_source16/cmake/tribits/doc/build_ref/Makefile b/trilinos_source16/cmake/tribits/doc/build_ref/Makefile new file mode 100644 index 0000000000..cdc5ce57fd --- /dev/null +++ b/trilinos_source16/cmake/tribits/doc/build_ref/Makefile @@ -0,0 +1,40 @@ +##---------------------------------------------------------------------------## +## MAKEFILE +##---------------------------------------------------------------------------## + +EXTRA_ARGS= + +.PHONY: clean realclean all + +BASE_NAME = TribitsBuildReference +EXTRA_FILES = \ + Makefile \ + TribitsBuildReferenceBody.rst \ + TribitsBuildReferenceTemplate.rst + +# NOTE: We *don't* want to rebuild the file if only the version has changed we +# don't add a dependency on TribitsGitVersion.txt! + +CREATE_PROJECT_BUILD_REF_CMND = \ + ./create-project-build-ref.py \ + --project-name="" \ + --project-template-file=TribitsBuildReferenceTemplate.rst \ + --file-base=TribitsBuildReference + +all: $(EXTRA_FILES) + $(CREATE_PROJECT_BUILD_REF_CMND) \ + $(EXTRA_ARGS) + +$(BASE_NAME).rst: $(EXTRA_FILES) + $(CREATE_PROJECT_BUILD_REF_CMND) \ + --generate-html= --generate-latex= --generate-pdf= \ + $(EXTRA_ARGS) + +clean: + -rm -f $(BASE_NAME).rst + -rm -f $(BASE_NAME).html + -rm -f $(BASE_NAME).pdf + +##---------------------------------------------------------------------------## +## end of Makefile +##---------------------------------------------------------------------------## diff --git a/trilinos_source16/cmake/tribits/doc/build_ref/README b/trilinos_source16/cmake/tribits/doc/build_ref/README new file mode 100644 index 0000000000..ad4b06067d --- /dev/null +++ b/trilinos_source16/cmake/tribits/doc/build_ref/README @@ -0,0 +1,37 @@ +================================================================================ + TriBITS Build Reference Files +================================================================================ + +This directory contains files to create a project-specific build quick +reference document BuildReference.[rst,html,pdf]. The generic files +used for this purpose are: + + create-project-build-ref.py + TribitsBuildReferenceBody.rst + +See `create-project-build-ref.py --help` for details. + +This directory also contains a generic build of a BuildReference +document. The template file: + + TribitsBuildReferenceTemplate.rst + +is used to create the auto-generated (read-only) output files: + + TribitsBuildReference.html + TribitsBuildReference.pdf + TribitsBuildReference.rst + +using the script: + + create-build-ref.sh + +To run the script and update the output files, just do: + + $ cd + $ ./create-build-ref.sh + +That is all there is to it! + +The generated documents are then referred to by other general TriBITS +documentation. diff --git a/trilinos_source16/cmake/tribits/doc/build_ref/TribitsBuildReferenceBody.rst b/trilinos_source16/cmake/tribits/doc/build_ref/TribitsBuildReferenceBody.rst new file mode 100644 index 0000000000..3ab4ce13f1 --- /dev/null +++ b/trilinos_source16/cmake/tribits/doc/build_ref/TribitsBuildReferenceBody.rst @@ -0,0 +1,4493 @@ +.. Common references to other documents + +.. _TriBITS Users Guide and Reference: TribitsUsersGuide.html + +.. _Package Dependencies and Enable/Disable Logic: TribitsUsersGuide.html#package-dependencies-and-enable-disable-logic + +.. _TriBITS Dependency Handling Behaviors: TribitsUsersGuide.html#tribits-dependency-handling-behaviors + +.. _tribits_tpl_find_include_dirs_and_libraries(): TribitsUsersGuide.html#tribits-tpl-find-include-dirs-and-libraries + +.. _tribits_ctest_driver(): TribitsUsersGuide.html#tribits-ctest-driver + +.. _Ninja: https://ninja-build.org + +.. _CMake Ninja Fortran Support: https://cmake.org/cmake/help/latest/generator/Ninja.html + +.. _CTest Resource Allocation System: https://cmake.org/cmake/help/latest/manual/ctest.1.html#resource-allocation + +.. _CTest Resource Specification File: https://cmake.org/cmake/help/latest/manual/ctest.1.html#ctest-resource-specification-file + +.. _CTest Resource Allocation Environment Variables: https://cmake.org/cmake/help/latest/manual/ctest.1.html#environment-variables + +.. _RESOURCE_GROUPS: https://cmake.org/cmake/help/latest/prop_test/RESOURCE_GROUPS.html#prop_test:RESOURCE_GROUPS + + + +Getting set up to use CMake +=========================== + +Before one can configure to be built, one must first obtain a +version of CMake on the system newer than This guide assumes +that once CMake is installed that it will be in the default path with the name +``cmake``. + + +Installing a binary release of CMake [casual users] +--------------------------------------------------- + +Download and install the binary (version or greater is +recommended) from: + + http://www.cmake.org/cmake/resources/software.html + + +Installing CMake from source [developers and experienced users] +--------------------------------------------------------------- + +If you have access to the git repositories (which which includes a +snapshot of TriBITS), then install CMake with:: + + $ cd / + $ TRIBITS_BASE_DIR=/cmake/tribits + $ $TRIBITS_BASE_DIR/devtools_install/install-cmake.py \ + --install-dir-base= --cmake-version=X.Y.Z \ + --do-all + +This will result in cmake and related CMake tools being installed in +``/cmake-X.Y.Z/bin/`` (see the instructions printed at the +end on how to update your ``PATH`` env var). + +To get help for installing CMake with this script use:: + + $ $TRIBITS_BASE_DIR/devtools_install/install-cmake.py --help + +NOTE: You will want to read the help message about how to install CMake to +share with other users and maintainers and how to install with sudo if needed. + + +Installing Ninja from Source +---------------------------- + +The `Ninja`_ tool allows for much faster parallel builds for some large CMake +projects and performs much faster dependency analysis than the Makefiles +back-end build system. It also provides some other nice features like ``ninja +-n -d explain`` to show why the build system decides to (re)build the targets +that it decides to build. + +As of Ninja 1.10+, Fortran support is part of the official GitHub version of +Ninja as can be obtained from: + + https://github.com/ninja-build/ninja/releases + +(see `CMake Ninja Fortran Support`_). + +Ninja is easy to install from source on almost any machine. On Unix/Linux +systems it is as simple as ``configure --prefix=``, ``make`` and ``make +install``. + + +Getting CMake Help +================== + + +Finding CMake help at the website +--------------------------------- + + http://www.cmake.org + + +Building CMake help locally +--------------------------- + +To get help on CMake input options, run:: + + $ cmake --help + +To get help on a single CMake function, run:: + + $ cmake --help-command + +To generate the entire documentation at once, run:: + + $ cmake --help-full cmake.help.html + +(Open your web browser to the file cmake.help.html) + + +Configuring (Makefile, Ninja and other Generators) +=================================================== + +CMake supports a number of different build generators (e.g. Ninja, Eclipse, +XCode, MS Visual Studio, etc.) but the primary generator most people use on +Unix/Linux system is ``make`` (using the default cmake option ``-G"Unix +Makefiles"``) and CMake generated Makefiles. Another (increasingly) popular +generator is Ninja (using cmake option ``-GNinja``). Most of the material in +this section applies to all generators but most experience is for the +Makefiles and Ninja generators. + + +Setting up a build directory +---------------------------- + +In order to configure, one must set up a build directory. does +**not** support in-source builds so the build tree must be separate from the +source tree. The build tree can be created under the source tree such as +with:: + + $ cd / + $ mkdir + $ cd / + +but it is generally recommended to create a build directory parallel from the +source tree such as with:: + + / + / + / + +NOTE: If you mistakenly try to configure for an in-source build (e.g. with +'cmake .') you will get an error message and instructions on how to resolve +the problem by deleting the generated CMakeCache.txt file (and other generated +files) and then follow directions on how to create a different build directory +as shown above. + + +Basic configuration +------------------- + +A few different approaches for configuring are given below. + +* `Create a do-configure script [Recommended]`_ +* `Create a *.cmake file and point to it [Most Recommended]`_ +* `Using the QT CMake configuration GUI`_ + +.. _Create a do-configure script [Recommended]: + +a) Create a 'do-configure' script such as [Recommended]:: + + #!/bin/bash + cmake \ + -D CMAKE_BUILD_TYPE=DEBUG \ + -D _ENABLE_TESTS=ON \ + "$@" \ + ${SOURCE_BASE} + + and then run it with:: + + ./do-configure [OTHER OPTIONS] -D_ENABLE_=ON + + where ```` is a valid Package name (see above), etc. and + ``SOURCE_BASE`` is set to the source base directory (or your can + just give it explicitly in the script). + + See ``/sampleScripts/*`` for examples of real ``do-configure`` + scripts for different platforms. + + NOTE: If one has already configured once and one needs to configure from + scratch (needs to wipe clean defaults for cache variables, updates + compilers, other types of changes) then one will want to delete the local + CMakeCache.txt and other CMake-generated files before configuring again (see + `Reconfiguring completely from scratch`_). + +.. __CONFIGURE_OPTIONS_FILE: + +.. _Create a *.cmake file and point to it [Most Recommended]: + +b) Create a ``*.cmake`` file and point to it [Most Recommended]. + + Create a do-configure script like:: + + #!/bin/bash + cmake \ + -D _CONFIGURE_OPTIONS_FILE=MyConfigureOptions.cmake \ + -D _ENABLE_TESTS=ON \ + "$@" \ + ${SOURCE_BASE} + + where MyConfigureOptions.cmake (in the current working directory) might look + like:: + + set(CMAKE_BUILD_TYPE DEBUG CACHE STRING "Set in MyConfigureOptions.cmake") + set(_ENABLE_CHECKED_STL ON CACHE BOOL "Set in MyConfigureOptions.cmake") + set(BUILD_SHARED_LIBS ON CACHE BOOL "Set in MyConfigureOptions.cmake") + ... + + Using a configuration fragment ``*.cmake`` file allows for better reuse of + configure options across different configure scripts and better version + control of configure options. Using the comment ``"Set in + MyConfigureOptions.cmake"`` makes it easy see where that variable got set + when looking an the generated ``CMakeCache.txt`` file. Also, when this + ``*.cmake`` fragment file changes, CMake will automatically trigger a + reconfigure during a make (because it knows about the file and will check its + time stamp, unlike when using ``-C .cmake``, see below). + + One can use the ``FORCE`` option in the ``set()`` commands shown above and + that will override any value of the options that might already be set (but + when using ``-C`` to include this forced ``set( ... FORCE)`` will only + override the value if the file with the ``set()`` is listed after the + ``-D=`` command-line option). However, that will not allow the + user to override the options on the CMake command-line using + ``-D=`` so it is generally **not** desired to use ``FORCE``. + + One can also pass in a list of configuration fragment files separated by + commas ``','`` which will be read in the order they are given as:: + + -D _CONFIGURE_OPTIONS_FILE=.cmake,.cmake,... + + One can read in configure option files under the project source directory by + using the type ``STRING`` such as with:: + + -D _CONFIGURE_OPTIONS_FILE:STRING=cmake/MpiConfig1.cmake + + In this case, the relative paths will be with respect to the project base + source directory, not the current working directory (unlike when using ``-C + .cmake``, see below). (By specifying the type ``STRING``, one + turns off CMake interpretation as a ``FILEPATH``. Otherwise, the type + ``FILEPATH`` causes CMake to always interpret relative paths with respect to + the current working directory and set the absolute path). + + Note that CMake options files can also be read in using the built-in CMake + argument ``-C .cmake`` as:: + + cmake -C .cmake -C .cmake ... [other options] \ + ${SOURCE_BASE} + + However, there are some differences to using + ``_CONFIGURE_OPTIONS_FILE`` vs. ``-C`` to read in ``*.cmake`` files + to be aware of as described below: + + 1) One can use + ``-D_CONFIGURE_OPTIONS_FILE:STRING=/.cmake`` + with a relative path w.r.t. to the source tree to make it easier to point to + options files in the project source. Using ``cmake -C + /.cmake`` would require having to give the absolute + path ```` or a longer relative path from the build directory back + to the source directory. Having to give the absolute path to files in the + source tree complicates configure scripts in some cases (i.e. where the + project source directory location may not be known or easy to get). + + 2) When configuration files are read in using + ``_CONFIGURE_OPTIONS_FILE``, they will get reprocessed on every + reconfigure (such as when reconfigure happens automatically when running + ``make``). That means that if options change in those included ``*.cmake`` + files from the initial configure, then those updated options will get + automatically picked up in a reconfigure. But when processing ``*.cmake`` + files using the built-in ``-C .cmake`` argument, updated options will + not get set. Therefore, if one wants to have the ``*.cmake`` files + automatically be reprocessed, then one should use + ``_CONFIGURE_OPTIONS_FILE``. But if one does not want to have the + contents of the ``.cmake`` file reread on reconfigures, then one would + want to use ``-C .cmake``. + + 3) When using ``_CONFIGURE_OPTIONS_FILE``, one can create and use + parameterized ``*.cmake`` files that can be used with multiple TriBITS + projects. For example, one can have set statements like + ``set(${PROJECT_NAME}_ENABLE_Fortran OFF ...)`` since ``PROJECT_NAME`` is + known before the file is included. One cannot do that with ``-C`` and + instead would have to provide the full variables names specific for a given + TriBITS project. + + 4) When using ``_CONFIGURE_OPTIONS_FILE``, non-cache project-level + variables can be set in a ``*.cmake`` file that will impact the + configuration. When using the ``-C`` option, only variables set with + ``set( CACHE ...)`` will impact the configuration. + + 5) Cache variables forced set with ``set( CACHE + "" FORCE)`` in a ``.cmake`` file pulled in with ``-C + .cmake`` will only override a cache variable ``-D=`` + passed on the command-line if the ``-C .cmake`` argument comes + **after** the ``-D=`` argument (i.e. ``cmake + -D= -C .cmake``). Otherwise, if the order of the + ``-D`` and ``-C`` arguments is reversed (i.e. ``cmake -C .cmake + -D=``) then the forced ``set()`` statement **WILL NOT** + override the cache var set on the command-line with ``-D=``. + However, note that a forced ``set()`` statement **WILL** override other + cache vars set with non-forced ``set()`` statements ``set( + CACHE "")`` in the same ``*.cmake`` file or in previously read + ``-C .cmake`` files included on the command-line before the file ``-C + .cmake``. Alternatively, if the file is pulled in with + ``-D_CONFIGURE_OPTIONS_FILE=.cmake``, then a ``set( + CACHE "" FORCE)`` statement in a ``.cmake`` **WILL** + override a cache variable passed in on the command-line + ``-D=`` no matter the order of the arguments + ``-D_CONFIGURE_OPTIONS_FILE=.cmake`` and + ``-D=``. (This is because the file ``.cmake`` is + included as part of the processing of the project's top-level + ``CMakeLists.txt`` file.) + + 6) However, the ``*.cmake`` files specified by + ``_CONFIGURE_OPTIONS_FILE`` will only get read in **after** the + project's ``ProjectName.cmake`` and other ``set()`` statements are called at + the top of the project's top-level ``CMakeLists.txt`` file. So any CMake + cache variables that are set in this early CMake code will override cache + defaults set in the included ``*.cmake`` file. (This is why TriBITS + projects must be careful **not** to set default values for cache variables + directly like this but instead should set indirect + ``__DEFAULT`` non-cache variables.) But when a + ``*.cmake`` file is read in using ``-C``, then the ``set()`` statements in + those files will get processed before any in the project's + ``CMakeLists.txt`` file. So be careful about this difference in behavior + and carefully watch cache variable values actually set in the generated + ``CMakeCache.txt`` file. + + In other words, the context and impact of what get be set from a ``*.cmake`` + file read in through the built-in CMake ``-C`` argument is more limited + while the code listed in the ``*.cmake`` file pulled in with + ``-D_CONFIGURE_OPTIONS_FILE=.cmake`` behaves just like + regular CMake statements executed in the project's top-level + ``CMakeLists.txt`` file. In addition, any forced set statements in a + ``*.cmake`` file pulled in with ``-C`` **may or may not** override cache + vars sets on the command-line with ``-D=`` depending on the + order of the ``-C`` and ``-D`` options. (There is no order dependency for + ``*.cmake`` files passed in through + ``-D_CONFIGURE_OPTIONS_FILE=.cmake``.) + +.. _Using the QT CMake configuration GUI: + +c) Using the QT CMake configuration GUI: + + On systems where the QT CMake GUI is installed (e.g. Windows) the CMake GUI + can be a nice way to configure (or just explore options) if you + are a user. To make your configuration easily repeatable, you might want to + create a fragment file and just load it by setting + `_CONFIGURE_OPTIONS_FILE`_ in the GUI. + +Likely the most recommended approach to manage complex configurations is to +use ``*.cmake`` fragment files passed in through the +`_CONFIGURE_OPTIONS_FILE`_ option. This offers the greatest +flexibility and the ability to version-control the configuration settings. + + +Selecting the list of packages to enable +---------------------------------------- + +The project is broken up into a set of packages that can be enabled +(or disabled). For details and generic examples, see `Package Dependencies and +Enable/Disable Logic`_ and `TriBITS Dependency Handling Behaviors`_. + +See the following use cases: + +* `Determine the list of packages that can be enabled`_ +* `Print package dependencies`_ +* `Enable a set of packages`_ +* `Enable or disable tests for specific packages`_ +* `Enable to test all effects of changing a given package(s)`_ +* `Enable all packages (and optionally all tests)`_ +* `Disable a package and all its dependencies`_ +* `Remove all package enables in the cache`_ +* `Speed up debugging dependency handling`_ + + +Determine the list of packages that can be enabled +++++++++++++++++++++++++++++++++++++++++++++++++++ + +In order to see the list of available Packages to enable, just +run a basic CMake configure, enabling nothing, and then grep the output to see +what packages are available to enable. The full set of defined packages is +contained the lines starting with ``'Final set of enabled packages'`` and +``'Final set of non-enabled packages'``. If no packages are enabled by +default (which is base behavior), the full list of packages will be listed on +the line ``'Final set of non-enabled packages'``. Therefore, to see the +full list of defined packages, run:: + + ./do-configure 2>&1 | grep "Final set of .*enabled packages" + +Any of the packages shown on those lines can potentially be enabled using ``-D +_ENABLE_=ON`` (unless they are set to disabled +for some reason, see the CMake output for package disable warnings). + +Another way to see the full list of packages that can be enabled is to +configure with `_DUMP_PACKAGE_DEPENDENCIES`_ = ``ON`` and then grep +for ``_INTERNAL_PACKAGES`` using, for example:: + + ./do-configure 2>&1 | grep "_INTERNAL_PACKAGES: " + + +Print package dependencies +++++++++++++++++++++++++++ + +.. __DUMP_PACKAGE_DEPENDENCIES: + +The set of package dependencies can be printed in the ``cmake`` STDOUT by +setting the configure option:: + + -D _DUMP_PACKAGE_DEPENDENCIES=ON + +This will print the basic forward/upstream dependencies for each package. +To find this output, look for the line:: + + Printing package dependencies ... + +and the dependencies are listed below this for each package in the form:: + + -- _LIB_DEFINED_DEPENDENCIES: [O] <[PKG1>[R] ... + -- _TEST_DEFINED_DEPENDENCIES: [R] <[PKG8>[R] ... + +(Dependencies that don't exist are left out of the output. For example, if +there are no extra test dependencies, then ``_TEST_DEFINED_DEPENDENCIES`` +will not be printed.) + +To also see the direct forward/downstream dependencies for each package, +also include:: + + -D _DUMP_FORWARD_PACKAGE_DEPENDENCIES=ON + +These dependencies are printed along with the backward/upstsream dependencies +as described above. + +Both of these variables are automatically enabled when +`_VERBOSE_CONFIGURE`_ = ``ON``. + + +Enable a set of packages +++++++++++++++++++++++++ + +.. __ENABLE_ALL_OPTIONAL_PACKAGES: + +.. __ENABLE_TESTS: + +To enable a package ```` (and optionally also its tests and +examples), configure with:: + + -D _ENABLE_=ON \ + -D _ENABLE_ALL_OPTIONAL_PACKAGES=ON \ + -D _ENABLE_TESTS=ON \ + +This set of arguments allows a user to turn on ```` as well +as all packages that ```` can use. All of the package's +optional "can use" upstream dependent packages are enabled with +``-D_ENABLE_ALL_OPTIONAL_PACKAGES=ON``. However, +``-D_ENABLE_TESTS=ON`` will only enable tests and examples for +```` (and any other packages explicitly enabled). + +If a TriBITS package ```` has subpackages (e.g. subpackages +````, ````, ...), then enabling the package is equivalent to enabling +all of the required **and optional** subpackagses:: + + -D _ENABLE_=ON \ + -D _ENABLE_=ON \ + ... + +(In this case, the parent package's optional subpackages are enabled +regardless the value of ``_ENABLE_ALL_OPTIONAL_PACKAGES``.) + +However, a TriBITS subpackage will only be enabled if it is not already +disabled either explicitly or implicitly. + +NOTE: The CMake cache variable type for all ``XXX_ENABLE_YYY`` variables is +actually ``STRING`` and not ``BOOL``. That is because these enable variables +take on the string enum values of ``"ON"``, ``"OFF"``, end empty ``""``. An +empty enable means that the TriBITS dependency system is allowed to decide if +an enable should be turned on or off based on various logic. The CMake GUI +will enforce the values of ``"ON"``, ``"OFF"``, and empty ``""`` but it will +not enforce this if you set the value on the command line or in a ``set()`` +statement in an input ```*.cmake`` options files. However, setting +``-DXXX_ENABLE_YYY=TRUE`` and ``-DXXX_ENABLE_YYY=FALSE`` is allowed and will +be interpreted correctly.. + + +Enable or disable tests for specific packages ++++++++++++++++++++++++++++++++++++++++++++++ + +The enable tests for explicitly enabled packages, configure with:: + + -D _ENABLE_=ON \ + -D _ENABLE_=ON \ + -D _ENABLE_TESTS=ON \ + +This will result in the enable of the test suites for any package that +explicitly enabled with ``-D _ENABLE_=ON``. Note +that his will **not** result in the enable of the test suites for any packages +that may only be implicitly enabled in order to build the explicitly enabled +packages. + +.. __ENABLE_TESTS: + +If one wants to enable a package along with the enable of other packages, but +not the test suite for that package, then one can use a "exclude-list" +appraoch to disable the tests for that package by configuring with, for +example:: + + -D _ENABLE_=ON \ + -D _ENABLE_=ON \ + -D _ENABLE_=ON \ + -D _ENABLE_TESTS=ON \ + -D _ENABLE_TESTS=OFF \ + +The above will enable the package test suites for ```` and +```` but **not** for ```` (or any other +packages that might get implicitly enabled). One might use this approach if +one wants to build and install package ```` but does not +want to build and run the test suite for that package. + +Alternatively, one can use an "include-list" appraoch to enable packages and +only enable tests for specific packages, for example, configuring with:: + + -D _ENABLE_=ON \ + -D _ENABLE_TESTS=ON \ + -D _ENABLE_=ON \ + -D _ENABLE_=ON \ + -D _ENABLE_TESTS=ON \ + +That will have the same result as using the "exclude-list" approach above. + +**NOTE:** Setting ``_ENABLE_TESTS=ON`` will set +``_ENABLE_EXAMPLES=ON`` by default. Also, setting +``_ENABLE_TESTS=ON`` will result in setting +``_ENABLE_TESTS=ON`` for all subpackages in a parent +package that are explicitly enabled or are enabled in the forward sweep as a +result of `_ENABLE_ALL_FORWARD_DEP_PACKAGES`_ being set to ``ON``. + +These and other options give the user complete control of what packages get +enabled or disabled and what package test suites are enabled or disabled. + + +Enable to test all effects of changing a given package(s) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. __ENABLE_ALL_FORWARD_DEP_PACKAGES: + +To enable a package ```` to test it and all of its +down-stream packages, configure with:: + + -D _ENABLE_=ON \ + -D _ENABLE_ALL_FORWARD_DEP_PACKAGES=ON \ + -D _ENABLE_TESTS=ON \ + +The above set of arguments will result in package ```` and +all packages that depend on ```` to be enabled and have all +of their tests turned on. Tests will not be enabled in packages that do not +depend (at least implicitly) on ```` in this case. This +speeds up and robustifies testing for changes in specific packages (like in +per-merge testing in a continuous integration process). + +NOTE: setting ``_ENABLE_ALL_FORWARD_DEP_PACKAGES=ON`` also +automatically sets and overrides `_ENABLE_ALL_OPTIONAL_PACKAGES`_ to +be ``ON`` as well. (It makes no sense to want to enable forward dependent +packages for testing purposes unless you are enabling all optional packages.) + + +Enable all packages (and optionally all tests) +++++++++++++++++++++++++++++++++++++++++++++++ + +To enable all defined packages, add the configure option:: + + -D _ENABLE_ALL_PACKAGES=ON \ + +To also optionally enable the tests and examples in all of those enabled +packages, add the configure option:: + + -D _ENABLE_TESTS=ON \ + +Specific packages can be disabled (i.e. "exclude-listed") by adding +``_ENABLE_=OFF``. This will also disable all +packages that depend on ````. + +Note, all examples are also enabled by default when setting +``_ENABLE_TESTS=ON``. + +By default, setting ``_ENABLE_ALL_PACKAGES=ON`` only enables primary +tested (PT) packages and code. To have this also enable all secondary tested +(ST) packages and ST code in PT packages code, one must also set:: + + -D _ENABLE_SECONDARY_TESTED_CODE=ON \ + +NOTE: If this project is a "meta-project", then +``_ENABLE_ALL_PACKAGES=ON`` may not enable *all* the packages but +only the project's primary meta-project packages. See `Package Dependencies +and Enable/Disable Logic`_ and `TriBITS Dependency Handling Behaviors`_ for +details. + + +Disable a package and all its dependencies +++++++++++++++++++++++++++++++++++++++++++ + +To disable a package and all of the packages that depend on it, add the +configure option:: + + -D _ENABLE_=OFF + +For example:: + + -D _ENABLE_=ON \ + -D _ENABLE_ALL_OPTIONAL_PACKAGES=ON \ + -D _ENABLE_=OFF \ + +will enable ```` and all of the packages that it depends on +except for ```` and all of its forward dependencies. + +If a TriBITS package ```` has subpackages (e.g. a parent +package with subpackages ````, ````, ...), then disabling the parent +package is equivalent to disabling all of the required and optional +subpackages:: + + -D _ENABLE_=OFF \ + -D _ENABLE_=OFF \ + ... + +The disable of the subpackages in this case will override any enables. + +.. __DISABLE_ENABLED_FORWARD_DEP_PACKAGES: + +If a disabled package is a required dependency of some explicitly enabled +downstream package, then the configure will error out if:: + + -D _DISABLE_ENABLED_FORWARD_DEP_PACKAGES=OFF \ + +is set. Otherwise, if ``_DISABLE_ENABLED_FORWARD_DEP_PACKAGES=ON``, +a ``NOTE`` will be printed and the downstream package will be disabled and +configuration will continue. + + +Remove all package enables in the cache ++++++++++++++++++++++++++++++++++++++++ + +To wipe the set of package enables in the ``CMakeCache.txt`` file so they can +be reset again from scratch, re-configure with:: + + $ cmake -D _UNENABLE_ENABLED_PACKAGES=TRUE . + +This option will set to empty '' all package enables, leaving all other cache +variables as they are. You can then reconfigure with a new set of package +enables for a different set of packages. This allows you to avoid more +expensive configure time checks (like the standard CMake compiler checks) and +to preserve other cache variables that you have set and don't want to loose. +For example, one would want to do this to avoid more expensive compiler and +TPL checks. + + +Speed up debugging dependency handling ++++++++++++++++++++++++++++++++++++++++ + +To speed up debugging the package enable/disable dependency handling, set the +cache variable:: + + -D _TRACE_DEPENDENCY_HANDLING_ONLY=ON + +This will result in only performing the package enable/disable dependency +handling logic and tracing what would be done to configure the compilers and +configure the various enabled packages but not actually do that work. This +can greatly speed up the time to complete the ``cmake`` configure command when +debugging the dependency handling (or when creating tests that check that +behavior). + + +Selecting compiler and linker options +------------------------------------- + +The compilers for C, C++, and Fortran will be found by default by CMake if +they are not otherwise specified as described below (see standard CMake +documentation for how default compilers are found). The most direct way to +set the compilers are to set the CMake cache variables:: + + -D CMAKE__COMPILER= + +The path to the compiler can be just a name of the compiler +(e.g. ``-DCMAKE_C_COMPILER=gcc``) or can be an absolute path +(e.g. ``-DCMAKE_C_COMPILER=/usr/local/bin/cc``). The safest and more direct +approach to determine the compilers is to set the absolute paths using, for +example, the cache variables:: + + -D CMAKE_C_COMPILER=/opt/my_install/bin/gcc \ + -D CMAKE_CXX_COMPILER=/opt/my_install/bin/g++ \ + -D CMAKE_Fortran_COMPILER=/opt/my_install/bin/gfortran + +or if ``TPL_ENABLE_MPI=ON`` (see `Configuring with MPI support`_) something +like:: + + -D CMAKE_C_COMPILER=/opt/my_install/bin/mpicc \ + -D CMAKE_CXX_COMPILER=/opt/my_install/bin/mpicxx \ + -D CMAKE_Fortran_COMPILER=/opt/my_install/bin/mpif90 + +If these the CMake cache variables are not set, then CMake will use the +compilers specified in the environment variables ``CC``, ``CXX``, and ``FC`` +for C, C++ and Fortran, respectively. If one needs to drill down through +different layers of scripts, then it can be useful to set the compilers using +these environment variables. But in general is it recommended to be explicit +and use the above CMake cache variables to set the absolute path to the +compilers to remove all ambiguity. + +If absolute paths to the compilers are not specified using the CMake cache +variables or the environment variables as described above, then in MPI mode +(i.e. ``TPL_ENABLE_MPI=ON``) TriBITS performs its own search for the MPI +compiler wrappers that will find the correct compilers for most MPI +distributions (see `Configuring with MPI support`_). However, if in serial +mode (i.e. ``TPL_ENABLE_MPI=OFF``), then CMake will do its own default +compiler search. The algorithm by which raw CMake finds these compilers is +not precisely documented (and seems to change based on the platform). +However, on Linux systems, the observed algorithm appears to be: + +1. Search for the C compiler first by looking in ``PATH`` (or the equivalent + on Windows), starting with a compiler with the name ``cc`` and then moving + on to other names like ``gcc``, etc. This first compiler found is set to + ``CMAKE_C_COMPILER``. + +2. Search for the C++ compiler with names like ``c++``, ``g++``, etc., but + restrict the search to the same directory specified by base path to the C + compiler given in the variable ``CMAKE_C_COMPILER``. The first compiler + that is found is set to ``CMAKE_CXX_COMPILER``. + +3. Search for the Fortran compiler with names like ``f90``, ``gfortran``, + etc., but restrict the search to the same directory specified by base path + to the C compiler given in the variable ``CMAKE_C_COMPILER``. The first + compiler that is found is set to ``CMAKE_Fortran_COMPILER``. + +**WARNING:** While this built-in CMake compiler search algorithm may seems +reasonable, it fails to find the correct compilers in many cases for a non-MPI +serial build. For example, if a newer version of GCC is installed and is put +first in ``PATH``, then CMake will fail to find the updated ``gcc`` compiler +and will instead find the default system ``cc`` compiler (usually under +``/usr/bin/cc`` on Linux may systems) and will then only look for the C++ and +Fortran compilers under that directory. This will fail to find the correct +updated compilers because GCC does not install a C compiler named ``cc``! +Therefore, if you want to use the default CMake compiler search to find the +updated GCC compilers, you can set the CMake cache variable:: + + -D CMAKE_C_COMPILER=gcc + +or can set the environment variable ``CC=gcc``. Either one of these will +result in CMake finding the updated GCC compilers found first in ``PATH``. + +Once one has specified the compilers, one can also set the compiler flags, but +the way that CMake does this is a little surprising to many people. But the + TriBITS CMake build system offers the ability to tweak the built-in +CMake approach for setting compiler flags. First some background is in order. +When CMake creates the object file build command for a given source file, it +passes in flags to the compiler in the order:: + + ${CMAKE__FLAGS} ${CMAKE__FLAGS_} + +where ```` = ``C``, ``CXX``, or ``Fortran`` and ```` = +``DEBUG`` or ``RELEASE``. Note that the options in +``CMAKE__FLAGS_`` come after and override those in +``CMAKE__FLAGS``! The flags in ``CMAKE__FLAGS`` apply to all +build types. Optimization, debug, and other build-type-specific flags are set +in ``CMAKE__FLAGS_``. CMake automatically provides a +default set of debug and release optimization flags for +``CMAKE__FLAGS_`` (e.g. ``CMAKE_CXX_FLAGS_DEBUG`` is +typically ``"-g -O0"`` while ``CMAKE_CXX_FLAGS_RELEASE`` is typically +``"-O3"``). This means that if you try to set the optimization level with +``-DCMAKE_CXX_FLAGS="-04"``, then this level gets overridden by the flags +specified in ``CMAKE__FLAGS_BUILD`` or ``CMAKE__FLAGS_RELEASE``. + +TriBITS will set defaults for ``CMAKE__FLAGS`` and +``CMAKE__FLAGS_``, which may be different that what +raw CMake would set. TriBITS provides a means for project and package +developers and users to set and override these compiler flag variables +globally and on a package-by-package basis. Below, the facilities for +manipulating compiler flags is described. + +To see that the full set of compiler flags one has to actually build a target +by running, for example, ``make VERBOSE=1 `` (see `Building with +verbose output without reconfiguring`_). (NOTE: One can also see the exact +set of flags used for each target in the generated ``build.ninja`` file when +using the Ninja generator.) One cannot just look at the cache variables for +``CMAKE__FLAGS`` and ``CMAKE__FLAGS_`` in the +file ``CMakeCache.txt`` and see the full set of flags are actually being used. +These variables can override the cache variables by TriBITS as project-level +local non-cache variables as described below (see `Overriding CMAKE_BUILD_TYPE +debug/release compiler options`_). + +The TriBITS CMake build system will set up default compile flags for +GCC ('GNU') in development mode +(i.e. ``_ENABLE_DEVELOPMENT_MODE=ON``) on order to help produce +portable code. These flags set up strong warning options and enforce language +standards. In release mode (i.e. ``_ENABLE_DEVELOPMENT_MODE=OFF``), +these flags are not set. These flags get set internally into the variables +``CMAKE__FLAGS`` (when processing packages, not at the global cache +variable level) but the user can append flags that override these as described +below. + + +Configuring to build with default debug or release compiler flags ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. _CMAKE_BUILD_TYPE: + +To build a debug version, pass into 'cmake':: + + -D CMAKE_BUILD_TYPE=DEBUG + +This will result in debug flags getting passed to the compiler according to +what is set in ``CMAKE__FLAGS_DEBUG``. + +To build a release (optimized) version, pass into 'cmake':: + + -D CMAKE_BUILD_TYPE=RELEASE + +This will result in optimized flags getting passed to the compiler according +to what is in ``CMAKE__FLAGS_RELEASE``. + +The default build type is typically ``CMAKE_BUILD_TYPE=RELEASE`` unless ``-D +USE_XSDK_DEFAULTS=TRUE`` is set in which case the default build type is +``CMAKE_BUILD_TYPE=DEBUG`` as per the xSDK configure standard. + + +Adding arbitrary compiler flags but keeping default build-type flags +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +To append arbitrary compiler flags to ``CMAKE__FLAGS`` (which may be +set internally by TriBITS) that apply to all build types, configure with:: + + -D CMAKE__FLAGS="" + +where ```` are your extra compiler options like +``"-DSOME_MACRO_TO_DEFINE -funroll-loops"``. These options will get +appended to (i.e. come after) other internally defined compiler option and +therefore override them. The options are then pass to the compiler in the +order:: + + \ + ${CMAKE__FLAGS_} + +This that setting ``CMAKE__FLAGS`` can override the default flags that +TriBITS will set for ``CMAKE__FLAGS`` but will **not** override flags +specified in ``CMAKE__FLAGS_``. + +Instead of directly setting the CMake cache variables ``CMAKE__FLAGS`` +one can instead set environment variables ``CFLAGS``, ``CXXFLAGS`` and +``FFLAGS`` for ``CMAKE_C_FLAGS``, ``CMAKE_CXX_FLAGS`` and +``CMAKE_Fortran_FLAGS``, respectively. + +In addition, if ``-DUSE_XSDK_DEFAULTS=TRUE`` is set, then one can also pass +in Fortran flags using the environment variable ``FCFLAGS`` (raw CMake does +not recognize ``FCFLAGS``). But if ``FFLAGS`` and ``FCFLAGS`` are both set, +then they must be the same or a configure error will occur. + +Options can also be targeted to a specific TriBITS package using:: + + -D __FLAGS="" + +The package-specific options get appended **after** those already in +``CMAKE__FLAGS`` and therefore override (but not replace) those set +globally in ``CMAKE__FLAGS`` (either internally in the CMakeLists.txt +files or by the user in the cache). + +In addition, flags can be targeted to a specific TriBITS subpackage using the +same syntax:: + + -D __FLAGS="" + +If top-level package-specific flags and subpackage-specific flags are both set +for the same parent package such as with:: + + -D SomePackage__FLAGS="" \ + -D SomePackageSpkgA__FLAGS="" \ + +then the flags for the subpackage ``SomePackageSpkgA`` will be listed after +those for its parent package ``SomePackage`` on the compiler command-line as:: + + + +That way, compiler options for a subpackage override flags set for the parent +package. + +NOTES: + +1) Setting ``CMAKE__FLAGS`` as a cache variable by the user on input be +listed after and therefore override, but will not replace, any internally set +flags in ``CMAKE__FLAGS`` defined by the CMake system. To get +rid of these project/TriBITS set compiler flags/options, see the below items. + +2) Given that CMake passes in flags in +``CMAKE__FLAGS_`` after those in +``CMAKE__FLAGS`` means that users setting the ``CMAKE__FLAGS`` +and ``__FLAGS`` will **not** override the flags in +``CMAKE__FLAGS_`` which come after on the compile +line. Therefore, setting ``CMAKE__FLAGS`` and +``__FLAGS`` should only be used for options that will +not get overridden by the debug or release compiler flags in +``CMAKE__FLAGS_``. However, setting +``CMAKE__FLAGS`` will work well for adding extra compiler defines +(e.g. -DSOMETHING) for example. + +WARNING: Any options that you set through the cache variable +``CMAKE__FLAGS_`` will get overridden in the + CMake system for GNU compilers in development mode so don't try to +manually set ``CMAKE__FLAGS_`` directly! To +override those options, see +``CMAKE__FLAGS__OVERRIDE`` below. + + +Overriding CMAKE_BUILD_TYPE debug/release compiler options +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +To override the default CMake-set options in +``CMAKE__FLAGS_``, use:: + + -D CMAKE__FLAGS__OVERRIDE="" + +For example, to default debug options use:: + + -D CMAKE_C_FLAGS_DEBUG_OVERRIDE="-g -O1" \ + -D CMAKE_CXX_FLAGS_DEBUG_OVERRIDE="-g -O1" + -D CMAKE_Fortran_FLAGS_DEBUG_OVERRIDE="-g -O1" + +and to override default release options use:: + + -D CMAKE_C_FLAGS_RELEASE_OVERRIDE="-O3 -funroll-loops" \ + -D CMAKE_CXX_FLAGS_RELEASE_OVERRIDE="-03 -funroll-loops" + -D CMAKE_Fortran_FLAGS_RELEASE_OVERRIDE="-03 -funroll-loops" + +NOTES: The TriBITS CMake cache variable +``CMAKE__FLAGS__OVERRIDE`` is used and not +``CMAKE__FLAGS_`` because is given a default +internally by CMake and the new variable is needed to make the override +explicit. + + +Turning off strong warnings for individual packages ++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. __DISABLE_STRONG_WARNINGS: + +To turn off strong warnings (for all languages) for a given TriBITS package, +set:: + + -D _DISABLE_STRONG_WARNINGS=ON + +This will only affect the compilation of the sources for +````, not warnings generated from the header files in +downstream packages or client code. + +Note that strong warnings are only enabled by default in development mode +(``_ENABLE_DEVELOPMENT_MODE==ON``) but not release mode +(``_ENABLE_DEVELOPMENT_MODE==ON``). A release of should +therefore not have strong warning options enabled. + + +Overriding all (strong warnings and debug/release) compiler options ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +To override all compiler options, including both strong warning options +and debug/release options, configure with:: + + -D CMAKE_C_FLAGS="-O3 -funroll-loops" \ + -D CMAKE_CXX_FLAGS="-03 -fexceptions" \ + -D CMAKE_BUILD_TYPE=NONE \ + -D _ENABLE_STRONG_C_COMPILE_WARNINGS=OFF \ + -D _ENABLE_STRONG_CXX_COMPILE_WARNINGS=OFF \ + -D _ENABLE_SHADOW_WARNINGS=OFF \ + -D _ENABLE_COVERAGE_TESTING=OFF \ + -D _ENABLE_CHECKED_STL=OFF \ + +NOTE: Options like ``_ENABLE_SHADOW_WARNINGS``, +``_ENABLE_COVERAGE_TESTING``, and ``_ENABLE_CHECKED_STL`` +do not need to be turned off by default but they are shown above to make it +clear what other CMake cache variables can add compiler and link arguments. + +NOTE: By setting ``CMAKE_BUILD_TYPE=NONE``, then ``CMAKE__FLAGS_NONE`` +will be empty and therefore the options set in ``CMAKE__FLAGS`` will +be all that is passed in. + + +Enable and disable shadowing warnings for all packages +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +To enable shadowing warnings for all packages (that don't already +have them turned on) then use:: + + -D _ENABLE_SHADOW_WARNINGS=ON + +To disable shadowing warnings for all packages (even those that +have them turned on by default) then use:: + + -D _ENABLE_SHADOW_WARNINGS=OFF + +NOTE: The default value is empty '' which lets each package +decide for itself if shadowing warnings will be turned on or off for that +package. + + +Removing warnings as errors for CLEANED packages +++++++++++++++++++++++++++++++++++++++++++++++++ + +To remove the ``-Werror`` flag (or some other flag that is set) from being +applied to compile CLEANED packages (like the Trilinos package Teuchos), set +the following when configuring:: + + -D _WARNINGS_AS_ERRORS_FLAGS="" + + +Adding debug symbols to the build ++++++++++++++++++++++++++++++++++ + +To get the compiler to add debug symbols to the build, configure with:: + + -D _ENABLE_DEBUG_SYMBOLS=ON + +This will add ``-g`` on most compilers. NOTE: One does **not** generally need +to create a full debug build to get debug symbols on most compilers. + + +Printing out compiler flags for each package +++++++++++++++++++++++++++++++++++++++++++++ + +To print out the exact ``CMAKE__FLAGS`` that will be used for each +package, set:: + + -D _PRINT_PACKAGE_COMPILER_FLAGS=ON + +That will print lines in STDOUT that are formatted as:: + + : CMAKE__FLAGS="" + : CMAKE__FLAGS_="" + +This will print the value of the ``CMAKE__FLAGS`` and +``CMAKE__FLAGS_`` variables that are used as each package is +being processed and will contain the flags in the exact order they are applied +by CMake + + +Appending arbitrary libraries and link flags every executable ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +In order to append any set of arbitrary libraries and link flags to your +executables use:: + + -D_EXTRA_LINK_FLAGS="" \ + -DCMAKE_EXE_LINKER_FLAGS="" + +Above, you can pass any type of library and they will always be the last +libraries listed, even after all of the TPLs. + +NOTE: This is how you must set extra libraries like Fortran libraries and +MPI libraries (when using raw compilers). Please only use this variable +as a last resort. + +NOTE: You must only pass in libraries in ``_EXTRA_LINK_FLAGS`` and +*not* arbitrary linker flags. To pass in extra linker flags that are not +libraries, use the built-in CMake variable ``CMAKE_EXE_LINKER_FLAGS`` +instead. The TriBITS variable ``_EXTRA_LINK_FLAGS`` is badly named +in this respect but the name remains due to backward compatibility +requirements. + + +Enabling support for Ninja +-------------------------- + +The `Ninja`_ build tool can be used as the back-end build tool instead of +Makefiles by adding:: + + -GNinja + +to the CMake configure line (the default on most Linux and OSX platforms is +``-G"Unix Makefiles"``). This instructs CMake to create the back-end +``ninja`` build files instead of back-end Makefiles (see `Building (Ninja +generator)`_). + +.. __WRITE_NINJA_MAKEFILES: + +In addition, the TriBITS build system will, by default, generate Makefiles in +every binary directory where there is a CMakeLists.txt file in the source +tree. These Makefiles have targets scoped to that subdirectory that use +``ninja`` to build targets in that subdirectory just like with the native +CMake recursive ``-G "Unix Makefiles"`` generator. This allows one to ``cd`` +into any binary directory and type ``make`` to build just the targets in that +directory. These TriBITS-generated Ninja makefiles also support ``help`` and +``help-objects`` targets making it easy to build individual executables, +libraries and object files in any binary subdirectory. + +**WARNING:** Using ``make -j`` with these TriBITS-generated Ninja Makefiles +will **not** result in using ```` processes to build in parallel and will +instead use **all** of the free cores to build on the machine! To control the +number of processes used, run ``make NP=`` instead! See `Building in +parallel with Ninja`_. + +The generation of these Ninja makefiles can be disabled by setting:: + + -D_WRITE_NINJA_MAKEFILES=OFF + +(But these Ninja Makefiles get created very quickly even for a very large +CMake project so there is usually little reason to not generate them.) + + +Limiting parallel compile and link jobs for Ninja builds +-------------------------------------------------------- + +When the CMake generator Ninja is used (i.e. ``-GNinja``), one can limit the +number of parallel jobs that are used for compiling object files by setting:: + + -D _PARALLEL_COMPILE_JOBS_LIMIT= + +and/or limit the number of parallel jobs that are used for linking libraries +and executables by setting:: + + -D _PARALLEL_LINK_JOBS_LIMIT= + +where ```` and ```` are integers like ``20`` and ``4``. If these are +not set, then the number of parallel jobs will be determined by the ``-j

`` +argument passed to ``ninja -j

`` or by ninja automatically according to +machine load when running ``ninja``. + +Limiting the number of link jobs can be useful, for example, for certain +builds of large projects where linking many jobs in parallel can consume all +of the RAM on a given system and crash the build. + +NOTE: These options are ignored when using Makefiles or other CMake +generators. They only work for the Ninja generator. + + +Disabling explicit template instantiation for C++ +------------------------------------------------- + +By default, support for optional explicit template instantiation (ETI) for C++ +code is enabled. To disable support for optional ETI, configure with:: + + -D _ENABLE_EXPLICIT_INSTANTIATION=OFF + +When ``OFF``, all packages that have templated C++ code will use implicit +template instantiation (unless they have hard-coded usage of ETI). + +ETI can be enabled (``ON``) or disabled (``OFF``) for individual packages +with:: + + -D _ENABLE_EXPLICIT_INSTANTIATION=[ON|OFF] + +The default value for ``_ENABLE_EXPLICIT_INSTANTIATION`` is +set by ``_ENABLE_EXPLICIT_INSTANTIATION``. + +For packages that support it, explicit template instantiation can massively +reduce the compile times for the C++ code involved and can even avoid compiler +crashes in some cases. To see what packages support explicit template +instantiation, just search the CMakeCache.txt file for variables with +``ENABLE_EXPLICIT_INSTANTIATION`` in the name. + + +Disabling the Fortran compiler and all Fortran code +--------------------------------------------------- + +To disable the Fortran compiler and all code that depends on Fortran +set:: + + -D _ENABLE_Fortran=OFF + +NOTE: The Fortran compiler may be disabled automatically by default on systems +like MS Windows. + +NOTE: Most Apple Macs do not come with a compatible Fortran compiler by +default so you must turn off Fortran if you don't have a compatible Fortran +compiler. + + +Enabling runtime debug checking +------------------------------- + +a) Enabling ifdefed runtime debug checking: + + To turn on optional ifdefed runtime debug checking, configure with:: + + -D _ENABLE_DEBUG=ON + + This will result in a number of ifdefs to be enabled that will perform a + number of runtime checks. Nearly all of the debug checks in will + get turned on by default by setting this option. This option can be set + independent of ``CMAKE_BUILD_TYPE`` (which sets the compiler debug/release + options). + + NOTES: + + * The variable ``CMAKE_BUILD_TYPE`` controls what compiler options are + passed to the compiler by default while ``_ENABLE_DEBUG`` + controls what defines are set in config.h files that control ifdefed debug + checks. + + * Setting ``-DCMAKE_BUILD_TYPE=DEBUG`` will automatically set the + default ``_ENABLE_DEBUG=ON``. + +b) Enabling checked STL implementation: + + To turn on the checked STL implementation set:: + + -D _ENABLE_CHECKED_STL=ON + + NOTES: + + * By default, this will set -D_GLIBCXX_DEBUG as a compile option for all C++ + code. This only works with GCC currently. + + * This option is disabled by default because to enable it by default can + cause runtime segfaults when linked against C++ code that was compiled + without -D_GLIBCXX_DEBUG. + + +Configuring with MPI support +---------------------------- + +To enable MPI support you must minimally set:: + + -D TPL_ENABLE_MPI=ON + +There is built-in logic to try to find the various MPI components on your +system but you can override (or make suggestions) with:: + + -D MPI_BASE_DIR="path" + +(Base path of a standard MPI installation which has the subdirs 'bin', 'libs', +'include' etc.) + +or:: + + -D MPI_BIN_DIR="path1;path2;...;pathn" + +which sets the paths where the MPI executables (e.g. mpiCC, mpicc, mpirun, +mpiexec) can be found. By default this is set to ``${MPI_BASE_DIR}/bin`` if +``MPI_BASE_DIR`` is set. + +**NOTE:** TriBITS uses the MPI compiler wrappers (e.g. mpiCC, mpicc, mpic++, +mpif90, etc.) which is more standard with other builds systems for HPC +computing using MPI (and the way that MPI implementations were meant to be +used). But directly using the MPI compiler wrappers as the direct compilers +is inconsistent with the way that the standard CMake module ``FindMPI.cmake`` +which tries to "unwrap" the compiler wrappers and grab out the raw underlying +compilers and the raw compiler and linker command-line arguments. In this +way, TriBITS is more consistent with standard usage in the HPC community but +is less consistent with CMake (see "HISTORICAL NOTE" below). + +There are several different different variations for configuring with MPI +support: + +a) **Configuring build using MPI compiler wrappers:** + + The MPI compiler wrappers are turned on by default. There is built-in logic + in TriBITS that will try to find the right MPI compiler wrappers. However, + you can specifically select them by setting, for example:: + + -D MPI_C_COMPILER:FILEPATH=mpicc \ + -D MPI_CXX_COMPILER:FILEPATH=mpic++ \ + -D MPI_Fortan_COMPILER:FILEPATH=mpif77 + + which gives the name of the MPI C/C++/Fortran compiler wrapper executable. + In this case, just the names of the programs are given and absolute path of + the executables will be searched for under ``${MPI_BIN_DIR}/`` if the cache + variable ``MPI_BIN_DIR`` is set, or in the default path otherwise. The + found programs will then be used to set the cache variables + ``CMAKE_[C,CXX,Fortran]_COMPILER``. + + One can avoid the search and just use the absolute paths with, for example:: + + -D MPI_C_COMPILER:FILEPATH=/opt/mpich/bin/mpicc \ + -D MPI_CXX_COMPILER:FILEPATH=/opt/mpich/bin/mpic++ \ + -D MPI_Fortan_COMPILER:FILEPATH=/opt/mpich/bin/mpif77 + + However, you can also directly set the variables + ``CMAKE_[C,CXX,Fortran]_COMPILER`` with, for example:: + + -D CMAKE_C_COMPILER:FILEPATH=/opt/mpich/bin/mpicc \ + -D CMAKE_CXX_COMPILER:FILEPATH=/opt/mpich/bin/mpic++ \ + -D CMAKE_Fortan_COMPILER:FILEPATH=/opt/mpich/bin/mpif77 + + **WARNING:** If you set just the compiler names and not the absolute paths + with ``CMAKE__COMPILER`` in MPI mode, then a search will not be done + and these will be expected to be in the path at build time. (Note that his + is inconsistent the behavior of raw CMake in non-MPI mode described in + `Selecting compiler and linker options`_). If both + ``CMAKE__COMPILER`` and ``MPI__COMPILER`` are set, however, then + ``CMAKE__COMPILER`` will be used and ``MPI__COMPILER`` will be + ignored. + + Note that when ``USE_XSDK_DEFAULTS=FALSE`` (see `xSDK Configuration + Options`_), then the environment variables ``CC``, ``CXX`` and ``FC`` are + ignored. But when ``USE_XSDK_DEFAULTS=TRUE`` and the CMake cache variables + ``CMAKE_[C,CXX,Fortran]_COMPILER`` are not set, then the environment + variables ``CC``, ``CXX`` and ``FC`` will be used for + ``CMAKE_[C,CXX,Fortran]_COMPILER``, even if the CMake cache variables + ``MPI_[C,CXX,Fortran]_COMPILER`` are set! So if one wants to make sure and + set the MPI compilers irrespective of the xSDK mode, then one should set + cmake cache variables ``CMAKE_[C,CXX,Fortran]_COMPILER`` to the absolute + path of the MPI compiler wrappers. + + **HISTORICAL NOTE:** The TriBITS system has its own custom MPI integration + support and does not (currently) use the standard CMake module + ``FindMPI.cmake``. This custom support for MPI was added to TriBITS in 2008 + when it was found the built-in ``FindMPI.cmake`` module was not sufficient + for the needs of Trilinos and the approach taken by the module (still in use + as of CMake 3.4.x) which tries to unwrap the raw compilers and grab the list + of include directories, link libraries, etc, was not sufficiently portable + for the systems where Trilinos needed to be used. But earlier versions of + TriBITS used the ``FindMPI.cmake`` module and that is why the CMake cache + variables ``MPI_[C,CXX,Fortran]_COMPILER`` are defined and still supported. + +b) **Configuring to build using raw compilers and flags/libraries:** + + While using the MPI compiler wrappers as described above is the preferred + way to enable support for MPI, you can also just use the raw compilers and + then pass in all of the other information that will be used to compile and + link your code. + + To turn off the MPI compiler wrappers, set:: + + -D MPI_USE_COMPILER_WRAPPERS=OFF + + You will then need to manually pass in the compile and link lines needed to + compile and link MPI programs. The compile flags can be set through:: + + -D CMAKE_[C,CXX,Fortran]_FLAGS="$EXTRA_COMPILE_FLAGS" + + The link and library flags must be set through:: + + -D _EXTRA_LINK_FLAGS="$EXTRA_LINK_FLAGS" + + Above, you can pass any type of library or other linker flags in and they + will always be the last libraries listed, even after all of the TPLs. + + NOTE: A good way to determine the extra compile and link flags for MPI is to + use:: + + export EXTRA_COMPILE_FLAGS="`$MPI_BIN_DIR/mpiCC --showme:compile`" + + export EXTRA_LINK_FLAGS="`$MPI_BIN_DIR/mpiCC --showme:link`" + + where ``MPI_BIN_DIR`` is set to your MPI installations binary directory. + +c) **Setting up to run MPI programs:** + + In order to use the ctest program to run MPI tests, you must set the mpi + run command and the options it takes. The built-in logic will try to find + the right program and options but you will have to override them in many + cases. + + MPI test and example executables are passed to CTest ``add_test()`` as:: + + add_test(NAME COMMAND + ${MPI_EXEC} ${MPI_EXEC_PRE_NUMPROCS_FLAGS} + ${MPI_EXEC_NUMPROCS_FLAG} + ${MPI_EXEC_POST_NUMPROCS_FLAGS} + ) + + where ````, ````, and ```` are specific + to the test being run. + + The test-independent MPI arguments are:: + + -D MPI_EXEC:FILEPATH="exec_name" + + (The name of the MPI run command (e.g. mpirun, mpiexec) that is used to run + the MPI program. This can be just the name of the program in which case + the full path will be looked for in ``${MPI_BIN_DIR}`` as described above. + If it is an absolute path, it will be used without modification.) + + :: + + -D MPI_EXEC_DEFAULT_NUMPROCS=4 + + (The default number of processes to use when setting up and running + MPI test and example executables. The default is set to '4' and only + needs to be changed when needed or desired.) + + :: + + -D MPI_EXEC_MAX_NUMPROCS=4 + + (The maximum number of processes to allow when setting up and running MPI + tests and examples that use MPI. The default is set to '4' but should be + set to the largest number that can be tolerated for the given machine or the + most cores on the machine that you want the test suite to be able to use. + Tests and examples that require more processes than this are excluded from + the CTest test suite at configure time. ``MPI_EXEC_MAX_NUMPROCS`` is also + used to exclude tests in a non-MPI build (i.e. ``TPL_ENABLE_MPI=OFF``) if + the number of required cores for a given test is greater than this value.) + + :: + + -D MPI_EXEC_NUMPROCS_FLAG=-np + + (The command-line option just before the number of processes to use + ````. The default value is based on the name of ``${MPI_EXEC}``, for + example, which is ``-np`` for OpenMPI.) + + :: + + -D MPI_EXEC_PRE_NUMPROCS_FLAGS="arg1;arg2;...;argn" + + (Other command-line arguments that must come *before* the numprocs + argument. The default is empty "".) + + :: + + -D MPI_EXEC_POST_NUMPROCS_FLAGS="arg1;arg2;...;argn" + + (Other command-line arguments that must come *after* the numprocs + argument. The default is empty "".) + + NOTE: Multiple arguments listed in ``MPI_EXEC_PRE_NUMPROCS_FLAGS`` and + ``MPI_EXEC_POST_NUMPROCS_FLAGS`` must be quoted and separated by ``';'`` as + these variables are interpreted as CMake arrays. + + +Configuring for OpenMP support +------------------------------ + +To enable OpenMP support, one must set:: + + -D _ENABLE_OpenMP=ON + +Note that if you enable OpenMP directly through a compiler option (e.g., +``-fopenmp``), you will NOT enable OpenMP inside source code. + +To skip adding flags for OpenMP for ```` = ``C``, ``CXX``, or +``Fortran``, use:: + + -D OpenMP__FLAGS_OVERRIDE=" " + +The single space " " will result in no flags getting added. This is needed +since one can't set the flags ``OpenMP__FLAGS`` to an empty string or +the ``find_package(OpenMP)`` command will fail. Setting the variable +``-DOpenMP__FLAGS_OVERRIDE= " "`` is the only way to enable OpenMP but +skip adding the OpenMP flags provided by ``find_package(OpenMP)``. + + +Building shared libraries +------------------------- + +.. _BUILD_SHARED_LIBS: + +To configure to build shared libraries, set:: + + -D BUILD_SHARED_LIBS=ON + +The above option will result in all shared libraries to be build on all +systems (i.e., ``.so`` on Unix/Linux systems, ``.dylib`` on Mac OS X, and +``.dll`` on Windows systems). + +NOTE: If the project has ``USE_XSDK_DEFAULTS=ON`` set, then this will set +``BUILD_SHARED_LIBS=TRUE`` by default. Otherwise, the default is +``BUILD_SHARED_LIBS=FALSE`` + +Many systems support a feature called ``RPATH`` when shared libraries are used +that embeds the default locations to look for shared libraries when an +executable is run. By default on most systems, CMake will automatically add +RPATH directories to shared libraries and executables inside of the build +directories. This allows running CMake-built executables from inside the +build directory without needing to set ``LD_LIBRARY_PATH`` on any other +environment variables. However, this can be disabled by setting:: + + -D CMAKE_SKIP_BUILD_RPATH=TRUE + +but it is hard to find a use case where that would be useful. + + +Building static libraries and executables +----------------------------------------- + +To build static libraries, turn off the shared library support:: + + -D BUILD_SHARED_LIBS=OFF + +Some machines, such as the Cray XT5, require static executables. To build + executables as static objects, a number of flags must be set:: + + -D BUILD_SHARED_LIBS=OFF \ + -D TPL_FIND_SHARED_LIBS=OFF \ + -D _LINK_SEARCH_START_STATIC=ON + +The first flag tells cmake to build static versions of the +libraries. The second flag tells cmake to locate static library versions of +any required TPLs. The third flag tells the auto-detection routines that +search for extra required libraries (such as the mpi library and the gfortran +library for gnu compilers) to locate static versions. + + +Changing include directories in downstream CMake projects to non-system +----------------------------------------------------------------------- + +By default, include directories from IMPORTED library targets from the + project's installed ``Config.cmake`` files will be +considered ``SYSTEM`` headers and therefore will be included on the compile +lines of downstream CMake projects with ``-isystem`` with most compilers. +However, when using CMake 3.23+, by configuring with:: + + -D _IMPORTED_NO_SYSTEM=ON + +then all of the IMPORTED library targets in the set of installed +``Config.cmake`` files will have the ``IMPORTED_NO_SYSTEM`` target +property set. This will cause downstream customer CMake projects to apply the +include directories from these IMPORTED library targets as non-SYSTEM include +directories. On most compilers, that means that the include directories will +be listed on the compile lines with ``-I`` instead of with ``-isystem`` (for +compilers that support the ``-isystem`` option). (Changing from ``-isystem +`` to ``-I `` moves ```` forward in the +compiler's include directory search order and could also result in the found +header files emitting compiler warnings that would other otherwise be silenced +when the headers were found in include directories pulled in with +``-isystem``.) + +**NOTE:** Setting ``_IMPORTED_NO_SYSTEM=ON`` when using a CMake +version less than 3.23 will result in a fatal configure error (so don't do +that). + +**A workaround for CMake versions less than 3.23** is for **downstream +customer CMake projects** to set the native CMake cache variable:: + + -D CMAKE_NO_SYSTEM_FROM_IMPORTED=TRUE + +This will result in **all** include directories from **all** IMPORTED library +targets used in the downstream customer CMake project to be listed on the +compile lines using ``-I`` instead of ``-isystem``, and not just for the +IMPORTED library targets from this project's installed +``Config.cmake`` files! + +**NOTE:** Setting ``CMAKE_NO_SYSTEM_FROM_IMPORTED=TRUE`` in the +CMake configure will **not** result in changing how include directories from +'s IMPORTED targets are handled in a downstream customer CMake +project! It will only change how include directories from upstream package's +IMPORTED targets are handled in the CMake project build itself. + + +Enabling the usage of resource files to reduce length of build lines +-------------------------------------------------------------------- + +When using the ``Unix Makefile`` generator and the ``Ninja`` generator, CMake +supports some very useful (undocumented) options for reducing the length of +the command-lines used to build object files, create libraries, and link +executables. Using these options can avoid troublesome "command-line too +long" errors, "Error 127" library creation errors, and other similar errors +related to excessively long command-lines to build various targets. + +When using the ``Unix Makefile`` generator, CMake responds to the three cache +variables ``CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES``, +``CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS`` and +``CMAKE_CXX_USE_RESPONSE_FILE_FOR_LIBRARIES`` described below. + +To aggregate the list of all of the include directories (e.g. ``'-I +'``) into a single ``*.rsp`` file for compiling object files, set:: + + -D CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES=ON + +To aggregate the list of all of the object files (e.g. ``'/.o'``) +into a single ``*.rsp`` file for creating libraries or linking executables, +set:: + + -D CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS=ON + +To aggregate the list of all of the libraries (e.g. ``'/.a'``) +into a single ``*.rsp`` file for creating shared libraries or linking +executables, set:: + + -D CMAKE_CXX_USE_RESPONSE_FILE_FOR_LIBRARIES=ON + +When using the ``Ninja`` generator, CMake only responds to the single option:: + + -D CMAKE_NINJA_FORCE_RESPONSE_FILE=ON + +which turns on the usage of ``*.rsp`` response files for include directories, +object files, and libraries (and therefore is equivalent to setting the above +three ``Unix Makefiles`` generator options to ``ON``). + +This feature works well on most standard systems but there are problems in +some situations and therefore these options can only be safely enabled on +case-by-case basis -- experimenting to ensure they are working correctly. +Some examples of some known problematic cases (as of CMake 3.11.2) are: + +* CMake will only use resource files with static libraries created with GNU + ``ar`` (e.g. on Linux) but not BSD ``ar`` (e.g. on MacOS). With BSD ``ar``, + CMake may break up long command-lines (i.e. lots of object files) with + multiple calls to ``ar`` but that may only work with the ``Unix Makefiles`` + generator, not the ``Ninja`` generator. + +* Some versions of ``gfortran`` do not accept ``*.rsp`` files. + +* Some versions of ``nvcc`` (e.g. with CUDA 8.044) do not accept ``*.rsp`` + files for compilation or linking. + +Because of problems like these, TriBITS cannot robustly automatically turn on +these options. Therefore, it is up to the user to try these options out to +see if they work with their specific version of CMake, compilers, and OS. + +NOTE: When using the ``Unix Makefiles`` generator, one can decide to set any +combination of these three options based on need and preference and what +actually works with a given OS, version of CMake, and provided compilers. For +example, on one system ``CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS=ON`` may work +but ``CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES=ON`` may not (which is the case +for ``gfortran`` mentioned above). Therefore, one should experiment carefully +and inspect the build lines using ``make VERBOSE=1 `` as described in +`Building with verbose output without reconfiguring`_ when deciding which of +these options to enable. + +NOTE: Newer versions of CMake may automatically determine when these options +need to be turned on so watch for that in looking at the build lines. + + +External Packages/Third-Party Library (TPL) support +--------------------------------------------------- + +A set of external packages/third-party libraries (TPL) can be enabled and +disabled and the locations of those can be specified at configure time (if +they are not found in the default path). + + +Enabling support for an optional Third-Party Library (TPL) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +To enable a given external packages/TPL, set:: + + -D TPL_ENABLE_=ON + +where ```` = ``BLAS``, ``LAPACK`` ``Boost``, ``Netcdf``, etc. +(Requires TPLs for enabled package will automatically be enabled.) + +The full list of TPLs that is defined and can be enabled is shown by doing a +configure with CMake and then grepping the configure output for ``Final set of +.* TPLs``. The set of TPL names listed in ``'Final set of enabled external +packages/TPLs'`` and ``'Final set of non-enabled external packages/TPLs'`` +gives the full list of TPLs that can be enabled (or disabled). + +Optional package-specific support for a TPL can be turned off by setting:: + + -D _ENABLE_=OFF + +This gives the user full control over what TPLs are supported by which package +independent of whether the TPL is enabled or not. + +Support for an optional TPL can also be turned on implicitly by setting:: + + -D _ENABLE_=ON + +where ```` is a TriBITS package that has an optional +dependency on ````. That will result in setting +``TPL_ENABLE_=ON`` internally (but not set in the cache) if +``TPL_ENABLE_=OFF`` is not already set. + + +Specifying the location of the parts of an enabled external package/TPL ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Once an external package/TPL is enabled, the parts of that TPL must be found. +For many external packages/TPLs, this will be done automatically by searching +the environment paths. + +Some external packages/TPLs are specified with a call to +``find_package()`` (see CMake documentation for +``find_package()``). Many other external packages/TPLs use a legacy TriBITS +system that locates the parts using the CMake commands ``find_file()`` and +``find_library()`` as described below. + +Every defined external package/TPL uses a specification provided in a +``FindTPL.cmake`` module file. This file describes how the package +is found in a way that provides modern CMake IMPORTED targets (including the +``::all_libs`` target) that is used by the downstream packages. + +Some TPLs require only libraries (e.g. Fortran libraries like BLAS or LAPACK), +some TPL require only include directories, and some TPLs require both. + +For ``FindTPL.cmake`` files using the legacy TriBITS TPL system, a +TPL is fully specified through the following cache variables: + +* ``TPL__INCLUDE_DIRS:PATH``: List of paths to header files for the + TPL (if the TPL supplies header files). + +* ``TPL__LIBRARIES:PATH``: List of (absolute) paths to libraries, + ordered as they will be on the link line (of the TPL supplies libraries). + +These variables are the only variables are used to create IMPORTED CMake +targets for the TPL. One can set these two variables as CMake cache +variables, for ``SomeTPL`` for example, with:: + + -D TPL_SomeTPL_INCLUDE_DIRS="${LIB_BASE}/include/a;${LIB_BASE}/include/b" \ + -D TPL_SomeTPL_LIBRARIES="${LIB_BASE}/lib/liblib1.so;${LIB_BASE}/lib/liblib2.so" \ + +Using this approach, one can be guaranteed that these libraries and these +include directories and will used in the compile and link lines for the +packages that depend on this TPL ``SomeTPL``. + +**NOTE:** When specifying ``TPL__INCLUDE_DIRS`` and/or +``TPL__LIBRARIES``, the build system will use these without question. +It will **not** check for the existence of these directories or files so make +sure that these files and directories exist before these are used in the +compiles and links. (This can actually be a feature in rare cases the +libraries and header files don't actually get created until after the +configure step is complete but before the build step.) + +**NOTE:** It is generally *not recommended* to specify the TPLs libraries as +just a set of link options as, for example:: + + TPL_SomeTPL_LIBRARIES="-L/some/dir;-llib1;-llib2;..." + +But this is supported as long as this link line contains only link library +directories and library names. (Link options that are not order-sensitive are +also supported like ``-mkl``.) + +When the variables ``TPL__INCLUDE_DIRS`` and +``TPL__LIBRARIES`` are not specified, then most +``FindTPL.cmake`` modules use a default find operation. Some will +call ``find_package()`` internally by default and some may +implement the default find in some other way. To know for sure, see the +documentation for the specific external package/TPL (e.g. looking in the +``FindTPL.cmake`` file to be sure). NOTE: if a given +``FindTPL.cmake`` will use ``find_package()`` by +default, this can be disabled by configuring with:: + + -D_ALLOW_PACKAGE_PREFIND=OFF + +(Not all ``FindTPL.cmake`` files support this option.) + +Many ``FindTPL.cmake`` files, use the legacy TriBITS TPL system for +finding include directories and/or libraries based on the function +`tribits_tpl_find_include_dirs_and_libraries()`_. These simple standard +``FindTPL.cmake`` modules specify a set of header files and/or +libraries that must be found. The directories where these header files and +library files are looked for are specified using the CMake cache variables: + +* ``_INCLUDE_DIRS:PATH``: List of paths to search for header files + using ``find_file()`` for each header file, in order. + +* ``_LIBRARY_NAMES:STRING``: List of unadorned library names, in the + order of the link line. The platform-specific prefixes (e.g.. 'lib') and + postfixes (e.g. '.a', '.lib', or '.dll') will be added automatically by + CMake. For example, the library ``libblas.so``, ``libblas.a``, ``blas.lib`` + or ``blas.dll`` will all be found on the proper platform using the name + ``blas``. + +* ``_LIBRARY_DIRS:PATH``: The list of directories where the library + files will be searched for using ``find_library()``, for each library, in + order. + +Most of these ``FindTPL.cmake`` modules will define a default set of +libraries to look for and therefore ``_LIBRARY_NAMES`` can typically +be left off. + +Therefore, to find the same set of libraries for ``SimpleTPL`` shown +above, one would specify:: + + -D SomeTPL_LIBRARY_DIRS="${LIB_BASE}/lib" + +and if the set of libraries to be found is different than the default, one can +override that using:: + + -D SomeTPL_LIBRARY_NAMES="lib1;lib2" + +Therefore, this is in fact the preferred way to specify the libraries for +these legacy TriBITS TPLs. + +In order to allow a TPL that normally requires one or more libraries to ignore +the libraries, one can set ``_LIBRARY_NAMES`` to empty, for example:: + + -D _LIBRARY_NAMES="" + +If all the parts of a TPL are not found on an initial configure, the configure +will error out with a helpful error message. In that case, one can change the +variables ``_INCLUDE_DIRS``, ``_LIBRARY_NAMES``, and/or +``_LIBRARY_DIRS`` in order to help fund the parts of the TPL. One +can do this over and over until the TPL is found. By reconfiguring, one avoids +a complete configure from scratch which saves time. Or, one can avoid the +find operations by directly setting ``TPL__INCLUDE_DIRS`` and +``TPL__LIBRARIES`` as described above. + +**TPL Example 1: Standard BLAS Library** + +Suppose one wants to find the standard BLAS library ``blas`` in the +directory:: + + /usr/lib/ + libblas.so + libblas.a + ... + +The ``FindTPLBLAS.cmake`` module should be set up to automatically find the +BLAS TPL by simply enabling BLAS with:: + + -D TPL_ENABLE_BLAS=ON + +This will result in setting the CMake cache variable ``TPL_BLAS_LIBRARIES`` as +shown in the CMake output:: + + -- TPL_BLAS_LIBRARIES='/user/lib/libblas.so' + +(NOTE: The CMake ``find_library()`` command that is used internally will +always select the shared library by default if both shared and static +libraries are specified, unless told otherwise. See `Building static +libraries and executables`_ for more details about the handling of shared and +static libraries.) + +However, suppose one wants to find the ``blas`` library in a non-default +location, such as in:: + + /projects/something/tpls/lib/libblas.so + +In this case, one could simply configure with:: + + -D TPL_ENABLE_BLAS=ON \ + -D BLAS_LIBRARY_DIRS=/projects/something/tpls/lib \ + +That will result in finding the library shown in the CMake output:: + + -- TPL_BLAS_LIBRARIES='/projects/something/tpls/libblas.so' + +And if one wants to make sure that this BLAS library is used, then one can +just directly set:: + + -D TPL_BLAS_LIBRARIES=/projects/something/tpls/libblas.so + +**TPL Example 2: Intel Math Kernel Library (MKL) for BLAS** + +There are many cases where the list of libraries specified in the +``FindTPL.cmake`` module is not correct for the TPL that one wants to +use or is present on the system. In this case, one will need to set the CMake +cache variable ``_LIBRARY_NAMES`` to tell the +`tribits_tpl_find_include_dirs_and_libraries()`_ function what libraries to +search for, and in what order. + +For example, the Intel Math Kernel Library (MKL) implementation for the BLAS +is usually given in several libraries. The exact set of libraries needed +depends on the version of MKL, whether 32bit or 64bit libraries are needed, +etc. Figuring out the correct set and ordering of these libraries for a given +platform may be non-trivial. But once the set and the order of the libraries +is known, then one can provide the correct list at configure time. + +For example, suppose one wants to use the threaded MKL libraries listed in the +directories:: + + /usr/local/intel/Compiler/11.1/064/mkl/lib/em64t/ + /usr/local/intel/Compiler/11.1/064/lib/intel64/ + +and the list of libraries being searched for is ``mkl_intel_lp64``, +``mkl_intel_thread``, ``mkl_core`` and ``iomp5``. + +In this case, one could specify this with the following do-configure script:: + + #!/bin/bash + + INTEL_DIR=/usr/local/intel/Compiler/11.1/064 + + cmake \ + -D TPL_ENABLE_BLAS=ON \ + -D BLAS_LIBRARY_DIRS="${INTEL_DIR}/em64t;${INTEL_DIR}/intel64" \ + -D BLAS_LIBRARY_NAMES="mkl_intel_lp64;mkl_intel_thread;mkl_core;iomp5" \ + ... + ${PROJECT_SOURCE_DIR} + +This would call ``find_library()`` on each of the listed library names in +these directories and would find them and list them in:: + + -- TPL_BLAS_LIBRARIES='/usr/local/intel/Compiler/11.1/064/em64t/libmkl_intel_lp64.so;...' + +(where ``...`` are the rest of the found libraries.) + +NOTE: When shared libraries are used, one typically only needs to list the +direct libraries, not the indirect libraries, as the shared libraries are +linked to each other. + +In this example, one could also play it super safe and manually list out the +libraries in the right order by configuring with:: + + -D TPL_BLAS_LIBRARIES="${INTEL_DIR}/em64t/libmkl_intel_lp64.so;..." + +(where ``...`` are the rest of the libraries found in order). + + +Adjusting upstream dependencies for a Third-Party Library (TPL) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Some TPLs have dependencies on one or more upstream TPLs. These dependencies +must be specified correctly for the compile and links to work correctly. The + Project already defines these dependencies for the average situation +for all of these TPLs. However, there may be situations where the +dependencies may need to be tweaked to match how these TPLs were actually +installed on some systems. To redefine what dependencies a TPL can have (if +the upstream TPLs are enabled), set:: + + -D _LIB_DEFINED_DEPENDENCIES=";;..." + +A dependency on an upstream TPL ```` will be set if the an upstream TPL +```` is actually enabled. + +If any of the specified dependent TPLs ```` are listed after +```` in the ``TPLsList.cmake`` file (or are not listed at all), then +a configure-time error will occur. + +To take complete control over what dependencies an TPL has, set:: + + -D _LIB_ENABLED_DEPENDENCIES=";;..." + +If the upstream TPLs listed here are not defined upstream and enabled TPLs, +then a configure-time error will occur. + + +Disabling support for a Third-Party Library (TPL) ++++++++++++++++++++++++++++++++++++++++++++++++++ + +Disabling a TPL explicitly can be done using:: + + -D TPL_ENABLE_=OFF + +This will result in the disabling of any direct or indirect downstream +packages that have a required dependency on ```` as described in +`Disable a package and all its dependencies`_. + +NOTE: If a disabled TPL is a required dependency of some explicitly enabled +downstream package, then the configure will error out if +`_DISABLE_ENABLED_FORWARD_DEP_PACKAGES`_ ``= OFF``. Otherwise, a +NOTE will be printed and the downstream package will be disabled and +configuration will continue. + + +Disabling tentatively enabled TPLs +++++++++++++++++++++++++++++++++++ + +To disable a tentatively enabled TPL, set:: + + -D TPL_ENABLE_=OFF + +where ```` = ``BinUtils``, ``Boost``, etc. + +NOTE: Some TPLs in are always tentatively enabled (e.g. BinUtils +for C++ stacktracing) and if all of the components for the TPL are found +(e.g. headers and libraries) then support for the TPL will be enabled, +otherwise it will be disabled. This is to allow as much functionality as +possible to get automatically enabled without the user having to learn about +the TPL, explicitly enable the TPL, and then see if it is supported or not +on the given system. However, if the TPL is not supported on a given +platform, then it may be better to explicitly disable the TPL (as shown +above) so as to avoid the output from the CMake configure process that shows +the tentatively enabled TPL being processes and then failing to be enabled. +Also, it is possible that the enable process for the TPL may pass, but the +TPL may not work correctly on the given platform. In this case, one would +also want to explicitly disable the TPL as shown above. + + +Require all TPL libraries be found +++++++++++++++++++++++++++++++++++ + +By default, some TPLs don't require that all of the libraries listed in +``_LIBRARY_NAMES`` be found. To change this behavior so that all +libraries for all enabled TPLs be found, one can set:: + + -D _MUST_FIND_ALL_TPL_LIBS=TRUE + +This makes the configure process catch more mistakes with the env. + + +Disable warnings from TPL header files +++++++++++++++++++++++++++++++++++++++ + +To disable warnings coming from included TPL header files for C and C++ code, +set:: + + -D_TPL_SYSTEM_INCLUDE_DIRS=TRUE + +On some systems and compilers (e.g. GNU), that will result is include +directories for all TPLs to be passed in to the compiler using ``-isystem`` +instead of ``-I``. + +WARNING: On some systems this will result in build failures involving gfortran +and module files. Therefore, don't enable this if Fortran code in your +project is pulling in module files from TPLs. + + +Building against pre-installed packages +--------------------------------------- + +The project can build against any pre-installed packages defined in +the project and ignore the internally defined packages. To trigger the enable +of a pre-installed internal package treated as an external package, configure +with:: + + -D TPL_ENABLE_=ON + +That will cause the CMake project to pull in the pre-installed +package ```` as an external package using +``find_package()`` instead of configuring and building the +internally defined ```` package. + +Configuring and building against a pre-installed package treated as an +external packages has several consequences: + +* Any internal packages that are upstream from ```` from an + enabled set of dependencies will also be treated as external packages (and + therefore must be pre-installed as well). + +* The TriBITS package ``Dependencies.cmake`` files for the + ```` package and all of its upstream packages must still + exist and will still be read in by the CMake project and the same + enable/disable logic will be performed as if the packages were being treated + internal. (However, the base ``CMakeLists.txt`` and all of other files for + these internally defined packages being treated as external packages can be + missing and will be ignored.) + +* The same set of enabled and disabled upstream dependencies must be specified + to the CMake project that was used to pre-build and pre-install + these internally defined packages being treated as external packages. + (Otherwise, a configure error will result from the mismatch.) + +* The definition of any TriBITS external packages/TPLs that are enabled + upstream dependencies from any of these external packages should be defined + automatically and will **not** be found again. (But there can be exceptions + for minimally TriBITS-compliant external packages; see the section + "TriBITS-Compliant External Packages" in the "TriBITS Users Guide".) + +The logic for treating internally defined packages as external packages will +be printed in the CMake configure output in the section ``Adjust the set of +internal and external packages`` with output like:: + + Adjust the set of internal and external packages ... + + -- Treating internal package as EXTERNAL because TPL_ENABLE_=ON + -- Treating internal package as EXTERNAL because downstream package being treated as EXTERNAL + -- NOTE: is indirectly downstream from a TriBITS-compliant external package + -- NOTE: is indirectly downstream from a TriBITS-compliant external package + +All of these internally defined being treated as external (and all of their +upstream dependencies) are processed in a loop over these just these +TriBITS-compliant external packages and ``find_package()`` is only called on +the terminal TriBITS-compliant external packages. This is shown in the CMake +output in the section ``Getting information for all enabled TriBITS-compliant +or upstream external packages/TPLs`` and looks like:: + + Getting information for all enabled TriBITS-compliant or upstream external packages/TPLs in reverse order ... + + Processing enabled external package/TPL: (...) + -- Calling find_package( for TriBITS-compliant external package + Processing enabled external package/TPL: (...) + -- The external package/TPL was defined by a downstream TriBITS-compliant external package already processed + Processing enabled external package/TPL: (...) + -- The external package/TPL was defined by a downstream TriBITS-compliant external package already processed + Processing enabled external package/TPL: (...) + -- The external package/TPL was defined by a downstream TriBITS-compliant external package already processed + +In the above example ````, ```` and ```` are all direct or +indirect dependencies of ```` and therefore calling just +``find_package()`` fully defines those TriBITS-compliant external +packages as well. + +All remaining TPLs that are not defined in that first reverse loop are defined +in a second forward loop over regular TPLs:: + + Getting information for all remaining enabled external packages/TPLs ... + +NOTE: The case is also supported where a TriBITS-compliant external package +like ```` does not define all of it upstream dependencies (i.e. does not +define the ``::all_libs`` target) and these external packages/TPLs will +be found again. This allows the possibility of finding different/inconsistent +upstream dependencies but this is allowed to accommodate some packages with +non-TriBITS CMake build systems that don't create fully TriBITS-compliant +external packages. + + +xSDK Configuration Options +-------------------------- + +The configure of will adhere to the `xSDK Community Package +Policies`_ simply by setting the CMake cache variable:: + + -D USE_XSDK_DEFAULTS=TRUE + +Setting this will have the following impact: + +* ``BUILD_SHARED_LIBS`` will be set to ``TRUE`` by default instead of + ``FALSE``, which is the default for raw CMake projects (see `Building shared + libraries`_). + +* ``CMAKE_BUILD_TYPE`` will be set to ``DEBUG`` by default instead of + ``RELEASE`` which is the standard TriBITS default (see `CMAKE_BUILD_TYPE`_). + +* The compilers in MPI mode ``TPL_ENABLE_MPI=ON`` or serial mode + ``TPL_ENABLE_MPI=OFF`` will be read from the environment variables ``CC``, + ``CXX`` and ``FC`` if they are set but the cmake cache variables + ``CMAKE_C_COMPILER``, ``CMAKE_C_COMPILER`` and ``CMAKE_C_COMPILER`` are not + set. Otherwise, the TriBITS default behavior is to ignore these environment + variables in MPI mode. + +* The Fortran flags will be read from environment variable ``FCFLAGS`` if the + environment variable ``FFLAGS`` and the CMake cache variable + ``CMAKE_Fortran_FLAGS`` are empty. Otherwise, raw CMake ignores ``FCFLAGS`` + (see `Adding arbitrary compiler flags but keeping default build-type + flags`_). + +The rest of the required xSDK configure standard is automatically satisfied by +every TriBITS CMake project, including the project. + + +Generating verbose output +------------------------- + +There are several different ways to generate verbose output to debug problems +when they occur: + +.. __TRACE_FILE_PROCESSING: + +a) **Trace file processing during configure:** + + :: + + -D _TRACE_FILE_PROCESSING=ON + + This will cause TriBITS to print out a trace for all of the project's, + repository's, and package's files get processed on lines using the prefix + ``File Trace:``. This shows what files get processed and in what order they + get processed. To get a clean listing of all the files processed by TriBITS + just grep out the lines starting with ``-- File Trace:``. This can be + helpful in debugging configure problems without generating too much extra + output. + + Note that `_TRACE_FILE_PROCESSING`_ is set to ``ON`` automatically + when `_VERBOSE_CONFIGURE`_ = ``ON``. + +.. __VERBOSE_CONFIGURE: + +b) **Getting verbose output from TriBITS configure:** + + To do a complete debug dump for the TriBITS configure process, use:: + + -D _VERBOSE_CONFIGURE=ON + + However, this produces a *lot* of output so don't enable this unless you are + very desperate. But this level of details can be very useful when debugging + configuration problems. + + To just view the package and TPL dependencies, it is recommended to use + ``-D`` `_DUMP_PACKAGE_DEPENDENCIES`_ ``= ON``. + + To just print the link libraries for each library and executable created, + use:: + + -D _DUMP_LINK_LIBS=ON + + Of course ``_DUMP_PACKAGE_DEPENDENCIES`` and + ``_DUMP_LINK_LIBS`` can be used together. Also, note that + ``_DUMP_PACKAGE_DEPENDENCIES`` and ``_DUMP_LINK_LIBS`` + both default t ``ON`` when ``_VERBOSE_CONFIGURE=ON`` on the first + configure. + + +c) **Getting verbose output from the makefile:** + + :: + + -D CMAKE_VERBOSE_MAKEFILE=TRUE + + NOTE: It is generally better to just pass in ``VERBOSE=`` when directly + calling ``make`` after configuration is finished. See `Building with + verbose output without reconfiguring`_. + +d) **Getting very verbose output from configure:** + + :: + + -D _VERBOSE_CONFIGURE=ON --debug-output --trace + + NOTE: This will print a complete stack trace to show exactly where you are. + + +Enabling/disabling deprecated warnings +-------------------------------------- + +To turn off all deprecated warnings, set:: + + -D _SHOW_DEPRECATED_WARNINGS=OFF + +This will disable, by default, all deprecated warnings in packages in +. By default, deprecated warnings are enabled. + +To enable/disable deprecated warnings for a single package, set:: + + -D _SHOW_DEPRECATED_WARNINGS=OFF + +This will override the global behavior set by +``_SHOW_DEPRECATED_WARNINGS`` for individual package +````. + + +Adjusting CMake DEPRECATION warnings +------------------------------------ + +By default, deprecated TriBITS features being used in the project's CMake +files will result in CMake deprecation warning messages (issued by calling +``message(DEPRECATION ...)`` internally). The handling of these deprecation +warnings can be changed by setting the CMake cache variable +``TRIBITS_HANDLE_TRIBITS_DEPRECATED_CODE``. For example, to remove all +deprecation warnings, set:: + + -D TRIBITS_HANDLE_TRIBITS_DEPRECATED_CODE=IGNORE + +Other valid values include: + +* ``DEPRECATION``: Issue a CMake ``DEPRECATION`` message and continue (default). +* ``AUTHOR_WARNING``: Issue a CMake ``AUTHOR_WARNING`` message and continue. +* ``SEND_ERROR``: Issue a CMake ``SEND_ERROR`` message and continue. +* ``FATAL_ERROR``: Issue a CMake ``FATAL_ERROR`` message and exit. + + +Disabling deprecated code +------------------------- + +To actually disable and remove deprecated code from being included in +compilation, set:: + + -D _HIDE_DEPRECATED_CODE=ON + +and a subset of deprecated code will actually be removed from the build. This +is to allow testing of downstream client code that might otherwise ignore +deprecated warnings. This allows one to certify that a downstream client code +is free of calling deprecated code. + +To hide deprecated code for a single package set:: + + -D _HIDE_DEPRECATED_CODE=ON + +This will override the global behavior set by +``_HIDE_DEPRECATED_CODE`` for individual package +````. + + +Outputting package dependency information +----------------------------------------- + +.. __DEPS_DEFAULT_OUTPUT_DIR: + +To generate the various XML and HTML package dependency files, one can set the +output directory when configuring using:: + + -D _DEPS_DEFAULT_OUTPUT_DIR:FILEPATH= + +This will generate, by default, the output files +``PackageDependencies.xml``, +``PackageDependenciesTable.html``, and +``CDashSubprojectDependencies.xml``. If ``_DEPS_DEFAULT_OUTPUT_DIR`` +is not set, then the individual output files can be specified as described below. + +.. __DEPS_XML_OUTPUT_FILE: + +The filepath for PackageDependencies.xml can be overridden (or set +independently) using:: + + -D _DEPS_XML_OUTPUT_FILE:FILEPATH= + +.. __DEPS_HTML_OUTPUT_FILE: + +The filepath for ``PackageDependenciesTable.html`` can be overridden +(or set independently) using:: + + -D _DEPS_HTML_OUTPUT_FILE:FILEPATH= + +.. __CDASH_DEPS_XML_OUTPUT_FILE: + +The filepath for CDashSubprojectDependencies.xml can be overridden (or set +independently) using:: + + -D _CDASH_DEPS_XML_OUTPUT_FILE:FILEPATH= + +NOTES: + +* One must start with a clean CMake cache for all of these defaults to work. + +* The files ``PackageDependenciesTable.html`` and + ``CDashSubprojectDependencies.xml`` will only get generated if support for + Python is enabled. + + +Test-related configuration settings +----------------------------------- + +Many options can be set at configure time to determine what tests are enabled +and how they are run. The following subsections described these various +settings. + + +Enabling different test categories +++++++++++++++++++++++++++++++++++ + +To turn on a set a given set of tests by test category, set:: + + -D _TEST_CATEGORIES=";;..." + +Valid categories include ``BASIC``, ``CONTINUOUS``, ``NIGHTLY``, ``HEAVY`` and +``PERFORMANCE``. ``BASIC`` tests get built and run for pre-push testing, CI +testing, and nightly testing. ``CONTINUOUS`` tests are for post-push testing +and nightly testing. ``NIGHTLY`` tests are for nightly testing only. +``HEAVY`` tests are for more expensive tests that require larger number of MPI +processes and longer run times. These test categories are nested +(e.g. ``HEAVY`` contains all ``NIGHTLY``, ``NIGHTLY`` contains all +``CONTINUOUS`` and ``CONTINUOUS`` contains all ``BASIC`` tests). However, +``PERFORMANCE`` tests are special category used only for performance testing +and don't nest with the other categories. + + +Disabling specific tests +++++++++++++++++++++++++ + +Any TriBITS-added ctest test (i.e. listed in ``ctest -N``) can be disabled at +configure time by setting:: + + -D _DISABLE=ON + +where ```` must exactly match the test listed out by ``ctest +-N``. This will result in the printing of a line for the excluded test when +`Trace test addition or exclusion`_ is enabled and the test will not be added +with ``add_test()`` and therefore CTest (and CDash) will never see the +disabled test. + +Another approach to disable a test is the set the ctest property ``DISABLED`` +and print and a message at configure time by setting:: + + -D _SET_DISABLED_AND_MSG="" + +In this case, the test will still be added with ``add_test()`` and seen by +CTest, but CTest will not run the test locally but will mark it as "Not Run" +(and post to CDash as "Not Run" tests with test details "Not Run (Disabled)" +in processes where tests get posted to CDash). Also, ```` +will get printed to STDOUT when CMake is run to configure the project and +``-D_TRACE_ADD_TEST=ON`` is set. + +Also, note that if a test is currently disabled using the ``DISABLED`` option +in the CMakeLists.txt file, then that ``DISABLE`` property can be removed by +configuring with:: + + -D _SET_DISABLED_AND_MSG=FALSE + +(or any value that CMake evaluates to FALSE like "FALSE", "false", "NO", "no", +"", etc.). + +Also note that other specific defined tests can also be excluded using the +``ctest -E`` argument. + + +Disabling specific test executable builds ++++++++++++++++++++++++++++++++++++++++++ + +Any TriBITS-added executable (i.e. listed in ``make help``) can be disabled +from being built by setting:: + + -D _EXE_DISABLE=ON + +where ```` is the name of the target in the build system. + +Note that one should also disable any ctest tests that might use this +executable as well with ``-D_DISABLE=ON`` (see above). This +will result in the printing of a line for the executable target being disabled +at configure time to CMake STDOUT. + + +Disabling just the ctest tests but not the test executables ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +To allow the building of the tests and examples in a package (enabled either +through setting `_ENABLE_TESTS`_ ``= ON`` or +`_ENABLE_TESTS`_ ``= ON``) but not actually define the ctest +tests that will get run, configure with:: + + -D _SKIP_CTEST_ADD_TEST=TRUE \ + +(This has the effect of skipping calling the ``add_test()`` command in the +CMake code for the package ````.) + +To avoid defining ctest tests for all of the enabled packages, configure +with:: + + -D _SKIP_CTEST_ADD_TEST=TRUE \ + +(The default for ``_SKIP_CTEST_ADD_TEST`` for each TriBITS +package ```` is set to the project-wide option +``_SKIP_CTEST_ADD_TEST``.) + +One can also use these options to "white-list" and "black-list" the set of +package tests that one will run. For example, to enable the building of all +test and example targets but only actually defining ctest tests for two +specific packages (i.e. "white-listing"), one would configure with:: + + -D _ENABLE_ALL_PACKAGES=ON \ + -D _ENABLE_TESTS=ON \ + -D _SKIP_CTEST_ADD_TEST=TRUE \ + -D _SKIP_CTEST_ADD_TEST=FALSE \ + -D _SKIP_CTEST_ADD_TEST=FALSE \ + +Alternatively, to enable the building of all test and example targets and +allowing the ctest tests to be defined for all packages except for a couple of +specific packages (i.e. "black-listing"), one would configure with:: + + -D _ENABLE_ALL_PACKAGES=ON \ + -D _ENABLE_TESTS=ON \ + -D _SKIP_CTEST_ADD_TEST=TRUE \ + -D _SKIP_CTEST_ADD_TEST=TRUE \ + +Using different values for ``_SKIP_CTEST_ADD_TEST`` and +``_SKIP_CTEST_ADD_TEST`` in this way allows for building all +of the test and example targets for the enabled packages but not defining +ctest tests for any set of packages desired. This allows setting up testing +scenarios where one wants to test the building of all test-related targets but +not actually run the tests with ctest for a subset of all of the enabled +packages. (This can be useful in cases where the tests are very expensive and +one can't afford to run all of them given the testing budget, or when running +tests on a given platform is very flaky, or when some packages have fragile or +poor quality tests that don't port to new platforms very well.) + +NOTE: These options avoid having to pass specific sets of labels when running +``ctest`` itself (such as when defining ``ctest -S