You Should Add FeatureSummary to your CMake Projects
Here's a common problem: your cmake build is failing with linker errors, and now your're looking through your CMake logs and reading the compilation database to see what libraries were actually included.
What if I told you that there was a better way? Enter Feature Summary.
Basic Usage
The FeatureSummary module has two parts
- add_feature_info(<name>, <condition>, <description>) to add entries to the summary.
- feature_summary(WHAT ALL) to print the summary.
In short, add include(FeatureSummary) to make the commands available to downstream modules, then when declaring options, add them to the summary with add_feature_info.
cmake_minimum_required(VERSION 3.28)
project(FeatureSummaryExample)
include(FeatureSummary)
# Will be reported in the feature summary without further intervention
find_package(Threads REQUIRED)
find_package(Catch2 3)
# Create an option, and add it to feature summary
option(WERROR "Enable -Werror to turn warnings into errors" False)
add_feature_info(
Werror WERROR "Enable -Werror to turn warnings into errors"
)
option(RUN_CLANG_TIDY "Run clang-tidy as part of the build" False)
add_feature_info(
"Run Clang Tidy" RUN_CLANG_TIDY "Run clang tidy as part of the build"
)
# Print the feature summary
feature_summary(WHAT ALL)
Best Practices
You should wait until the very end of your CMake file to call feature_summary. It will only print changes made to that point, so if you call too early, the result may not reflect the final state of the build.
When you run cmake, the options you set (or did not set) will be printed out:
-- The following features have been enabled:
* Werror, Enable -Werror to turn warnings into errors
-- The following REQUIRED packages have been found:
* Threads
-- The following features have been disabled:
* Run Clang Tidy, Run clang tidy as part of the build
-- The following OPTIONAL packages have not been found:
* Catch2 (required version >= 3)
-- Configuring done (0.4s)
Making it Less Verbose
Having to declare an option and then calling add_feature_info each time quickly becomes tedious. A quick script can improve this significantly.
include(FeatureSummary)
function(add_feature_option
_variable_name
_option_description
_option_default
)
if(NOT DEFINED default)
set(default OFF)
endif()
# option(<variable> "<help_text>" [value])
option(${_variable_name} ${_option_description} ${_option_default})
# add_feature_info(<name> <enabled> <description>)
set(_option_value ${${_variable_name}})
add_feature_info(
"${PROJECT_NAME}::${_variable_name}"
${_option_value}
${_option_description}
)
endfunction()
This function declares the option, and adds it to the feature summary in a single pass, saving us quite some typing (and ensuring that all options are always in the feature summary).
cmake_minimum_required(VERSION 3.28)
project(FeatureSummaryExample)
include(FeatureSummary)
include(AddFeatureOption)
# Will be reported in the feature summary without further intervention
find_package(Catch2 3 QUIET)
# Create an option, and add it to feature summary
add_feature_option(
WERROR "Enable -Werror to turn warnings into errors" False
)
add_feature_option(
RUN_CLANG_TIDY "Run clang-tidy as part of the build" False
)
# Print the feature summary
feature_summary(WHAT ALL)