# FeatureSummary

Functions for generating a summary of enabled/disabled features.

These functions can be used to generate a summary of enabled and disabled packages and/or features for a build tree such as:

    -- The following features have been enabled:

     * Example, usage example

    -- The following OPTIONAL packages have been found:

     * LibXml2 (required version >= 2.4), XML library, <http://xmlsoft.org>
       Enables HTML-import in MyWordProcessor
       Enables odt-export in MyWordProcessor
     * PNG, image library, <http://www.libpng.org/pub/png/>
       Enables saving screenshots

    -- The following OPTIONAL packages have not been found:

     * Lua, the Lua scripting language, <https://www.lua.org>
       Enables macros in MyWordProcessor
     * OpenGL, Open Graphics Library

## Global Properties

FeatureSummary_PKG_TYPES

  Added in version 3.8.

  This global property defines a semicolon-separated list of package types used by the `FeatureSummary` module.

  The order in this list is important, the first package type in the list has the lowest importance, while the last has the highest importance. The type of a package can only be changed to a type with higher importance.

  The default package types are `RUNTIME`, `OPTIONAL`, `RECOMMENDED` and `REQUIRED`, with their importance ranked as `RUNTIME < OPTIONAL < RECOMMENDED < REQUIRED`.

FeatureSummary_REQUIRED_PKG_TYPES

  Added in version 3.8.

  This global property defines a semicolon-separated list of package types that are considered required.

  If one or more packages in these categories are not found, CMake will abort when the `feature_summary()` command is called with the `FATAL_ON_MISSING_REQUIRED_PACKAGES` option enabled.

  The default value for this global property is `REQUIRED`.

FeatureSummary_DEFAULT_PKG_TYPE

  Added in version 3.8.

  This global property defines the default package type.

  When the `feature_summary()` command is called, and the user has not explicitly set a type of some package, its type will be set to this value.

  This value must be one of the types defined in the `FeatureSummary_PKG_TYPES` global property.

  The default value for this global property is `OPTIONAL`.

FeatureSummary_<TYPE>_DESCRIPTION

  Added in version 3.9.

  This global property can be defined for each package `<TYPE>` to a string that will be used in the output titles of the `feature_summary()` command. For example:

      The following <FeatureSummary_<TYPE>_DESCRIPTION> have been found:

  If not set, default string `<TYPE> packages` is used.

## Functions

feature_summary

      feature_summary([FILENAME <file>]
                      [APPEND]
                      [VAR <variable_name>]
                      [INCLUDE_QUIET_PACKAGES]
                      [FATAL_ON_MISSING_REQUIRED_PACKAGES]
                      [DESCRIPTION <description> | DEFAULT_DESCRIPTION]
                      [QUIET_ON_EMPTY]
                      WHAT (ALL
                           | PACKAGES_FOUND | PACKAGES_NOT_FOUND
                           | <TYPE>_PACKAGES_FOUND | <TYPE>_PACKAGES_NOT_FOUND
                           | ENABLED_FEATURES | DISABLED_FEATURES)
                     )

  This function can be used to print information about enabled or disabled packages and features of a project. By default, only the names of the features/packages will be printed and their required version when one was specified. Use `set_package_properties()` to add more useful information, like e.g. a homepage URL for the respective package or their purpose in the project.

  The options are:

  `WHAT`

    This is the only mandatory option. It specifies what information will be printed:

    `ALL`

      Print everything.

    `ENABLED_FEATURES`

      The list of all features which are enabled.

    `DISABLED_FEATURES`

      The list of all features which are disabled.

    `PACKAGES_FOUND`

      The list of all packages which have been found.

    `PACKAGES_NOT_FOUND`

      The list of all packages which have not been found.

    For each package type `<TYPE>` defined by the `FeatureSummary_PKG_TYPES` global property, the following information can also be used:

    `<TYPE>_PACKAGES_FOUND`

      The list of only packages of type `<TYPE>` which have been found.

    `<TYPE>_PACKAGES_NOT_FOUND`

      The list of only packages of type `<TYPE>` which have not been found.

    Changed in version 3.1: The `WHAT` option is now a multi-value keyword, so that these values can be combined, with the exception of the `ALL` value, in order to customize the output. For example:

        feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES)

  `FILENAME <file>`

    If this option is given, the information is printed into this file instead of the terminal. Relative `<file>` path is interpreted as being relative to the current source directory (i.e. `CMAKE_CURRENT_SOURCE_DIR`).

  `APPEND`

    If this option is given, the output is appended to the `<file>` provided by the `FILENAME` option, otherwise the file is overwritten if it already exists.

  `VAR <variable_name>`

    If this option is given, the information is stored into the specified variable `<variable_name>` instead of the terminal.

  `DESCRIPTION <description>`

    A description or headline which will be printed above the actual content. Without this option, if only one package type was requested, no title is printed, unless a custom string is explicitly set using this option or `DEFAULT_DESCRIPTION` option is used that outputs a default title for the requested type.

  `DEFAULT_DESCRIPTION`

    Added in version 3.9.

    The default description or headline to be printed above the content as opposed to the customizable `DESCRIPTION <description>`.

  `INCLUDE_QUIET_PACKAGES`

    If this option is given, packages which have been searched with `find_package(... QUIET)` will also be listed. By default they are skipped.

  `FATAL_ON_MISSING_REQUIRED_PACKAGES`

    If this option is given, CMake will abort with fatal error if a package which is marked as one of the package types listed in the `FeatureSummary_REQUIRED_PKG_TYPES` global property has not been found.

  The `FeatureSummary_DEFAULT_PKG_TYPE` global property can be modified to change the default package type assigned when not explicitly assigned by the user.

  `QUIET_ON_EMPTY`

    Added in version 3.8.

    If this option is given, when only one package type was requested, and no packages belonging to that category were found, then no output (including the `DESCRIPTION`) is printed nor added to the `FILENAME`, or the `VAR` variable.

  Example 1, append everything to a file:

      include(FeatureSummary)
      feature_summary(WHAT ALL
                      FILENAME ${CMAKE_BINARY_DIR}/all.log APPEND)

  Example 2, print the enabled features into the variable `enabledFeaturesText`, including the `QUIET` packages:

      include(FeatureSummary)
      feature_summary(WHAT ENABLED_FEATURES
                     INCLUDE_QUIET_PACKAGES
                     DESCRIPTION "Enabled Features:"
                     VAR enabledFeaturesText)
      message(STATUS "${enabledFeaturesText}")

  Example 3, add custom package type and print only the categories that are not empty:

      include(FeatureSummary)
      set_property(GLOBAL APPEND PROPERTY FeatureSummary_PKG_TYPES BUILD)
      find_package(FOO)
      set_package_properties(FOO PROPERTIES TYPE BUILD)
      feature_summary(WHAT BUILD_PACKAGES_FOUND
                      DESCRIPTION "Build tools found:"
                      QUIET_ON_EMPTY)
      feature_summary(WHAT BUILD_PACKAGES_NOT_FOUND
                      DESCRIPTION "Build tools not found:"
                      QUIET_ON_EMPTY)

set_package_properties

      set_package_properties(<name> PROPERTIES
                             [URL <url>]
                             [DESCRIPTION <description>]
                             [TYPE (RUNTIME|OPTIONAL|RECOMMENDED|REQUIRED)]
                             [PURPOSE <purpose>]
                            )

  Use this function to configure and provide information about the package named `<name>`, which can then be displayed using the `feature_summary()` command. This can be performed either directly within the corresponding Find module or in the project that uses the module after invoking the `find_package()` call. The features for which information can be set are determined automatically after the `find_package()` command.

  `URL <url>`

    This should be the homepage of the package, or something similar. Ideally this is set already directly in the Find module.

  `DESCRIPTION <description>`

    A short description what that package is, at most one sentence. Ideally this is set already directly in the Find module.

  `TYPE <type>`

    What type of dependency has the using project on that package. Default is `OPTIONAL`. In this case it is a package which can be used by the project when available at buildtime, but it also work without. `RECOMMENDED` is similar to `OPTIONAL`, i.e. the project will build if the package is not present, but the functionality of the resulting binaries will be severely limited. If a `REQUIRED` package is not available at buildtime, the project may not even build. This can be combined with the `feature_summary(FATAL_ON_MISSING_REQUIRED_PACKAGES)` command option. Last, a `RUNTIME` package is a package which is actually not used at all during the build, but which is required for actually running the resulting binaries. So if such a package is missing, the project can still be built, but it may not work later on. If `set_package_properties()` is called multiple times for the same package with different TYPEs, the `TYPE` is only changed to higher TYPEs (`RUNTIME < OPTIONAL < RECOMMENDED < REQUIRED`), lower TYPEs are ignored. The `TYPE` property is project-specific, so it cannot be set by the Find module, but must be set in the project. The accepted types can be changed by setting the `FeatureSummary_PKG_TYPES` global property.

  `PURPOSE <purpose>`

    This describes which features this package enables in the project, i.e. it tells the user what functionality they get in the resulting binaries. If `set_package_properties()` is called multiple times for a package, all `PURPOSE` properties are appended to a list of purposes of the package in the project. As the `TYPE` property, also the `PURPOSE` property is project-specific, so it cannot be set by the Find module, but must be set in the project.

  Example for setting the info for a package:

      include(FeatureSummary)
      find_package(LibXml2)
      set_package_properties(LibXml2 PROPERTIES
                             DESCRIPTION "XML library"
                             URL "http://xmlsoft.org")
      # or
      set_package_properties(LibXml2 PROPERTIES
                             TYPE RECOMMENDED
                             PURPOSE "Enables HTML-import in MyWordProcessor")
      # or
      set_package_properties(LibXml2 PROPERTIES
                             TYPE OPTIONAL
                             PURPOSE "Enables odt-export in MyWordProcessor")

      find_package(DBUS)
      set_package_properties(DBUS PROPERTIES
        TYPE RUNTIME
        PURPOSE "Necessary to disable the screensaver during a presentation")

add_feature_info

      add_feature_info(<name> <enabled> <description>)

  Use this function to add information about a feature identified with a given `<name>`. The `<enabled>` contains whether this feature is enabled or not. It can be a variable or a list of conditions. `<description>` is a text describing the feature. The information can be displayed using `feature_summary()` for `ENABLED_FEATURES` and `DISABLED_FEATURES` respectively.

  Changed in version 3.8: `<enabled>` can be a list of conditions.

  Changed in version 4.0: Full Condition Syntax is now supported for `<enabled>`. See policy `CMP0183`.

  Example for setting the info for a feature:

      include(FeatureSummary)

      option(WITH_FOO "Help for foo" ON)
      add_feature_info(Foo WITH_FOO "this feature provides very cool stuff")

  Example for setting feature info based on a list of conditions:

      option(WITH_FOO "Help for foo" ON)
      option(WITH_BAR "Help for bar" OFF)
      add_feature_info(
        FooBar
        "WITH_FOO;NOT WITH_BAR"
        "this feature is enabled when WITH_FOO is ON and WITH_BAR turned OFF"
      )

  Example for setting feature info depending on a full condition syntax:

  Unlike semicolon-separated list of conditions, this enables using entire condition syntax as being the `if` clause argument, such as grouping conditions with parens and similar.

      option(WITH_FOO "Help for foo" ON)
      option(WITH_BAR "Help for bar" ON)
      option(WITH_BAZ "Help for baz" OFF)
      add_feature_info(
        FooBarBaz
        "WITH_FOO AND (WITH_BAR OR WITH_BAZ)"
        "this feature is enabled when the entire condition is true"
      )

## Deprecated Functions

The following legacy and deprecated functions are provided for backward compatibility with previous CMake versions:

set_package_info

  Deprecated since version 3.8.

      set_package_info(<name> <description> [ <url> [<purpose>] ])

  Set up information about the package `<name>`, which can then be displayed via `feature_summary()`. This can be done either directly in the Find module or in the project which uses the `FeatureSummary` module after the `find_package()` call. The features for which information can be set are added automatically by the `find_package()` command.

  This function is deprecated. Use the `set_package_properties()`, and `add_feature_info()` functions instead.

set_feature_info

  Deprecated since version 3.8.

      set_feature_info(<name> <description> [<url>])

  Does the same as:

      set_package_info(<name> <description> [<url>])

print_enabled_features

  Deprecated since version 3.8.

      print_enabled_features()

  Does the same as:

      feature_summary(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:")

print_disabled_features

  Deprecated since version 3.8.

      print_disabled_features()

  Does the same as:

      feature_summary(WHAT DISABLED_FEATURES DESCRIPTION "Disabled features:")