mirror of
https://github.com/Kitware/CMake.git
synced 2026-06-24 08:47:59 +00:00
cmake: Populate help string from documentation table for -D entries
When a built-in cache variable is set via `-D <var>=<value>` with no help text supplied, populate `HELPSTRING` from the built-in documentation table (sourced from `Help/variable/*.rst` and the per-language pattern manuals). Project-defined and unknown variables continue to receive the legacy "No help, variable specified on the command line." sentinel. The cache entry's type and value are left untouched: type stays `UNINITIALIZED` for bare `-D` and an explicit `-D <var>:TYPE=<value>` is honored as before. The `cmCacheManager::LoadCache` path is not modified, so reload of existing caches is a fixed point. Fixes: #27830
This commit is contained in:
committed by
Brad King
parent
0494f294d2
commit
7fdf315ba3
@@ -45,6 +45,16 @@
|
||||
This option may also be given as a single argument:
|
||||
``-D<var>:<type>=<value>`` or ``-D<var>=<value>``.
|
||||
|
||||
The cache :prop_cache:`HELPSTRING` is populated as follows:
|
||||
|
||||
* If the cache entry is known to CMake, its help string is
|
||||
set to a one-line description of the variable.
|
||||
|
||||
.. versionadded:: 4.4
|
||||
|
||||
* Otherwise, its help string is set to the generic default
|
||||
``No help, variable specified on the command line.``
|
||||
|
||||
It's important to note that the order of ``-C`` and ``-D`` arguments is
|
||||
significant. They will be carried out in the order they are listed, with the
|
||||
last argument taking precedence over the previous ones. For example, if you
|
||||
|
||||
5
Help/release/dev/cache-doc-lookup.rst
Normal file
5
Help/release/dev/cache-doc-lookup.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
cache-doc-lookup
|
||||
----------------
|
||||
|
||||
* The :option:`cmake -D` command-line option now populates a
|
||||
default :prop_cache:`HELPSTRING` for variables known to CMake.
|
||||
@@ -879,6 +879,22 @@ target_link_libraries(
|
||||
llpkgc::llpkgc
|
||||
)
|
||||
|
||||
# Built-in cache variable documentation table. This is a committed,
|
||||
# hand-edited translation unit consumed by cmCacheManager to provide
|
||||
# fallback HELPSTRING values for cache entries that ship without one.
|
||||
# See the header comment in cmCacheDocumentationTable.cxx for the scope
|
||||
# and maintenance discipline. The cmCachePatternTable sibling provides
|
||||
# the same service for placeholder-shaped variable names (CMAKE_<LANG>_*,
|
||||
# CMAKE_POLICY_DEFAULT_CMP<NNNN>, etc.) and is consulted as a fallback
|
||||
# inside cmCacheDocumentationTable::Get. No code generation occurs at
|
||||
# build time.
|
||||
target_sources(CMakeLib PRIVATE
|
||||
cmCacheDocumentationTable.h
|
||||
cmCacheDocumentationTable.cxx
|
||||
cmCachePatternTable.h
|
||||
cmCachePatternTable.cxx
|
||||
)
|
||||
|
||||
if(CMake_ENABLE_DEBUGGER)
|
||||
target_sources(
|
||||
CMakeLib
|
||||
|
||||
739
Source/cmCacheDocumentationTable.cxx
Normal file
739
Source/cmCacheDocumentationTable.cxx
Normal file
@@ -0,0 +1,739 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file LICENSE.rst or https://cmake.org/licensing for details. */
|
||||
|
||||
// Built-in cache variable documentation table.
|
||||
//
|
||||
// This file is hand-maintained. Each entry's Summary is a one-line tooltip
|
||||
// installed as the ``HELPSTRING`` of cache variables created via
|
||||
// ``cmake -D <var>=<value>`` when the user did not supply one.
|
||||
//
|
||||
// Membership policy: this table is deliberately limited to variables that a
|
||||
// user would plausibly set on the ``cmake`` command line when configuring a
|
||||
// project.
|
||||
//
|
||||
// Maintenance discipline:
|
||||
// * Adding a new user-facing variable: hand-write one entry below in
|
||||
// ASCII sort order and make sure the corresponding
|
||||
// Help/variable/<NAME>.rst exists.
|
||||
// * Significantly rewording a Help/variable/<NAME>.rst that has an entry
|
||||
// here: review and update the corresponding Summary in the same change
|
||||
// so the tooltip and the manual stay in step. CMake reviewers should
|
||||
// look for this co-evolution.
|
||||
// * Structural drift (typo in NAME, RST renamed or removed) is caught by
|
||||
// Tests/RunCMake/CacheVarHelpCoverage, which asserts that every entry
|
||||
// in this table has a matching Help/variable/<NAME>.rst.
|
||||
//
|
||||
// The Entry layout below (two lines per row, ``{ "NAME",\n "summary" },``)
|
||||
// is intentional: it keeps the table easy to diff, review, and hand-edit
|
||||
// against the corresponding Help/variable/*.rst manuals. clang-format is
|
||||
// suppressed across the array so contributors can update one Summary
|
||||
// without the formatter reflowing every neighbor.
|
||||
|
||||
#include "cmCacheDocumentationTable.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
|
||||
#include <cm/string_view>
|
||||
#include <cmext/string_view>
|
||||
|
||||
#include "cmCachePatternTable.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using cmCacheDocumentationTable::Entry;
|
||||
|
||||
// The entries are sorted by Name in ASCII order so that std::lower_bound
|
||||
// can locate a variable in O(log N) time without any runtime indexing
|
||||
// structure. The testCacheDocumentationTable regression test in
|
||||
// Tests/CMakeLib verifies this invariant.
|
||||
/* clang-format off */
|
||||
Entry const kEntries[] = {
|
||||
{ "BUILD_SHARED_LIBS"_s,
|
||||
"Global default for the library type used by add_library() when no STATIC/SHARED keyword is given: SHARED if true, STATIC otherwise. Not defined by CMake itself; commonly exposed as an option() by projects."_s },
|
||||
{ "BUILD_TESTING"_s,
|
||||
"Control whether the CTest module invokes enable_testing()"_s },
|
||||
{ "CMAKE_ADD_CUSTOM_COMMAND_DEPENDS_EXPLICIT_ONLY"_s,
|
||||
"Enable DEPENDS_EXPLICIT_ONLY option by default for add_custom_command()"_s },
|
||||
{ "CMAKE_ADSP_ROOT"_s,
|
||||
"When cross-compiling for ADSP SHARC/Blackfin, this variable holds the absolute path to the root install directory of the CCES or VDSP++ toolchain."_s },
|
||||
{ "CMAKE_AIX_EXPORT_ALL_SYMBOLS"_s,
|
||||
"Default value for AIX_EXPORT_ALL_SYMBOLS target property"_s },
|
||||
{ "CMAKE_AIX_SHARED_LIBRARY_ARCHIVE"_s,
|
||||
"Enable or disable creation of shared library archives"_s },
|
||||
{ "CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS"_s,
|
||||
"Default value for ANDROID_ANT_ADDITIONAL_OPTIONS target property"_s },
|
||||
{ "CMAKE_ANDROID_API"_s,
|
||||
"When cross-compiling for Android with NVIDIA Nsight Tegra Visual Studio Edition, sets the default for the ANDROID_API target property. In other Android builds, initializes CMAKE_SYSTEM_VERSION if not already set."_s },
|
||||
{ "CMAKE_ANDROID_API_MIN"_s,
|
||||
"Default minimum Android API level for targets"_s },
|
||||
{ "CMAKE_ANDROID_ARCH"_s,
|
||||
"When cross-compiling for Android with NVIDIA Nsight Tegra Visual Studio Edition, sets the default for the ANDROID_ARCH target property. Otherwise, the architecture name (arm, arm64, x86, x86_64) corresponding to CMAKE_ANDROID_ARCH_ABI."_s },
|
||||
{ "CMAKE_ANDROID_ARCH_ABI"_s,
|
||||
"When cross-compiling for Android, this variable specifies the target architecture and ABI (arm64-v8a, armeabi-v7a, x86, x86_64, etc.)."_s },
|
||||
{ "CMAKE_ANDROID_ARM_MODE"_s,
|
||||
"When cross-compiling for Android with armeabi architecture, set to ON to target 32-bit ARM (-marm) instead of the default 16-bit Thumb."_s },
|
||||
{ "CMAKE_ANDROID_ARM_NEON"_s,
|
||||
"When Cross Compiling for Android and CMAKE_ANDROID_ARCH_ABI is set to armeabi-v7a set CMAKE_ANDROID_ARM_NEON to ON to target ARM NEON devices."_s },
|
||||
{ "CMAKE_ANDROID_ASSETS_DIRECTORIES"_s,
|
||||
"Default value for ANDROID_ASSETS_DIRECTORIES target property"_s },
|
||||
{ "CMAKE_ANDROID_EXCEPTIONS"_s,
|
||||
"Specify whether C++ exceptions are enabled in Android NDK builds"_s },
|
||||
{ "CMAKE_ANDROID_GUI"_s,
|
||||
"Default value for ANDROID_GUI target property of executables"_s },
|
||||
{ "CMAKE_ANDROID_JAR_DEPENDENCIES"_s,
|
||||
"Default value for ANDROID_JAR_DEPENDENCIES target property"_s },
|
||||
{ "CMAKE_ANDROID_JAR_DIRECTORIES"_s,
|
||||
"Default value for ANDROID_JAR_DIRECTORIES target property"_s },
|
||||
{ "CMAKE_ANDROID_JAVA_SOURCE_DIR"_s,
|
||||
"Default value for ANDROID_JAVA_SOURCE_DIR target property"_s },
|
||||
{ "CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES"_s,
|
||||
"Default value for ANDROID_NATIVE_LIB_DEPENDENCIES target property"_s },
|
||||
{ "CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES"_s,
|
||||
"Default value for ANDROID_NATIVE_LIB_DIRECTORIES target property"_s },
|
||||
{ "CMAKE_ANDROID_NDK"_s,
|
||||
"When Cross Compiling for Android with the NDK, this variable holds the absolute path to the root directory of the NDK. The directory must contain a platforms subdirectory holding the android-<api> directories."_s },
|
||||
{ "CMAKE_ANDROID_NDK_DEPRECATED_HEADERS"_s,
|
||||
"When cross-compiling for Android with the NDK, specify whether to use deprecated per-api-level headers instead of the unified headers."_s },
|
||||
{ "CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION"_s,
|
||||
"When cross-compiling for Android with the NDK, specify the toolchain version (clang on r19+, or GCC/Clang version on r18-); default selects latest available GCC."_s },
|
||||
{ "CMAKE_ANDROID_PROCESS_MAX"_s,
|
||||
"Default value for ANDROID_PROCESS_MAX target property"_s },
|
||||
{ "CMAKE_ANDROID_PROGUARD"_s,
|
||||
"Default value for ANDROID_PROGUARD target property"_s },
|
||||
{ "CMAKE_ANDROID_PROGUARD_CONFIG_PATH"_s,
|
||||
"Default value for ProGuard config file location on Android targets"_s },
|
||||
{ "CMAKE_ANDROID_RTTI"_s,
|
||||
"Enable RTTI for Android NDK cross compilation"_s },
|
||||
{ "CMAKE_ANDROID_SECURE_PROPS_PATH"_s,
|
||||
"Default value for Android secure properties file location"_s },
|
||||
{ "CMAKE_ANDROID_SKIP_ANT_STEP"_s,
|
||||
"Default value for skipping Ant build step for Android targets"_s },
|
||||
{ "CMAKE_ANDROID_STANDALONE_TOOLCHAIN"_s,
|
||||
"When Cross Compiling for Android with a Standalone Toolchain, this variable holds the absolute path to the root directory of the toolchain. The specified directory must contain a sysroot subdirectory."_s },
|
||||
{ "CMAKE_ANDROID_STL_TYPE"_s,
|
||||
"For Android with Tegra, sets default ANDROID_STL_TYPE target property; for NDK, selects STL variant (none, system, gabi++, gnustl, c++, stlport); default is gnustl_static or c++_static."_s },
|
||||
{ "CMAKE_APPBUNDLE_PATH"_s,
|
||||
"Search path for macOS application bundles used by find_program() and find_package()"_s },
|
||||
{ "CMAKE_APPLE_SILICON_PROCESSOR"_s,
|
||||
"On Apple Silicon macOS hosts, set to arm64 or x86_64 to specify CMAKE_HOST_SYSTEM_PROCESSOR; user cache entry only, never modified by project code."_s },
|
||||
{ "CMAKE_ARCHIVE_OUTPUT_DIRECTORY"_s,
|
||||
"Default output directory for archive target files"_s },
|
||||
{ "CMAKE_AUTOGEN_BETTER_GRAPH_MULTI_CONFIG"_s,
|
||||
"Enable better dependency graph for multi-config autogen targets"_s },
|
||||
{ "CMAKE_AUTOGEN_COMMAND_LINE_LENGTH_MAX"_s,
|
||||
"Limit for autogen command line length triggering response file use on Windows"_s },
|
||||
{ "CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY"_s,
|
||||
"Strategy for autogen intermediate directories: FULL (pattern-based) or SHORT (hash-based)"_s },
|
||||
{ "CMAKE_AUTOGEN_ORIGIN_DEPENDS"_s,
|
||||
"Forward origin target dependencies to autogen targets"_s },
|
||||
{ "CMAKE_AUTOGEN_PARALLEL"_s,
|
||||
"Number of parallel moc/uic processes for autogen targets"_s },
|
||||
{ "CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE"_s,
|
||||
"Add autogen include directory as system include to targets"_s },
|
||||
{ "CMAKE_AUTOGEN_VERBOSE"_s,
|
||||
"Sets verbosity of AUTOMOC/AUTOUIC/AUTORCC generators; positive integer or true boolean enables extra output."_s },
|
||||
{ "CMAKE_AUTOMOC"_s,
|
||||
"Whether to handle Qt moc automatically for targets"_s },
|
||||
{ "CMAKE_AUTOMOC_COMPILER_PREDEFINES"_s,
|
||||
"Whether to generate compiler predefines for moc"_s },
|
||||
{ "CMAKE_AUTOMOC_DEPEND_FILTERS"_s,
|
||||
"Filter definitions for extracting additional dependencies for moc"_s },
|
||||
{ "CMAKE_AUTOMOC_EXECUTABLE"_s,
|
||||
"Path to moc executable for AUTOMOC"_s },
|
||||
{ "CMAKE_AUTOMOC_INCLUDE_DIRECTORIES"_s,
|
||||
"Include directories for AUTOMOC to pass to moc."_s },
|
||||
{ "CMAKE_AUTOMOC_MACRO_NAMES"_s,
|
||||
"Macro names used by AUTOMOC to determine if a file needs moc processing."_s },
|
||||
{ "CMAKE_AUTOMOC_MOC_OPTIONS"_s,
|
||||
"Additional options for moc when using CMAKE_AUTOMOC."_s },
|
||||
{ "CMAKE_AUTOMOC_PATH_PREFIX"_s,
|
||||
"Generate -p path prefix option for moc on AUTOMOC targets."_s },
|
||||
{ "CMAKE_AUTORCC"_s,
|
||||
"Whether to handle rcc automatically for Qt targets."_s },
|
||||
{ "CMAKE_AUTORCC_EXECUTABLE"_s,
|
||||
"Custom rcc executable path for AUTORCC."_s },
|
||||
{ "CMAKE_AUTORCC_OPTIONS"_s,
|
||||
"Additional options for rcc when using CMAKE_AUTORCC."_s },
|
||||
{ "CMAKE_AUTOUIC"_s,
|
||||
"Whether to handle uic automatically for Qt targets."_s },
|
||||
{ "CMAKE_AUTOUIC_EXECUTABLE"_s,
|
||||
"Custom uic executable path for AUTOUIC."_s },
|
||||
{ "CMAKE_AUTOUIC_OPTIONS"_s,
|
||||
"Additional options for uic when using CMAKE_AUTOUIC."_s },
|
||||
{ "CMAKE_AUTOUIC_SEARCH_PATHS"_s,
|
||||
"Search paths for AUTOUIC to find included .ui files."_s },
|
||||
{ "CMAKE_BUILD_RPATH"_s,
|
||||
"Runtime path (RPATH) entries to add to binaries in the build tree."_s },
|
||||
{ "CMAKE_BUILD_RPATH_USE_ORIGIN"_s,
|
||||
"Whether to use relative paths for the build RPATH."_s },
|
||||
{ "CMAKE_BUILD_TYPE"_s,
|
||||
"Build type for single-configuration generators (Makefile Generators, Ninja, etc.). Typical values: Debug, Release, RelWithDebInfo, MinSizeRel; custom build types may also be defined."_s },
|
||||
{ "CMAKE_BUILD_WITH_INSTALL_NAME_DIR"_s,
|
||||
"Whether to use INSTALL_NAME_DIR on targets in the build tree."_s },
|
||||
{ "CMAKE_BUILD_WITH_INSTALL_RPATH"_s,
|
||||
"Build with install RPATH instead of requiring relinking."_s },
|
||||
{ "CMAKE_CLANG_VFS_OVERLAY"_s,
|
||||
"Absolute path to clang virtual file system YAML file for Windows clang-cl cross-compilation"_s },
|
||||
{ "CMAKE_CODEBLOCKS_COMPILER_ID"_s,
|
||||
"Compiler ID in generated CodeBlocks project files; auto-detected if empty"_s },
|
||||
{ "CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES"_s,
|
||||
"Exclude files outside project root from CodeBlocks project files"_s },
|
||||
{ "CMAKE_CODELITE_USE_TARGETS"_s,
|
||||
"Generate CodeLite project files based on targets rather than projects"_s },
|
||||
{ "CMAKE_COLOR_DIAGNOSTICS"_s,
|
||||
"Enable color diagnostics in compiler and build system output"_s },
|
||||
{ "CMAKE_COLOR_MAKEFILE"_s,
|
||||
"Enable color output when using Makefile generators"_s },
|
||||
{ "CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY"_s,
|
||||
"Directory for compiler-generated .pdb debug symbol files"_s },
|
||||
{ "CMAKE_COMPILE_WARNING_AS_ERROR"_s,
|
||||
"Specify whether to treat warnings on compile as errors. This variable is used to initialize the COMPILE_WARNING_AS_ERROR property on all the targets."_s },
|
||||
{ "CMAKE_CONFIGURATION_TYPES"_s,
|
||||
"Semicolon-separated list of available build types for multi-config generators (Visual Studio, Xcode, Ninja Multi-Config). Typical entries: Debug, Release, RelWithDebInfo, MinSizeRel; custom entries may also be defined."_s },
|
||||
{ "CMAKE_CROSSCOMPILING"_s,
|
||||
"Set to true by CMake when cross compiling (if CMAKE_SYSTEM_NAME is manually set). Not recommended for Apple device builds due to SDK-based target selection."_s },
|
||||
{ "CMAKE_CROSS_CONFIGS"_s,
|
||||
"Semicolon-separated list of configurations for Ninja Multi-Config cross-config mode"_s },
|
||||
{ "CMAKE_CTEST_ARGUMENTS"_s,
|
||||
"Command-line arguments to pass to ctest when running tests"_s },
|
||||
{ "CMAKE_CUDA_ARCHITECTURES"_s,
|
||||
"Default GPU architectures for CUDA compilation"_s },
|
||||
{ "CMAKE_CUDA_EXTENSIONS"_s,
|
||||
"Default value for CUDA_EXTENSIONS target property if set when a target is created. See the cmake-compile-features(7) manual for information on compile features and a list of supported compilers."_s },
|
||||
{ "CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS"_s,
|
||||
"Default value for CUDA_RESOLVE_DEVICE_SYMBOLS target property"_s },
|
||||
{ "CMAKE_CUDA_RUNTIME_LIBRARY"_s,
|
||||
"Select CUDA runtime library for compiling and linking CUDA code"_s },
|
||||
{ "CMAKE_CUDA_SEPARABLE_COMPILATION"_s,
|
||||
"Default value for CUDA_SEPARABLE_COMPILATION target property"_s },
|
||||
{ "CMAKE_CUDA_STANDARD"_s,
|
||||
"Default value for CUDA_STANDARD target property if set when a target is created. See the cmake-compile-features(7) manual for information on compile features and a list of supported compilers."_s },
|
||||
{ "CMAKE_CUDA_STANDARD_REQUIRED"_s,
|
||||
"Default value for CUDA_STANDARD_REQUIRED target property if set when a target is created. See the cmake-compile-features(7) manual for information on compile features and a list of supported compilers."_s },
|
||||
{ "CMAKE_CXX_EXTENSIONS"_s,
|
||||
"Default value for CXX_EXTENSIONS target property if set when a target is created. See the cmake-compile-features(7) manual for information on compile features and a list of supported compilers."_s },
|
||||
{ "CMAKE_CXX_MODULE_STD"_s,
|
||||
"Whether to add utility targets as dependencies for C++23 targets"_s },
|
||||
{ "CMAKE_CXX_SCAN_FOR_MODULES"_s,
|
||||
"Whether to scan C++ source files for module dependencies"_s },
|
||||
{ "CMAKE_CXX_STANDARD"_s,
|
||||
"Default value used to initialize the CXX_STANDARD target property when a target is created. See the cmake-compile-features(7) manual for the list of supported standards and compilers."_s },
|
||||
{ "CMAKE_CXX_STANDARD_REQUIRED"_s,
|
||||
"Default value for CXX_STANDARD_REQUIRED target property if set when a target is created. See the cmake-compile-features(7) manual for information on compile features and a list of supported compilers."_s },
|
||||
{ "CMAKE_C_EXTENSIONS"_s,
|
||||
"Default value for C_EXTENSIONS target property if set when a target is created. See the cmake-compile-features(7) manual for information on compile features and a list of supported compilers."_s },
|
||||
{ "CMAKE_C_STANDARD"_s,
|
||||
"Default value used to initialize the C_STANDARD target property when a target is created. See the cmake-compile-features(7) manual for the list of supported standards and compilers."_s },
|
||||
{ "CMAKE_C_STANDARD_REQUIRED"_s,
|
||||
"Default value for C_STANDARD_REQUIRED target property if set when a target is created. See the cmake-compile-features(7) manual for information on compile features and a list of supported compilers."_s },
|
||||
{ "CMAKE_DEBUGGER_WORKING_DIRECTORY"_s,
|
||||
"Working directory for debugger when launching targets"_s },
|
||||
{ "CMAKE_DEBUG_TARGET_PROPERTIES"_s,
|
||||
"Enables debug output for target properties by listing which properties to trace when evaluating targets."_s },
|
||||
{ "CMAKE_DEFAULT_BUILD_TYPE"_s,
|
||||
"Default configuration to use in build.ninja for Ninja Multi-Config"_s },
|
||||
{ "CMAKE_DEFAULT_CONFIGS"_s,
|
||||
"Default configurations to build for targets without :Config suffix"_s },
|
||||
{ "CMAKE_DEPENDS_IN_PROJECT_ONLY"_s,
|
||||
"Only consider dependencies within project source and binary directories"_s },
|
||||
{ "CMAKE_DEPENDS_USE_COMPILER"_s,
|
||||
"Set FALSE to use CMake for dependency discovery instead of compiler"_s },
|
||||
{ "CMAKE_DISABLE_PRECOMPILE_HEADERS"_s,
|
||||
"Default value for disabling precompiled headers on all targets"_s },
|
||||
{ "CMAKE_DLL_NAME_WITH_SOVERSION"_s,
|
||||
"Whether to include soversion in DLL names on Windows platform"_s },
|
||||
{ "CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES"_s,
|
||||
"Generate linked resources in Eclipse project generator output"_s },
|
||||
{ "CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT"_s,
|
||||
"Generate Eclipse project in source directory for version control integration"_s },
|
||||
{ "CMAKE_ECLIPSE_RESOURCE_ENCODING"_s,
|
||||
"Set the resource encoding in Eclipse CDT4 project generator."_s },
|
||||
{ "CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION"_s,
|
||||
"Error when cmake_install.cmake encounters absolute INSTALL DESTINATION."_s },
|
||||
{ "CMAKE_EXECUTABLE_ENABLE_EXPORTS"_s,
|
||||
"Specify whether executables export symbols for loadable modules"_s },
|
||||
{ "CMAKE_EXECUTE_PROCESS_COMMAND_ECHO"_s,
|
||||
"Print commands in execute_process() calls to STDERR, STDOUT, or NONE."_s },
|
||||
{ "CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL"_s,
|
||||
"Default for execute_process() COMMAND_ERROR_IS_FATAL option."_s },
|
||||
{ "CMAKE_EXE_LINKER_FLAGS"_s,
|
||||
"Linker flags to be used to create executables"_s },
|
||||
{ "CMAKE_EXPORT_BUILD_DATABASE"_s,
|
||||
"Experimental; gated by CMAKE_EXPERIMENTAL_EXPORT_BUILD_DATABASE. Enables build_database.json with C++ module compile commands."_s },
|
||||
{ "CMAKE_EXPORT_COMPILE_COMMANDS"_s,
|
||||
"Enable output of a compile_commands.json file listing the exact compiler invocation for each translation unit. Implemented by the Makefile and Ninja generators; ignored elsewhere."_s },
|
||||
{ "CMAKE_EXPORT_NO_PACKAGE_REGISTRY"_s,
|
||||
"Disable the export(PACKAGE) command from writing to the user package registry when CMP0090 is not set to NEW."_s },
|
||||
{ "CMAKE_EXPORT_PACKAGE_REGISTRY"_s,
|
||||
"Enable the export(PACKAGE) command to write to the user package registry when CMP0090 is set to NEW."_s },
|
||||
{ "CMAKE_EXPORT_SARIF"_s,
|
||||
"Enable CMake diagnostics output in SARIF format, written to .cmake/sarif/cmake.sarif by default or to path specified by cmake --sarif-output."_s },
|
||||
{ "CMAKE_FIND_APPBUNDLE"_s,
|
||||
"Control how find_*() commands select macOS Application Bundles."_s },
|
||||
{ "CMAKE_FIND_DEBUG_MODE"_s,
|
||||
"Print debug information for find_program, find_library, find_file, find_path, and find_package to stderr. Output is human-readable, not machine-parseable."_s },
|
||||
{ "CMAKE_FIND_FRAMEWORK"_s,
|
||||
"Control how find_*() commands select macOS Frameworks."_s },
|
||||
{ "CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX"_s,
|
||||
"Suffix to search in lib<suffix> directories before lib in find_library()."_s },
|
||||
{ "CMAKE_FIND_NO_INSTALL_PREFIX"_s,
|
||||
"Exclude CMAKE_INSTALL_PREFIX from CMAKE_SYSTEM_PREFIX_PATH."_s },
|
||||
{ "CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY"_s,
|
||||
"DEPRECATED: Use CMAKE_FIND_USE_PACKAGE_REGISTRY instead. When unset, find_package uses User Package Registry unless disabled. Ignored if CMAKE_FIND_USE_PACKAGE_REGISTRY is set."_s },
|
||||
{ "CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY"_s,
|
||||
"DEPRECATED: Use CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY instead. When unset, find_package uses System Package Registry unless disabled. Ignored if CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY is set."_s },
|
||||
{ "CMAKE_FIND_PACKAGE_PREFER_CONFIG"_s,
|
||||
"Prefer find_package() Config mode over Module mode."_s },
|
||||
{ "CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS"_s,
|
||||
"Resolve symbolic links in <PackageName>_DIR during find_package() lookups."_s },
|
||||
{ "CMAKE_FIND_PACKAGE_TARGETS_GLOBAL"_s,
|
||||
"Promote IMPORTED targets found by find_package() to GLOBAL scope."_s },
|
||||
{ "CMAKE_FIND_PACKAGE_WARN_NO_MODULE"_s,
|
||||
"Warn when find_package() implicitly assumes Config mode."_s },
|
||||
{ "CMAKE_FIND_ROOT_PATH"_s,
|
||||
"Semicolon-separated list of alternative filesystem roots searched by find_package(), find_library(), and the other find_*() commands. Most useful when cross-compiling."_s },
|
||||
{ "CMAKE_FIND_ROOT_PATH_MODE_INCLUDE"_s,
|
||||
"Control whether CMAKE_FIND_ROOT_PATH is used by find_file/find_path"_s },
|
||||
{ "CMAKE_FIND_ROOT_PATH_MODE_LIBRARY"_s,
|
||||
"Control whether CMAKE_FIND_ROOT_PATH is used by find_library"_s },
|
||||
{ "CMAKE_FIND_ROOT_PATH_MODE_PACKAGE"_s,
|
||||
"Control whether CMAKE_FIND_ROOT_PATH is used by find_package"_s },
|
||||
{ "CMAKE_FIND_ROOT_PATH_MODE_PROGRAM"_s,
|
||||
"Control whether CMAKE_FIND_ROOT_PATH is used by find_program"_s },
|
||||
{ "CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH"_s,
|
||||
"Controls whether find commands search cmake-specific environment variables"_s },
|
||||
{ "CMAKE_FIND_USE_CMAKE_PATH"_s,
|
||||
"Controls whether find commands search cmake-specific cache variables"_s },
|
||||
{ "CMAKE_FIND_USE_CMAKE_SYSTEM_PATH"_s,
|
||||
"Controls whether find commands search platform-specific cmake variables"_s },
|
||||
{ "CMAKE_FIND_USE_INSTALL_PREFIX"_s,
|
||||
"Controls whether find commands search CMAKE_INSTALL_PREFIX locations"_s },
|
||||
{ "CMAKE_FIND_USE_PACKAGE_REGISTRY"_s,
|
||||
"Controls whether find_package searches the User Package Registry; takes precedence over the deprecated CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY variable."_s },
|
||||
{ "CMAKE_FIND_USE_PACKAGE_ROOT_PATH"_s,
|
||||
"Controls whether find commands search <PackageName>_ROOT variables"_s },
|
||||
{ "CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH"_s,
|
||||
"Controls whether find commands search system environment variables"_s },
|
||||
{ "CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY"_s,
|
||||
"Controls whether find_package searches the System Package Registry"_s },
|
||||
{ "CMAKE_FOLDER"_s,
|
||||
"Set the folder name to organize targets in an IDE"_s },
|
||||
{ "CMAKE_FRAMEWORK"_s,
|
||||
"Default value for FRAMEWORK target property"_s },
|
||||
{ "CMAKE_FRAMEWORK_PATH"_s,
|
||||
"Semicolon-separated list of directories for macOS framework search path"_s },
|
||||
{ "CMAKE_Fortran_FORMAT"_s,
|
||||
"Set to FIXED or FREE to indicate the Fortran source layout"_s },
|
||||
{ "CMAKE_Fortran_MODULE_DIRECTORY"_s,
|
||||
"Fortran module output directory"_s },
|
||||
{ "CMAKE_Fortran_PREPROCESS"_s,
|
||||
"Default value for Fortran_PREPROCESS target property"_s },
|
||||
{ "CMAKE_GENERATOR_PLATFORM"_s,
|
||||
"Generator-specific target-platform name (set via cmake -A, cmake-gui, or the CMAKE_GENERATOR_PLATFORM environment variable). Used by Visual Studio and Green Hills MULTI; ignored by other generators. Not to be modified by project code."_s },
|
||||
{ "CMAKE_GENERATOR_TOOLSET"_s,
|
||||
"Native-build-system toolset specification (set via cmake -T, cmake-gui, or the CMAKE_GENERATOR_TOOLSET environment variable). Used by Visual Studio, Xcode, and Green Hills MULTI; ignored by other generators. Not to be modified by project code."_s },
|
||||
{ "CMAKE_GHS_NO_SOURCE_GROUP_FILE"_s,
|
||||
"ON/OFF boolean to control if project file for target is single or multiple"_s },
|
||||
{ "CMAKE_GLOBAL_AUTOGEN_TARGET"_s,
|
||||
"Switch to enable generation of a global autogen target"_s },
|
||||
{ "CMAKE_GLOBAL_AUTOGEN_TARGET_NAME"_s,
|
||||
"Change the name of the global autogen target"_s },
|
||||
{ "CMAKE_GLOBAL_AUTORCC_TARGET"_s,
|
||||
"Switch to enable generation of a global autorcc target"_s },
|
||||
{ "CMAKE_GLOBAL_AUTORCC_TARGET_NAME"_s,
|
||||
"Change the name of the global autorcc target"_s },
|
||||
{ "CMAKE_GNUtoMS"_s,
|
||||
"Convert GNU import libraries (.dll.a) to MS format (.lib)"_s },
|
||||
{ "CMAKE_HIP_ARCHITECTURES"_s,
|
||||
"List of GPU architectures for HIP device code generation; interpreted per CMAKE_HIP_PLATFORM"_s },
|
||||
{ "CMAKE_HIP_EXTENSIONS"_s,
|
||||
"Default value for HIP_EXTENSIONS target property if set when a target is created. See the cmake-compile-features(7) manual for information on compile features and a list of supported compilers."_s },
|
||||
{ "CMAKE_HIP_PLATFORM"_s,
|
||||
"GPU platform for HIP targets (amd, nvidia, or spirv)"_s },
|
||||
{ "CMAKE_HIP_STANDARD"_s,
|
||||
"Default value for HIP_STANDARD target property if set when a target is created. See the cmake-compile-features(7) manual for information on compile features and a list of supported compilers."_s },
|
||||
{ "CMAKE_HIP_STANDARD_REQUIRED"_s,
|
||||
"Default value for HIP_STANDARD_REQUIRED target property if set when a target is created. See the cmake-compile-features(7) manual for information on compile features and a list of supported compilers."_s },
|
||||
{ "CMAKE_IGNORE_PATH"_s,
|
||||
"Semicolon-separated list of directories to ignore in find commands"_s },
|
||||
{ "CMAKE_IGNORE_PREFIX_PATH"_s,
|
||||
"Semicolon-separated list of search prefixes to ignore in find commands"_s },
|
||||
{ "CMAKE_INCLUDE_CURRENT_DIR"_s,
|
||||
"Automatically add CMAKE_CURRENT_SOURCE_DIR and CMAKE_CURRENT_BINARY_DIR to include path. Does not propagate to subdirectories. Defaults to OFF."_s },
|
||||
{ "CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE"_s,
|
||||
"Automatically add CMAKE_CURRENT_SOURCE_DIR and CMAKE_CURRENT_BINARY_DIR to INTERFACE_INCLUDE_DIRECTORIES for libraries and executables. Defaults to OFF."_s },
|
||||
{ "CMAKE_INCLUDE_DIRECTORIES_BEFORE"_s,
|
||||
"When ON, include_directories prepends instead of appending directories"_s },
|
||||
{ "CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE"_s,
|
||||
"Force project include directories to appear first in compiler command lines"_s },
|
||||
{ "CMAKE_INCLUDE_PATH"_s,
|
||||
"Semicolon-separated search path for find_file and find_path commands"_s },
|
||||
{ "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"_s,
|
||||
"Default component name for install commands when COMPONENT argument is omitted"_s },
|
||||
{ "CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS"_s,
|
||||
"Default permissions for directories created implicitly during installation"_s },
|
||||
{ "CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO"_s,
|
||||
"Experimental feature (requires CMAKE_EXPERIMENTAL_FIXME gate): directives to install package information when exported target info is installed via install(EXPORT)."_s },
|
||||
{ "CMAKE_INSTALL_MESSAGE"_s,
|
||||
"Verbosity of installation messages: ALWAYS (default, shows Installing and Up-to-date), LAZY (only Installing), or NEVER (silent)."_s },
|
||||
{ "CMAKE_INSTALL_NAME_DIR"_s,
|
||||
"Directory name for installed targets on Apple platforms"_s },
|
||||
{ "CMAKE_INSTALL_OBJECT_NAME_STRATEGY"_s,
|
||||
"Strategy to use for naming installed object files"_s },
|
||||
{ "CMAKE_INSTALL_OBJECT_ONLY_USE_DESTINATION"_s,
|
||||
"Controls whether install DESTINATION for object libraries uses subdirectories"_s },
|
||||
{ "CMAKE_INSTALL_PREFIX"_s,
|
||||
"Install directory prepended to all install() destinations. Defaults to c:/Program Files/${PROJECT_NAME} on Windows and /usr/local on UNIX; may be overridden at install time via cmake --install --prefix."_s },
|
||||
{ "CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH"_s,
|
||||
"Boolean controlling whether toolchain-defined rpaths are removed during install"_s },
|
||||
{ "CMAKE_INSTALL_RPATH"_s,
|
||||
"Semicolon-separated list specifying rpath to use in installed targets"_s },
|
||||
{ "CMAKE_INSTALL_RPATH_USE_LINK_PATH"_s,
|
||||
"If TRUE, append linker search and installed library paths to installed rpath"_s },
|
||||
{ "CMAKE_INTERMEDIATE_DIR_STRATEGY"_s,
|
||||
"CMAKE_INTERMEDIATE_DIR_STRATEGY is a string cache variable specifying the strategy to use for target intermediate directories and their contents. The supported values are:"_s },
|
||||
{ "CMAKE_INTERPROCEDURAL_OPTIMIZATION"_s,
|
||||
"Default value for INTERPROCEDURAL_OPTIMIZATION of targets"_s },
|
||||
{ "CMAKE_IOS_INSTALL_COMBINED"_s,
|
||||
"This is deprecated. Default value for IOS_INSTALL_COMBINED of targets. This variable is used to initialize the IOS_INSTALL_COMBINED property on all the targets."_s },
|
||||
{ "CMAKE_ISPC_HEADER_DIRECTORY"_s,
|
||||
"Default output directory for ISPC-generated headers"_s },
|
||||
{ "CMAKE_ISPC_HEADER_SUFFIX"_s,
|
||||
"Output suffix for ISPC-generated headers"_s },
|
||||
{ "CMAKE_ISPC_INSTRUCTION_SETS"_s,
|
||||
"Default instruction sets for ISPC compilation"_s },
|
||||
{ "CMAKE_KATE_FILES_MODE"_s,
|
||||
"Kate project generator file mode (AUTO, SVN, GIT, HG, FOSSIL, or LIST)"_s },
|
||||
{ "CMAKE_KATE_MAKE_ARGUMENTS"_s,
|
||||
"Arguments passed to make tool when Kate invokes build"_s },
|
||||
{ "CMAKE_LIBRARY_OUTPUT_DIRECTORY"_s,
|
||||
"Where to put all LIBRARY target files when built"_s },
|
||||
{ "CMAKE_LIBRARY_PATH"_s,
|
||||
"Semicolon-separated search path for find_library command"_s },
|
||||
{ "CMAKE_LINKER_TYPE"_s,
|
||||
"Specify which linker to use for link steps; initialized on targets and used by try_compile()."_s },
|
||||
{ "CMAKE_LINK_DEPENDS_NO_SHARED"_s,
|
||||
"Whether to skip link dependencies on shared library files"_s },
|
||||
{ "CMAKE_LINK_DEPENDS_USE_LINKER"_s,
|
||||
"For Makefile/Ninja generators, whether linker generates link dependencies"_s },
|
||||
{ "CMAKE_LINK_DIRECTORIES_BEFORE"_s,
|
||||
"Prepend directories by default in link_directories instead of appending"_s },
|
||||
{ "CMAKE_LINK_INTERFACE_LIBRARIES"_s,
|
||||
"Default value for LINK_INTERFACE_LIBRARIES of targets"_s },
|
||||
{ "CMAKE_LINK_LIBRARIES_ONLY_TARGETS"_s,
|
||||
"Enable check that all target-like items in target_link_libraries() are existing targets."_s },
|
||||
{ "CMAKE_LINK_LIBRARIES_STRATEGY"_s,
|
||||
"Specify a strategy for ordering targets' link dependencies on linker command lines."_s },
|
||||
{ "CMAKE_LINK_SEARCH_END_STATIC"_s,
|
||||
"End link line with static system libraries; use -Bstatic with compatible linkers."_s },
|
||||
{ "CMAKE_LINK_SEARCH_START_STATIC"_s,
|
||||
"Assume linker looks for static libraries by default; use -Bstatic with compatible linkers."_s },
|
||||
{ "CMAKE_LINK_WARNING_AS_ERROR"_s,
|
||||
"Specify whether to treat warnings on link as errors. This variable is used to initialize the LINK_WARNING_AS_ERROR property on all the targets."_s },
|
||||
{ "CMAKE_LINK_WHAT_YOU_USE"_s,
|
||||
"Default value for LINK_WHAT_YOU_USE target property"_s },
|
||||
{ "CMAKE_MACOSX_BUNDLE"_s,
|
||||
"Default value for MACOSX_BUNDLE target property"_s },
|
||||
{ "CMAKE_MACOSX_RPATH"_s,
|
||||
"Whether to use rpaths on macOS and iOS"_s },
|
||||
{ "CMAKE_MAKE_PROGRAM"_s,
|
||||
"Tool that can launch the native build system. The value may be the full path to an executable or just the tool name if it is expected to be in the PATH. The tool selected depends on the CMAKE_GENERATOR used to configure the project:"_s },
|
||||
{ "CMAKE_MAXIMUM_RECURSION_DEPTH"_s,
|
||||
"Maximum recursion depth for CMake scripts"_s },
|
||||
{ "CMAKE_MESSAGE_CONTEXT"_s,
|
||||
"List of context names prepended to message output when logging context enabled"_s },
|
||||
{ "CMAKE_MESSAGE_CONTEXT_SHOW"_s,
|
||||
"Setting this variable to true enables showing a context with each line logged by message command (see CMAKE_MESSAGE_CONTEXT for how context is specified), as an alternative to cmake --log-context option."_s },
|
||||
{ "CMAKE_MESSAGE_INDENT"_s,
|
||||
"Indentation strings prepended to message command output for NOTICE and below"_s },
|
||||
{ "CMAKE_MESSAGE_LOG_LEVEL"_s,
|
||||
"When set, specifies the logging level used by message command with values same as cmake(1) --log-level option; command line option takes precedence if both are set."_s },
|
||||
{ "CMAKE_MFC_FLAG"_s,
|
||||
"Use the MFC library for an executable or dll; enables Microsoft Foundation Classes (MFC); set to 1 for static library, 2 for shared; used in Visual Studio project files."_s },
|
||||
{ "CMAKE_MODULE_LINKER_FLAGS"_s,
|
||||
"Linker flags to be used to create modules"_s },
|
||||
{ "CMAKE_MODULE_PATH"_s,
|
||||
"Semicolon-separated list of directories searched for CMake modules by include() and find_package() before the modules shipped with CMake. Empty by default."_s },
|
||||
{ "CMAKE_MSVCIDE_RUN_PATH"_s,
|
||||
"Extra PATH locations for executing add_custom_command or add_custom_target with Visual Studio Generators; allows running commands and dlls the IDE doesn't know about; initialized from CMAKE_MSVCIDE_RUN_PATH environment variable if set."_s },
|
||||
{ "CMAKE_MSVC_DEBUG_INFORMATION_FORMAT"_s,
|
||||
"Select the MSVC debug information format targeting the MSVC ABI"_s },
|
||||
{ "CMAKE_MSVC_RUNTIME_CHECKS"_s,
|
||||
"Select the list of enabled runtime checks when targeting MSVC ABI"_s },
|
||||
{ "CMAKE_MSVC_RUNTIME_LIBRARY"_s,
|
||||
"Select the MSVC runtime library for use by compilers targeting MSVC ABI"_s },
|
||||
{ "CMAKE_NINJA_OUTPUT_PATH_PREFIX"_s,
|
||||
"Tell Ninja Generators to add a prefix to every output path"_s },
|
||||
{ "CMAKE_NO_BUILTIN_CHRPATH"_s,
|
||||
"Do not use builtin binary editor to fix runtime library search paths"_s },
|
||||
{ "CMAKE_NO_SYSTEM_FROM_IMPORTED"_s,
|
||||
"Default value for NO_SYSTEM_FROM_IMPORTED target property"_s },
|
||||
{ "CMAKE_OBJCXX_EXTENSIONS"_s,
|
||||
"Default value for OBJCXX_EXTENSIONS target property if set when a target is created. See the cmake-compile-features(7) manual for information on compile features and a list of supported compilers."_s },
|
||||
{ "CMAKE_OBJCXX_STANDARD"_s,
|
||||
"Default value for OBJCXX_STANDARD target property if set when a target is created. See the cmake-compile-features(7) manual for information on compile features and a list of supported compilers."_s },
|
||||
{ "CMAKE_OBJCXX_STANDARD_REQUIRED"_s,
|
||||
"Default value for OBJCXX_STANDARD_REQUIRED target property if set when a target is created. See the cmake-compile-features(7) manual for information on compile features and a list of supported compilers."_s },
|
||||
{ "CMAKE_OBJC_EXTENSIONS"_s,
|
||||
"Default value for OBJC_EXTENSIONS target property if set when a target is created. See the cmake-compile-features(7) manual for information on compile features and a list of supported compilers."_s },
|
||||
{ "CMAKE_OBJC_STANDARD"_s,
|
||||
"Default value for OBJC_STANDARD target property if set when a target is created. See the cmake-compile-features(7) manual for information on compile features and a list of supported compilers."_s },
|
||||
{ "CMAKE_OBJC_STANDARD_REQUIRED"_s,
|
||||
"Default value for OBJC_STANDARD_REQUIRED target property if set when a target is created. See the cmake-compile-features(7) manual for information on compile features and a list of supported compilers."_s },
|
||||
{ "CMAKE_OBJECT_PATH_MAX"_s,
|
||||
"Maximum object file full-path length allowed by native build tools; CMake hashes long paths to keep them under this limit."_s },
|
||||
{ "CMAKE_OPTIMIZE_DEPENDENCIES"_s,
|
||||
"Initializes the OPTIMIZE_DEPENDENCIES target property"_s },
|
||||
{ "CMAKE_OSX_ARCHITECTURES"_s,
|
||||
"Target architectures for macOS and iOS builds (e.g. x86_64;arm64). Initializes the OSX_ARCHITECTURES target property; if empty, the compiler's default architecture is used."_s },
|
||||
{ "CMAKE_OSX_DEPLOYMENT_TARGET"_s,
|
||||
"Minimum macOS or iOS version on which the built binaries are to be deployed. Initialized from the MACOSX_DEPLOYMENT_TARGET environment variable when not set explicitly."_s },
|
||||
{ "CMAKE_OSX_SYSROOT"_s,
|
||||
"Location or short name (e.g. macosx) of the macOS platform SDK passed to the compiler via -isysroot. Initialized from the SDKROOT environment variable; empty by default."_s },
|
||||
{ "CMAKE_PCH_INSTANTIATE_TEMPLATES"_s,
|
||||
"Initializes the PCH_INSTANTIATE_TEMPLATES target property"_s },
|
||||
{ "CMAKE_PCH_WARN_INVALID"_s,
|
||||
"Initializes the PCH_WARN_INVALID target property"_s },
|
||||
{ "CMAKE_PDB_OUTPUT_DIRECTORY"_s,
|
||||
"Output directory for MS debug symbol .pdb files generated by linker"_s },
|
||||
{ "CMAKE_PKG_CONFIG_DISABLE_UNINSTALLED"_s,
|
||||
"Disable uninstalled package file priority in pkg-config searches"_s },
|
||||
{ "CMAKE_PKG_CONFIG_PC_LIB_DIRS"_s,
|
||||
"Primary search paths for pkg-config package files"_s },
|
||||
{ "CMAKE_PKG_CONFIG_PC_PATH"_s,
|
||||
"Supplementary search paths for pkg-config package files"_s },
|
||||
{ "CMAKE_PKG_CONFIG_SYSROOT_DIR"_s,
|
||||
"Path to prepend to -I include and -L library directories extracted by cmake_pkg_config command."_s },
|
||||
{ "CMAKE_PKG_CONFIG_TOP_BUILD_DIR"_s,
|
||||
"Path to derive pc_top_builddir package variable by cmake_pkg_config command."_s },
|
||||
{ "CMAKE_PLATFORM_NO_VERSIONED_SONAME"_s,
|
||||
"Disable version information on shared library targets on applicable platforms"_s },
|
||||
{ "CMAKE_POLICY_VERSION_MINIMUM"_s,
|
||||
"Set minimum Policy Version for a project; for configuring third-party projects without modifying their code."_s },
|
||||
{ "CMAKE_POSITION_INDEPENDENT_CODE"_s,
|
||||
"Default value used to initialize the POSITION_INDEPENDENT_CODE target property on targets that are not SHARED or MODULE libraries. SHARED and MODULE libraries always have PIC enabled."_s },
|
||||
{ "CMAKE_PREFIX_PATH"_s,
|
||||
"Semicolon-separated list of installation prefixes searched by find_package(), find_program(), find_library(), find_file(), and find_path(). Empty by default; intended to be set by the project or the user."_s },
|
||||
{ "CMAKE_PROGRAM_PATH"_s,
|
||||
"Semicolon-separated list of directories to search for programs with find_program command."_s },
|
||||
{ "CMAKE_PROJECT_INCLUDE"_s,
|
||||
"CMake language file(s) to include as last step of project command calls for code injection without source modification."_s },
|
||||
{ "CMAKE_PROJECT_INCLUDE_BEFORE"_s,
|
||||
"CMake language file(s) to include as first step of project command calls for code injection without source modification."_s },
|
||||
{ "CMAKE_PROJECT_TOP_LEVEL_INCLUDES"_s,
|
||||
"Semicolon-separated list of CMake language files to include as part of the very first project() call."_s },
|
||||
{ "CMAKE_RUNTIME_OUTPUT_DIRECTORY"_s,
|
||||
"Where to put all RUNTIME target files when built"_s },
|
||||
{ "CMAKE_Rust_EDITION"_s,
|
||||
"Default Rust edition for Rust targets when created"_s },
|
||||
{ "CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS"_s,
|
||||
"Specify whether shared library generates an import file"_s },
|
||||
{ "CMAKE_SHARED_LINKER_FLAGS"_s,
|
||||
"Linker flags to be used to create shared libraries"_s },
|
||||
{ "CMAKE_SKIP_BUILD_RPATH"_s,
|
||||
"Do not include RPATHs in the build tree"_s },
|
||||
{ "CMAKE_SKIP_INSTALL_ALL_DEPENDENCY"_s,
|
||||
"If true, install target does not depend on all target; installation proceeds independently of build status."_s },
|
||||
{ "CMAKE_SKIP_INSTALL_RPATH"_s,
|
||||
"Do not include RPATHs in the install tree"_s },
|
||||
{ "CMAKE_SKIP_LINTING"_s,
|
||||
"Default value for the SKIP_LINTING target property"_s },
|
||||
{ "CMAKE_SKIP_TEST_ALL_DEPENDENCY"_s,
|
||||
"If true, test target does not depend on all target; test execution proceeds independently of build status."_s },
|
||||
{ "CMAKE_STAGING_PREFIX"_s,
|
||||
"Install path to use when cross-compiling; also used as a search prefix by find_*() commands."_s },
|
||||
{ "CMAKE_STATIC_LINKER_FLAGS"_s,
|
||||
"Flags to be used to create static libraries"_s },
|
||||
{ "CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS"_s,
|
||||
"Semicolon-separated list of environment variables (var=value format) for Sublime Text 2 project generation."_s },
|
||||
{ "CMAKE_SUBLIME_TEXT_2_EXCLUDE_BUILD_TREE"_s,
|
||||
"If true, exclude build tree from Sublime Text 2 .sublime-project file if build tree is inside source tree."_s },
|
||||
{ "CMAKE_SUPPRESS_REGENERATION"_s,
|
||||
"If true, CMake does not add special regeneration target or perform build system checks for source changes."_s },
|
||||
{ "CMAKE_SYSROOT"_s,
|
||||
"Path passed to the compiler via --sysroot (when supported) and used as a prefix for find_*() searches. May only be set in a toolchain file (CMAKE_TOOLCHAIN_FILE)."_s },
|
||||
{ "CMAKE_SYSTEM_NAME"_s,
|
||||
"Name of the operating system being targeted (e.g. Linux, Darwin, Windows). Defaults to CMAKE_HOST_SYSTEM_NAME; set explicitly when first configuring a build tree to enable cross-compiling."_s },
|
||||
{ "CMAKE_SYSTEM_PROCESSOR"_s,
|
||||
"Target system processor; same as CMAKE_HOST_SYSTEM_PROCESSOR for non-cross-compiling, set explicitly in toolchain files."_s },
|
||||
{ "CMAKE_SYSTEM_VERSION"_s,
|
||||
"Version of the target operating system. Defaults to CMAKE_HOST_SYSTEM_VERSION for host builds; must be set explicitly alongside CMAKE_SYSTEM_NAME when cross-compiling."_s },
|
||||
{ "CMAKE_Swift_LANGUAGE_VERSION"_s,
|
||||
"Swift language version (defaults based on Xcode version if not set)"_s },
|
||||
{ "CMAKE_TLS_CAINFO"_s,
|
||||
"Path to TLS CA certificate file for file(DOWNLOAD), file(UPLOAD), ExternalProject, and FetchContent"_s },
|
||||
{ "CMAKE_TLS_VERIFY"_s,
|
||||
"Enable TLS verification for file(DOWNLOAD), file(UPLOAD), ExternalProject, and FetchContent"_s },
|
||||
{ "CMAKE_TLS_VERSION"_s,
|
||||
"Minimum TLS version for file(DOWNLOAD), file(UPLOAD), ExternalProject, and FetchContent (see manual)"_s },
|
||||
{ "CMAKE_TOOLCHAIN_FILE"_s,
|
||||
"Path to a CMake toolchain file, read early in the CMake run, that specifies the compilers, toolchain utilities, and target-platform information used when cross-compiling."_s },
|
||||
{ "CMAKE_TRY_COMPILE_CONFIGURATION"_s,
|
||||
"Build configuration used for try_compile and try_run projects"_s },
|
||||
{ "CMAKE_TRY_COMPILE_NO_PLATFORM_VARIABLES"_s,
|
||||
"Set to a true value to tell the try_compile command not to propagate any platform variables into the test project. The try_compile command normally passes some CMake variables that configure the platform and toolchain behavior into test projects. See policy CMP0137."_s },
|
||||
{ "CMAKE_TRY_COMPILE_PLATFORM_VARIABLES"_s,
|
||||
"List of variables that the try_compile command source file signature must propagate into the test project in order to target the same platform as the host project. This variable should not be set by project code. It is meant to be set by CMake's platform information modules or by a toolchain file."_s },
|
||||
{ "CMAKE_TRY_COMPILE_TARGET_TYPE"_s,
|
||||
"Type of target generated for try_compile calls using the source file signature. Valid values are EXECUTABLE (use add_executable, default) or STATIC_LIBRARY (use add_library with STATIC option to avoid linking)."_s },
|
||||
{ "CMAKE_UNITY_BUILD"_s,
|
||||
"Enable batch compilation of multiple sources within targets"_s },
|
||||
{ "CMAKE_UNITY_BUILD_BATCH_SIZE"_s,
|
||||
"Specifies default upper limit on number of source files combined in one unity source file"_s },
|
||||
{ "CMAKE_UNITY_BUILD_RELOCATABLE"_s,
|
||||
"Enable relative paths in generated unity build source files"_s },
|
||||
{ "CMAKE_UNITY_BUILD_UNIQUE_ID"_s,
|
||||
"Specify unique identifier name generated per file in unity build"_s },
|
||||
{ "CMAKE_USER_MAKE_RULES_OVERRIDE"_s,
|
||||
"Specify a CMake file that overrides platform information. CMake loads the specified file while enabling support for each language from either the project or enable_language commands. It is loaded after CMake's builtin compiler and platform information modules have been loaded but before the information is used."_s },
|
||||
{ "CMAKE_VERBOSE_MAKEFILE"_s,
|
||||
"Enable verbose output from Makefile builds, showing each command line as it is launched. Initialized to FALSE by the project() command; users may override per build tree."_s },
|
||||
{ "CMAKE_VERIFY_INTERFACE_HEADER_SETS"_s,
|
||||
"Enable interface header set verification for targets"_s },
|
||||
{ "CMAKE_VERIFY_PRIVATE_HEADER_SETS"_s,
|
||||
"Enable private header set verification for targets"_s },
|
||||
{ "CMAKE_VISIBILITY_INLINES_HIDDEN"_s,
|
||||
"Default value for VISIBILITY_INLINES_HIDDEN target property"_s },
|
||||
{ "CMAKE_VS_DEBUGGER_COMMAND"_s,
|
||||
"Initialize debugger command path for Visual Studio targets"_s },
|
||||
{ "CMAKE_VS_DEBUGGER_COMMAND_ARGUMENTS"_s,
|
||||
"Initialize debugger command arguments for Visual Studio targets"_s },
|
||||
{ "CMAKE_VS_DEBUGGER_ENVIRONMENT"_s,
|
||||
"Initialize debugger environment variables for Visual Studio targets"_s },
|
||||
{ "CMAKE_VS_DEBUGGER_WORKING_DIRECTORY"_s,
|
||||
"Initialize debugger working directory for Visual Studio targets"_s },
|
||||
{ "CMAKE_VS_GLOBALS"_s,
|
||||
"Set custom global Visual Studio properties on all targets"_s },
|
||||
{ "CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD"_s,
|
||||
"Include INSTALL target in default Visual Studio build"_s },
|
||||
{ "CMAKE_VS_INCLUDE_PACKAGE_TO_DEFAULT_BUILD"_s,
|
||||
"Include PACKAGE target in default Visual Studio build"_s },
|
||||
{ "CMAKE_VS_JUST_MY_CODE_DEBUGGING"_s,
|
||||
"Enable Just My Code debugging with Visual Studio"_s },
|
||||
{ "CMAKE_VS_NO_COMPILE_BATCHING"_s,
|
||||
"Disable compile batching for Visual Studio generator"_s },
|
||||
{ "CMAKE_VS_NUGET_PACKAGE_RESTORE"_s,
|
||||
"Controls whether msbuild automatically restores NuGet packages before a build (Visual Studio Generators)"_s },
|
||||
{ "CMAKE_VS_SDK_EXCLUDE_DIRECTORIES"_s,
|
||||
"Override Visual Studio default Exclude Directories"_s },
|
||||
{ "CMAKE_VS_SDK_EXECUTABLE_DIRECTORIES"_s,
|
||||
"Override Visual Studio default Executable Directories"_s },
|
||||
{ "CMAKE_VS_SDK_INCLUDE_DIRECTORIES"_s,
|
||||
"Override Visual Studio default Include Directories"_s },
|
||||
{ "CMAKE_VS_SDK_LIBRARY_DIRECTORIES"_s,
|
||||
"Override Visual Studio default Library Directories"_s },
|
||||
{ "CMAKE_VS_SDK_LIBRARY_WINRT_DIRECTORIES"_s,
|
||||
"Override Visual Studio default Library WinRT Directories"_s },
|
||||
{ "CMAKE_VS_SDK_REFERENCE_DIRECTORIES"_s,
|
||||
"Override Visual Studio default Reference Directories"_s },
|
||||
{ "CMAKE_VS_SDK_SOURCE_DIRECTORIES"_s,
|
||||
"Override Visual Studio default Source Directories"_s },
|
||||
{ "CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION"_s,
|
||||
"Visual Studio Windows Target Platform Version. CMake selects the Windows SDK version when targeting Windows 10 and above on VS 2015+."_s },
|
||||
{ "CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION"_s,
|
||||
"Ask cmake_install.cmake script to warn when encountering files with absolute INSTALL DESTINATION"_s },
|
||||
{ "CMAKE_WATCOM_RUNTIME_LIBRARY"_s,
|
||||
"Initialize WATCOM_RUNTIME_LIBRARY target property for all targets"_s },
|
||||
{ "CMAKE_WIN32_EXECUTABLE"_s,
|
||||
"Default value for WIN32_EXECUTABLE target property"_s },
|
||||
{ "CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS"_s,
|
||||
"Default value for WINDOWS_EXPORT_ALL_SYMBOLS target property"_s },
|
||||
{ "CMAKE_XCODE_GENERATE_SCHEME"_s,
|
||||
"Enable generation of scheme files by the Xcode generator for analyze, archive, and test actions"_s },
|
||||
{ "CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY"_s,
|
||||
"If enabled, Xcode generator produces a single project file instead of one per project() invocation"_s },
|
||||
{ "CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER"_s,
|
||||
"Enable Address Sanitizer in the Diagnostics section of the generated Xcode scheme"_s },
|
||||
{ "CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN"_s,
|
||||
"Enable detection of stack use-after-return in the Diagnostics section of the generated Xcode scheme"_s },
|
||||
{ "CMAKE_XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING"_s,
|
||||
"Enable debugging when using document Versions Browser in the generated Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER"_s,
|
||||
"Disable the Main Thread Checker in the Diagnostics section of the generated Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS"_s,
|
||||
"Enable Dynamic Library Loads in the Diagnostics section of the generated Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE"_s,
|
||||
"Enable Dynamic Linker API usage in the Diagnostics section of the generated Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_ENABLE_GPU_API_VALIDATION"_s,
|
||||
"Populate Metal: API Validation in the Options section of the generated Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_ENABLE_GPU_FRAME_CAPTURE_MODE"_s,
|
||||
"Set GPU Frame Capture to Metal or Disabled in the Options section of the generated Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION"_s,
|
||||
"Populate Metal: Shader Validation in the Options section of the generated Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_ENVIRONMENT"_s,
|
||||
"Specify environment variables as MYVAR=value list to add to the Arguments section of the Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_GUARD_MALLOC"_s,
|
||||
"Enable Guard Malloc in the Diagnostics section of the generated Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_LAUNCH_CONFIGURATION"_s,
|
||||
"Set the build configuration to run the target in the generated Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_LAUNCH_MODE"_s,
|
||||
"Populate Launch in the Info section of the generated Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_LLDB_INIT_FILE"_s,
|
||||
"Populate LLDB Init File in the Info section of the generated Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP"_s,
|
||||
"Enable Main Thread Checker pause-on-issues in the Diagnostics section of the Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES"_s,
|
||||
"Enable Malloc Guard Edges in the Diagnostics section of the generated Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE"_s,
|
||||
"Enable Malloc Scribble in the Diagnostics section of the generated Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_MALLOC_STACK"_s,
|
||||
"Enable Malloc Stack diagnostics in the generated Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_TEST_CONFIGURATION"_s,
|
||||
"Build configuration for testing targets in the Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_THREAD_SANITIZER"_s,
|
||||
"Enable Thread Sanitizer diagnostics in the generated Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP"_s,
|
||||
"Enable Thread Sanitizer pause-on-issues in the generated Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER"_s,
|
||||
"Enable Undefined Behavior Sanitizer in the generated Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP"_s,
|
||||
"Enable Undefined Behavior Sanitizer pause-on-issues in the generated Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_WORKING_DIRECTORY"_s,
|
||||
"Working directory for Run and Profile actions in the Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS"_s,
|
||||
"Enable Zombie Objects diagnostics in the generated Xcode scheme."_s },
|
||||
{ "CMAKE_XCODE_XCCONFIG"_s,
|
||||
"If set, the Xcode generator will register the specified file as a global XCConfig file. For target-level XCConfig files see the XCODE_XCCONFIG target property."_s },
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
} // namespace
|
||||
|
||||
cmCacheDocumentationTable::LookupResult cmCacheDocumentationTable::Get(
|
||||
cm::string_view varName)
|
||||
{
|
||||
auto const* const first = std::begin(kEntries);
|
||||
auto const* const last = std::end(kEntries);
|
||||
auto const* const it = std::lower_bound(
|
||||
first, last, varName, [](Entry const& entry, cm::string_view target) {
|
||||
return entry.Name < target;
|
||||
});
|
||||
if (it != last && it->Name == varName) {
|
||||
return { it->Summary };
|
||||
}
|
||||
// Exact-match miss: fall back to the pattern table (CMAKE_<LANG>_FLAGS,
|
||||
// CMAKE_POLICY_DEFAULT_CMP<NNNN>, etc.). Exact-match always wins by
|
||||
// construction; only on a miss do we consult the (small, linearly
|
||||
// scanned) pattern table. See Source/cmCachePatternTable.{h,cxx} and
|
||||
// the testPatternMatch* cases in Tests/CMakeLib for the contract.
|
||||
return cmCachePatternTable::Match(varName);
|
||||
}
|
||||
|
||||
cmCacheDocumentationTable::Entry const*
|
||||
cmCacheDocumentationTable::EntriesBegin()
|
||||
{
|
||||
return std::begin(kEntries);
|
||||
}
|
||||
|
||||
cmCacheDocumentationTable::Entry const* cmCacheDocumentationTable::EntriesEnd()
|
||||
{
|
||||
return std::end(kEntries);
|
||||
}
|
||||
|
||||
std::size_t cmCacheDocumentationTable::EntriesSize()
|
||||
{
|
||||
return static_cast<std::size_t>(std::end(kEntries) - std::begin(kEntries));
|
||||
}
|
||||
67
Source/cmCacheDocumentationTable.h
Normal file
67
Source/cmCacheDocumentationTable.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file LICENSE.rst or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <cm/string_view>
|
||||
|
||||
/** \namespace cmCacheDocumentationTable
|
||||
* \brief Compile-time lookup for built-in CMake cache variable documentation.
|
||||
*
|
||||
* The table is a hand-maintained list of short, single-line plain-text
|
||||
* summaries keyed by the canonical CMake variable name (for example
|
||||
* ``CMAKE_BUILD_TYPE``). See the header comment in
|
||||
* ``cmCacheDocumentationTable.cxx`` for the scope of variables included
|
||||
* and the maintenance discipline.
|
||||
*
|
||||
* The sole consumer is ``cmake::ProcessCacheArg``, which reads
|
||||
* ``Summary`` to populate the ``HELPSTRING`` of cache entries created
|
||||
* via ``-D <var>=<value>`` when the user did not supply one.
|
||||
*/
|
||||
namespace cmCacheDocumentationTable {
|
||||
|
||||
/** \brief A single row in the built-in documentation table.
|
||||
*
|
||||
* The ``Name`` and ``Summary`` views reference storage with static
|
||||
* lifetime.
|
||||
*/
|
||||
struct Entry
|
||||
{
|
||||
cm::string_view Name;
|
||||
cm::string_view Summary;
|
||||
};
|
||||
|
||||
/** \brief Result of a single ``Get`` lookup.
|
||||
*
|
||||
* An unknown key yields an empty ``Summary``.
|
||||
*/
|
||||
struct LookupResult
|
||||
{
|
||||
cm::string_view Summary;
|
||||
};
|
||||
|
||||
/** \brief Look up the built-in documentation for \a varName.
|
||||
*
|
||||
* Returns a ``LookupResult`` whose ``Summary`` references storage with
|
||||
* static lifetime when \a varName corresponds to a documented CMake
|
||||
* variable. Otherwise returns an empty ``Summary``. The lookup runs
|
||||
* in ``O(log N)`` and performs no allocation.
|
||||
*/
|
||||
LookupResult Get(cm::string_view varName);
|
||||
|
||||
/** \brief Iterate the underlying table.
|
||||
*
|
||||
* These are exposed primarily for the ``testCacheDocumentationTable``
|
||||
* regression test in ``Tests/CMakeLib``, which verifies that the entries
|
||||
* are sorted (a precondition of ``Get``'s ``std::lower_bound`` lookup),
|
||||
* unique, and otherwise well-formed. Callers should not rely on a
|
||||
* particular entry count or ordering beyond the sort invariant.
|
||||
*/
|
||||
Entry const* EntriesBegin();
|
||||
Entry const* EntriesEnd();
|
||||
std::size_t EntriesSize();
|
||||
|
||||
}
|
||||
536
Source/cmCachePatternTable.cxx
Normal file
536
Source/cmCachePatternTable.cxx
Normal file
@@ -0,0 +1,536 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file LICENSE.rst or https://cmake.org/licensing for details. */
|
||||
|
||||
// Built-in cache variable documentation pattern table.
|
||||
//
|
||||
// This file is hand-maintained. Each entry's Pattern is a literal template
|
||||
// string containing one or more angle-bracketed placeholders (``<LANG>``,
|
||||
// ``<CONFIG>``, ``<PackageName>``, ``<PROJECT-NAME>``, ``<an-attribute>``,
|
||||
// ``<NNNN>``, ``<n>``). The Summary is a one-line tooltip installed as
|
||||
// the ``HELPSTRING`` of cache variables created via
|
||||
// ``cmake -D <var>=<value>`` whose name matches the template under the
|
||||
// lexical classes defined below and for which no exact-match entry exists
|
||||
// in ``cmCacheDocumentationTable``.
|
||||
//
|
||||
// The pattern table is consulted only on the miss path of the exact-match
|
||||
// ``cmCacheDocumentationTable::Get`` lookup; exact entries always win.
|
||||
//
|
||||
// Maintenance discipline:
|
||||
// * Adding a new pattern: hand-write one entry below in the canonical
|
||||
// ordering ``(numPlaceholders ASC, totalLiteralLen DESC, Pattern ASC)``
|
||||
// and make sure that, with ``<`` and ``>`` stripped, the pattern
|
||||
// names an existing ``Help/variable/<NAME>.rst`` file. The
|
||||
// ``testPatternTableOrdered`` regression test in
|
||||
// ``Tests/CMakeLib`` verifies the canonical ordering; the
|
||||
// ``CacheVarHelpCoverage`` lint verifies the structural-parity
|
||||
// invariant.
|
||||
// * Per-language or per-configuration restrictions documented in the
|
||||
// corresponding ``.rst`` file must be reproduced in the Summary
|
||||
// prose (the matcher is intentionally permissive; restrictions live
|
||||
// in the tooltip).
|
||||
// * Summaries must be single-line printable ASCII, no embedded
|
||||
// double quotes, no embedded newlines, and ``<= 200`` characters
|
||||
// (so that ``cmake-gui`` / ``ccmake`` render them legibly). The
|
||||
// ``testPatternTableFieldsValid`` regression test enforces all of
|
||||
// these.
|
||||
//
|
||||
// Matcher semantics: lazy + lookahead-anchored, single pass, no
|
||||
// backtracking. For each placeholder, the matcher consumes the minimum
|
||||
// class-valid prefix of the input that lets the next literal anchor
|
||||
// match at the cursor. The fixed-length classes ``<NNNN>`` and
|
||||
// ``<n>`` consume exactly four or one ASCII digits respectively.
|
||||
// Full-input consumption is required at the end. First fully-matching
|
||||
// entry in ``kPatterns[]`` wins.
|
||||
|
||||
#include "cmCachePatternTable.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
|
||||
#include <cm/string_view>
|
||||
#include <cmext/string_view>
|
||||
|
||||
#include "cmCacheDocumentationTable.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using cmCachePatternTable::Entry;
|
||||
|
||||
// The Entry layout below (two lines per row, ``{ "PATTERN",\n "summary"
|
||||
// },``) is intentional: it keeps the table easy to diff, review, and hand-edit
|
||||
// against the corresponding Help/variable/*.rst manuals. clang-format is
|
||||
// suppressed across the array so contributors can update one Summary
|
||||
// without the formatter reflowing every neighbor.
|
||||
//
|
||||
// Section headers ``// === N-placeholder, ... (K-literal-char bucket) ===``
|
||||
// are organizational signposts that mirror the canonical ordering invariant
|
||||
// enforced by ``testPatternTableOrdered``:
|
||||
//
|
||||
// (numPlaceholders ASC, totalLiteralLen DESC, Pattern ASC)
|
||||
//
|
||||
// where ``totalLiteralLen`` is the byte count of the pattern after every
|
||||
// ``<...>`` placeholder has been stripped. Examples:
|
||||
//
|
||||
// ``CMAKE_<LANG>_COMPILER_LAUNCHER`` -> ``CMAKE__COMPILER_LAUNCHER`` (24)
|
||||
// ``CMAKE_<LANG>_CLANG_TIDY`` -> ``CMAKE__CLANG_TIDY`` (17)
|
||||
// ``CMAKE_<LANG>_FLAGS`` -> ``CMAKE__FLAGS`` (12)
|
||||
//
|
||||
// Ordering literals DESC within a placeholder-count band is what makes
|
||||
// ``Match()``'s first-match-wins linear scan correct: a more-anchored
|
||||
// pattern (e.g. ``CMAKE_<LANG>_FLAGS_<CONFIG>_INIT``, literal=18) must
|
||||
// shadow a less-anchored one (``CMAKE_<LANG>_FLAGS_<CONFIG>``, literal=13)
|
||||
// so a lookup of ``CMAKE_CXX_FLAGS_DEBUG_INIT`` resolves to the former
|
||||
// rather than lazily binding ``CONFIG`` to ``DEBUG_INIT`` against the
|
||||
// latter. Contributors adding a new entry: place it in the bucket whose
|
||||
// literal-count matches yours, and update or add a new ``=== ... ===``
|
||||
// header if your literal-count is novel. The unit test catches mistakes.
|
||||
/* clang-format off */
|
||||
Entry const kPatterns[] = {
|
||||
|
||||
// === 1-placeholder, (37-literal-char bucket) ===
|
||||
{ "CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>"_s,
|
||||
"Default framework filename postfix under configuration <CONFIG>."_s },
|
||||
|
||||
// === 1-placeholder, (35-literal-char bucket) ===
|
||||
{ "CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG>"_s,
|
||||
"Initializes COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG> target property."_s },
|
||||
{ "CMAKE_INTERPROCEDURAL_OPTIMIZATION_<CONFIG>"_s,
|
||||
"Initializes INTERPROCEDURAL_OPTIMIZATION_<CONFIG> target property."_s },
|
||||
{ "CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED"_s,
|
||||
"Set to TRUE if <FEATURE> is supported regardless of linker language."_s },
|
||||
|
||||
// === 1-placeholder, (34-literal-char bucket) ===
|
||||
{ "CMAKE_<LANG>_CLANG_TIDY_EXPORT_FIXES_DIR"_s,
|
||||
"Default value for the <LANG>_CLANG_TIDY_EXPORT_FIXES_DIR target property; directory where clang-tidy writes suggested fix .yaml files. Applies only when <LANG> is C, CXX, OBJC, or OBJCXX."_s },
|
||||
|
||||
// === 1-placeholder, (33-literal-char bucket) ===
|
||||
{ "CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED"_s,
|
||||
"Specifies if <FEATURE> is supported regardless of link language."_s },
|
||||
|
||||
// === 1-placeholder, (31-literal-char bucket) ===
|
||||
{ "CMAKE_ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>"_s,
|
||||
"Initializes ARCHIVE_OUTPUT_DIRECTORY_<CONFIG> target property."_s },
|
||||
{ "CMAKE_LIBRARY_OUTPUT_DIRECTORY_<CONFIG>"_s,
|
||||
"Initializes LIBRARY_OUTPUT_DIRECTORY_<CONFIG> target property."_s },
|
||||
{ "CMAKE_RUNTIME_OUTPUT_DIRECTORY_<CONFIG>"_s,
|
||||
"Initializes RUNTIME_OUTPUT_DIRECTORY_<CONFIG> target property."_s },
|
||||
{ "CMAKE_USER_MAKE_RULES_OVERRIDE_<LANG>"_s,
|
||||
"Specify a CMake file that overrides platform information for <LANG>"_s },
|
||||
|
||||
// === 1-placeholder, (30-literal-char bucket) ===
|
||||
{ "CMAKE_LINK_LIBRARY_<FEATURE>_ATTRIBUTES"_s,
|
||||
"Defines behavior and attributes of the specified link library <FEATURE>."_s },
|
||||
|
||||
// === 1-placeholder, (29-literal-char bucket) ===
|
||||
{ "CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE"_s,
|
||||
"Path to a CMake language file included as the first step of any project() command call matching <PROJECT-NAME>. Intended for injecting custom code into project builds without modifying the source."_s },
|
||||
|
||||
// === 1-placeholder, (27-literal-char bucket) ===
|
||||
{ "CMAKE_<LANG>_INCLUDE_WHAT_YOU_USE"_s,
|
||||
"Default value for the <LANG>_INCLUDE_WHAT_YOU_USE target property; names an include-what-you-use command (and arguments) run alongside compilation. Applies only when <LANG> is C or CXX."_s },
|
||||
{ "CMAKE_DISABLE_FIND_PACKAGE_<PackageName>"_s,
|
||||
"Set to TRUE to disable calls to find_package(<PackageName>); the call returns as if the package were not found, even when REQUIRED was specified."_s },
|
||||
{ "CMAKE_PDB_OUTPUT_DIRECTORY_<CONFIG>"_s,
|
||||
"Initializes PDB_OUTPUT_DIRECTORY_<CONFIG> target property."_s },
|
||||
{ "CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>"_s,
|
||||
"Set to TRUE to make every call to find_package(<PackageName>) behave as if REQUIRED were specified, causing CMake to fail when the package is not found."_s },
|
||||
|
||||
// === 1-placeholder, (26-literal-char bucket) ===
|
||||
{ "CMAKE_MAP_IMPORTED_CONFIG_<CONFIG>"_s,
|
||||
"Initializes MAP_IMPORTED_CONFIG_<CONFIG> target property."_s },
|
||||
{ "CMAKE_MODULE_LINKER_FLAGS_<CONFIG>"_s,
|
||||
"Flags used by the linker when creating a module library for the <CONFIG> configuration. Appended after the configuration-independent CMAKE_MODULE_LINKER_FLAGS."_s },
|
||||
{ "CMAKE_SHARED_LINKER_FLAGS_<CONFIG>"_s,
|
||||
"Flags used by the linker when creating a shared library for the <CONFIG> configuration. Appended after the configuration-independent CMAKE_SHARED_LINKER_FLAGS."_s },
|
||||
{ "CMAKE_STATIC_LINKER_FLAGS_<CONFIG>"_s,
|
||||
"Flags used by the static-library archiver when creating a static library for the <CONFIG> configuration. Appended after the configuration-independent CMAKE_STATIC_LINKER_FLAGS."_s },
|
||||
|
||||
// === 1-placeholder, (25-literal-char bucket) ===
|
||||
{ "CMAKE_LINK_LIBRARY_USING_<FEATURE>"_s,
|
||||
"Defines how to link a library for <FEATURE>."_s },
|
||||
|
||||
// === 1-placeholder, (24-literal-char bucket) ===
|
||||
{ "CMAKE_<LANG>_COMPILER_LAUNCHER"_s,
|
||||
"Default value for the <LANG>_COMPILER_LAUNCHER target property; launcher tool prepended to every <LANG> compile command. Applies only when <LANG> is C, CXX, Fortran, HIP, ISPC, OBJC, OBJCXX, or CUDA."_s },
|
||||
{ "CMAKE_<LANG>_STANDARD_REQUIRED"_s,
|
||||
"Default value for the <LANG>_STANDARD_REQUIRED target property when a target is created. If TRUE, the requested language standard must be supported by the compiler."_s },
|
||||
{ "CMAKE_<LANG>_VISIBILITY_PRESET"_s,
|
||||
"Default value for the <LANG>_VISIBILITY_PRESET target property when a target is created. Controls the default symbol visibility (default, hidden, protected, internal) for <LANG> code."_s },
|
||||
{ "CMAKE_POLICY_DEFAULT_CMP<NNNN>"_s,
|
||||
"Default for CMake Policy CMP<NNNN> when otherwise left unset. Set to OLD or NEW to externally control the policy for projects that have not set it via cmake_minimum_required or cmake_policy."_s },
|
||||
{ "CMAKE_POLICY_WARNING_CMP<NNNN>"_s,
|
||||
"Explicitly enable or disable the warning when CMake Policy CMP<NNNN> has not been set explicitly. Meaningful only for the policies that do not warn by default."_s },
|
||||
|
||||
// === 1-placeholder, (23-literal-char bucket) ===
|
||||
{ "CMAKE_EXE_LINKER_FLAGS_<CONFIG>"_s,
|
||||
"Flags used by the linker when creating an executable for the <CONFIG> configuration. Appended after the configuration-independent CMAKE_EXE_LINKER_FLAGS."_s },
|
||||
{ "CMAKE_LINK_GROUP_USING_<FEATURE>"_s,
|
||||
"Defines how to link a group of libraries for <FEATURE>."_s },
|
||||
|
||||
// === 1-placeholder, (22-literal-char bucket) ===
|
||||
{ "CMAKE_<LANG>_LINKER_LAUNCHER"_s,
|
||||
"Default value for the <LANG>_LINKER_LAUNCHER target property; names a launcher tool prepended to every <LANG> link command. Applies only when <LANG> is C, CXX, OBJC, OBJCXX, or CUDA."_s },
|
||||
{ "CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE"_s,
|
||||
"Path to a CMake language file included as the last step of any project() command call matching <PROJECT-NAME>. Intended for injecting custom code without modifying the project source."_s },
|
||||
{ "CMAKE_XCODE_ATTRIBUTE_<an-attribute>"_s,
|
||||
"Tells the Xcode generator to set <an-attribute> to the given value in the generated Xcode project. Ignored on other generators. Low-level escape hatch for Xcode-specific settings."_s },
|
||||
|
||||
// === 1-placeholder, (20-literal-char bucket) ===
|
||||
{ "CMAKE_<LANG>_HOST_COMPILER"_s,
|
||||
"Host compiler executable for CUDA or HIP code compilation"_s },
|
||||
|
||||
// === 1-placeholder, (17-literal-char bucket) ===
|
||||
{ "CMAKE_<LANG>_CLANG_TIDY"_s,
|
||||
"Default value for the <LANG>_CLANG_TIDY target property; names a clang-tidy command (with arguments) run alongside compilation. Applies only when <LANG> is C, CXX, OBJC, or OBJCXX."_s },
|
||||
{ "CMAKE_<LANG>_EXTENSIONS"_s,
|
||||
"Default value for the <LANG>_EXTENSIONS target property when a target is created. Controls whether compiler-specific extensions to the language standard are enabled."_s },
|
||||
{ "CMAKE_<LANG>_FLAGS_INIT"_s,
|
||||
"Toolchain-file hook initializing CMAKE_<LANG>_FLAGS the first time the build tree is configured for <LANG>. Set in toolchain or platform files; user projects should set CMAKE_<LANG>_FLAGS instead."_s },
|
||||
{ "CMAKE_<LANG>_LINK_FLAGS"_s,
|
||||
"Language-wide flags for <LANG> used when linking for all configurations. Passed to every compiler invocation that drives linking. Per-config CMAKE_<LANG>_LINK_FLAGS_<CONFIG> are appended on top."_s },
|
||||
{ "CMAKE_<LANG>_PVS_STUDIO"_s,
|
||||
"Default value for the <LANG>_PVS_STUDIO target property; names a pvs-studio-analyzer command (with arguments) run alongside compilation. Applies only when <LANG> is C or CXX."_s },
|
||||
|
||||
// === 1-placeholder, (15-literal-char bucket) ===
|
||||
{ "CMAKE_<LANG>_COMPILER"_s,
|
||||
"Full path to the compiler used for language <LANG>. Set by CMake during compiler detection on the first configure; users may override on the command line to select a specific toolchain."_s },
|
||||
{ "CMAKE_<LANG>_CPPCHECK"_s,
|
||||
"Default value for the <LANG>_CPPCHECK target property; names a cppcheck command (with arguments) run alongside compilation. Applies only when <LANG> is C or CXX."_s },
|
||||
{ "CMAKE_<LANG>_STANDARD"_s,
|
||||
"Default value for the <LANG>_STANDARD target property when a target is created. Applies to <LANG> = C, CXX, CUDA, HIP, OBJC, OBJCXX. See cmake-compile-features(7)."_s },
|
||||
|
||||
// === 1-placeholder, (14-literal-char bucket) ===
|
||||
{ "CMAKE_<CONFIG>_POSTFIX"_s,
|
||||
"Default filename postfix for libraries under configuration <CONFIG>."_s },
|
||||
{ "CMAKE_<LANG>_CPPLINT"_s,
|
||||
"Default value for the <LANG>_CPPLINT target property; names a cpplint command (with arguments) run alongside compilation. Applies only when <LANG> is C or CXX."_s },
|
||||
|
||||
// === 1-placeholder, (13-literal-char bucket) ===
|
||||
{ "CMAKE_<LANG>_ICSTAT"_s,
|
||||
"Default value for the <LANG>_ICSTAT target property; names an icstat static-analysis command (with arguments) run alongside compilation. Applies only when <LANG> is C or CXX."_s },
|
||||
|
||||
// === 1-placeholder, (12-literal-char bucket) ===
|
||||
{ "CMAKE_<LANG>_FLAGS"_s,
|
||||
"Language-wide compiler flags for <LANG>. Initialized from the language-specific environment variable (CFLAGS, CXXFLAGS, FFLAGS, etc.) the first time the language is enabled."_s },
|
||||
{ "CMAKE_MATCH_<n>"_s,
|
||||
"Capture group <n> matched by the most recent regular expression (groups 0 through 9). Group 0 is the entire match; groups 1 through 9 are the parenthesized subexpressions."_s },
|
||||
|
||||
// === 1-placeholder, (11-literal-char bucket) ===
|
||||
{ "<PROJECT-NAME>_BINARY_DIR"_s,
|
||||
"Top-level binary directory for the named project. Created by the project() command with the given <PROJECT-NAME>; useful when add_subdirectory is used to connect several projects."_s },
|
||||
{ "<PROJECT-NAME>_SOURCE_DIR"_s,
|
||||
"Top-level source directory for the named project. Created by the project() command with the given <PROJECT-NAME>; useful when add_subdirectory is used to connect several projects."_s },
|
||||
|
||||
// === 1-placeholder, (8-literal-char bucket) ===
|
||||
{ "<PROJECT-NAME>_VERSION"_s,
|
||||
"Value given to the VERSION option of the most recent project() command with project name <PROJECT-NAME>, if any. Component values live in <PROJECT-NAME>_VERSION_{MAJOR,MINOR,PATCH,TWEAK}."_s },
|
||||
|
||||
// === 1-placeholder, (5-literal-char bucket) ===
|
||||
{ "<PackageName>_ROOT"_s,
|
||||
"Initial search prefix(es) for find_package(<PackageName>); covers both the mixed-case form (CMP0074, e.g. Foo_ROOT) and the upper-case form (CMP0144, e.g. FOO_ROOT)."_s },
|
||||
|
||||
// === 2-placeholder, (36-literal-char bucket) ===
|
||||
{ "CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED"_s,
|
||||
"Set to TRUE if <FEATURE> is supported for linker language <LANG>."_s },
|
||||
|
||||
// === 2-placeholder, (34-literal-char bucket) ===
|
||||
{ "CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED"_s,
|
||||
"Specifies if <FEATURE> is supported for link language <LANG>."_s },
|
||||
|
||||
// === 2-placeholder, (31-literal-char bucket) ===
|
||||
{ "CMAKE_<LANG>_LINK_LIBRARY_<FEATURE>_ATTRIBUTES"_s,
|
||||
"Defines semantics of link library <FEATURE> for language <LANG>."_s },
|
||||
|
||||
// === 2-placeholder, (26-literal-char bucket) ===
|
||||
{ "CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>"_s,
|
||||
"Defines how to link a library for <FEATURE>."_s },
|
||||
|
||||
// === 2-placeholder, (24-literal-char bucket) ===
|
||||
{ "CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>"_s,
|
||||
"Defines how to link a group of libraries for <FEATURE>."_s },
|
||||
|
||||
// === 2-placeholder, (20-literal-char bucket) ===
|
||||
{ "CMAKE_<LANG>_USING_LINKER_<TYPE>"_s,
|
||||
"Defines how to specify the <TYPE> linker for the link step."_s },
|
||||
|
||||
// === 2-placeholder, (18-literal-char bucket) ===
|
||||
{ "CMAKE_<LANG>_FLAGS_<CONFIG>_INIT"_s,
|
||||
"Toolchain-file hook initializing CMAKE_<LANG>_FLAGS_<CONFIG> the first time the build tree is configured for language <LANG>. Intended for toolchain or platform files."_s },
|
||||
{ "CMAKE_<LANG>_LINK_FLAGS_<CONFIG>"_s,
|
||||
"Language-wide flags for <LANG> used when linking for the <CONFIG> configuration. Passed to every compiler invocation that drives linking. Appended after CMAKE_<LANG>_LINK_FLAGS."_s },
|
||||
|
||||
// === 2-placeholder, (13-literal-char bucket) ===
|
||||
{ "CMAKE_<LANG>_FLAGS_<CONFIG>"_s,
|
||||
"Language-wide flags for <LANG> used when building for the <CONFIG> configuration. Appended after CMAKE_<LANG>_FLAGS on both compile and link invocations."_s },
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Character classes used by the matcher.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
constexpr bool IsAsciiAlpha(char c)
|
||||
{
|
||||
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
|
||||
}
|
||||
|
||||
constexpr bool IsAsciiDigit(char c)
|
||||
{
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
|
||||
// Identifier: ``[A-Za-z][A-Za-z0-9_]*`` -- start vs. continuation.
|
||||
constexpr bool IsIdentStart(char c)
|
||||
{
|
||||
return IsAsciiAlpha(c);
|
||||
}
|
||||
constexpr bool IsIdentCont(char c)
|
||||
{
|
||||
return IsAsciiAlpha(c) || IsAsciiDigit(c) || c == '_';
|
||||
}
|
||||
|
||||
// Identifier-with-hyphen: ``[A-Za-z][A-Za-z0-9_-]*`` -- start vs.
|
||||
// continuation.
|
||||
constexpr bool IsIdentHyphenStart(char c)
|
||||
{
|
||||
return IsAsciiAlpha(c);
|
||||
}
|
||||
constexpr bool IsIdentHyphenCont(char c)
|
||||
{
|
||||
return IsAsciiAlpha(c) || IsAsciiDigit(c) || c == '_' || c == '-';
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Placeholder dispatch.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
enum class PlaceholderClass
|
||||
{
|
||||
Ident, // <LANG>, <CONFIG>, <PackageName>
|
||||
IdentHyphen, // <PROJECT-NAME>, <an-attribute>
|
||||
FourDigit, // <NNNN>
|
||||
OneDigit, // <n>
|
||||
Unknown, // malformed pattern entry
|
||||
};
|
||||
|
||||
PlaceholderClass ClassOf(cm::string_view placeholder)
|
||||
{
|
||||
// ``placeholder`` includes the surrounding angle brackets, e.g. "<LANG>".
|
||||
// ``<FEATURE>`` and ``<TYPE>`` are documented as identifiers by their
|
||||
// RSTs (e.g. WEAK / WHOLE_ARCHIVE for FEATURE in
|
||||
// Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.rst and LLD / MOLD
|
||||
// for TYPE in Help/variable/CMAKE_LANG_USING_LINKER_TYPE.rst), so they
|
||||
// share the ``Ident`` lexical class with <LANG>/<CONFIG>/<PackageName>.
|
||||
// Without this clause the eleven pattern entries that use these two
|
||||
// placeholders would never match any input (regression guarded by
|
||||
// testEveryPatternReachable in Tests/CMakeLib).
|
||||
if (placeholder == "<LANG>" || placeholder == "<CONFIG>" ||
|
||||
placeholder == "<PackageName>" || placeholder == "<FEATURE>" ||
|
||||
placeholder == "<TYPE>") {
|
||||
return PlaceholderClass::Ident;
|
||||
}
|
||||
if (placeholder == "<PROJECT-NAME>" || placeholder == "<an-attribute>") {
|
||||
return PlaceholderClass::IdentHyphen;
|
||||
}
|
||||
if (placeholder == "<NNNN>") {
|
||||
return PlaceholderClass::FourDigit;
|
||||
}
|
||||
if (placeholder == "<n>") {
|
||||
return PlaceholderClass::OneDigit;
|
||||
}
|
||||
return PlaceholderClass::Unknown;
|
||||
}
|
||||
|
||||
bool ClassAllowsStart(PlaceholderClass cls, char c)
|
||||
{
|
||||
switch (cls) {
|
||||
case PlaceholderClass::Ident:
|
||||
return IsIdentStart(c);
|
||||
case PlaceholderClass::IdentHyphen:
|
||||
return IsIdentHyphenStart(c);
|
||||
case PlaceholderClass::FourDigit:
|
||||
case PlaceholderClass::OneDigit:
|
||||
return IsAsciiDigit(c);
|
||||
case PlaceholderClass::Unknown:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ClassAllowsCont(PlaceholderClass cls, char c)
|
||||
{
|
||||
switch (cls) {
|
||||
case PlaceholderClass::Ident:
|
||||
return IsIdentCont(c);
|
||||
case PlaceholderClass::IdentHyphen:
|
||||
return IsIdentHyphenCont(c);
|
||||
case PlaceholderClass::FourDigit:
|
||||
case PlaceholderClass::OneDigit:
|
||||
return IsAsciiDigit(c);
|
||||
case PlaceholderClass::Unknown:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Helpers.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
bool LiteralMatches(cm::string_view input, std::size_t pos,
|
||||
cm::string_view literal)
|
||||
{
|
||||
return input.size() - pos >= literal.size() &&
|
||||
input.compare(pos, literal.size(), literal) == 0;
|
||||
}
|
||||
|
||||
// Try to match ``pattern`` against ``input`` end-to-end under the
|
||||
// lazy + lookahead-anchored semantics documented at the top of this file.
|
||||
// Returns true on full-consumption match; false otherwise.
|
||||
bool TryMatch(cm::string_view pattern, cm::string_view input)
|
||||
{
|
||||
std::size_t pi = 0;
|
||||
std::size_t ii = 0;
|
||||
|
||||
while (pi < pattern.size()) {
|
||||
if (pattern[pi] != '<') {
|
||||
// Literal segment: walk until next '<' or end of pattern.
|
||||
std::size_t literal_end = pi;
|
||||
while (literal_end < pattern.size() && pattern[literal_end] != '<') {
|
||||
++literal_end;
|
||||
}
|
||||
cm::string_view const lit = pattern.substr(pi, literal_end - pi);
|
||||
if (!LiteralMatches(input, ii, lit)) {
|
||||
return false;
|
||||
}
|
||||
pi = literal_end;
|
||||
ii += lit.size();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Placeholder segment: find the closing '>'.
|
||||
std::size_t const close = pattern.find('>', pi);
|
||||
if (close == cm::string_view::npos) {
|
||||
return false; // malformed pattern; matched by no input
|
||||
}
|
||||
cm::string_view const ph = pattern.substr(pi, close - pi + 1);
|
||||
PlaceholderClass const cls = ClassOf(ph);
|
||||
if (cls == PlaceholderClass::Unknown) {
|
||||
return false; // unknown placeholder class; rejected by unit test too
|
||||
}
|
||||
|
||||
// Locate the next anchor literal that follows this placeholder. An
|
||||
// empty anchor means the placeholder is the last segment in the
|
||||
// pattern (must consume to end-of-input) or that it is followed
|
||||
// immediately by another placeholder (adjacent placeholders are
|
||||
// forbidden -- testPatternTableFieldsValid rejects them at table
|
||||
// build time, so we treat the case defensively here).
|
||||
std::size_t const after_ph = close + 1;
|
||||
std::size_t anchor_end = after_ph;
|
||||
while (anchor_end < pattern.size() && pattern[anchor_end] != '<') {
|
||||
++anchor_end;
|
||||
}
|
||||
cm::string_view const anchor =
|
||||
pattern.substr(after_ph, anchor_end - after_ph);
|
||||
bool const consume_to_eoi =
|
||||
anchor.empty() && (anchor_end == pattern.size());
|
||||
if (anchor.empty() && !consume_to_eoi) {
|
||||
return false; // adjacent placeholders are not supported
|
||||
}
|
||||
|
||||
// Fixed-length classes consume exactly that many digits, then anchor.
|
||||
if (cls == PlaceholderClass::FourDigit ||
|
||||
cls == PlaceholderClass::OneDigit) {
|
||||
std::size_t const fixed_len =
|
||||
(cls == PlaceholderClass::FourDigit) ? 4u : 1u;
|
||||
if (input.size() - ii < fixed_len) {
|
||||
return false;
|
||||
}
|
||||
for (std::size_t k = 0; k < fixed_len; ++k) {
|
||||
if (!IsAsciiDigit(input[ii + k])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
std::size_t const cur = ii + fixed_len;
|
||||
if (consume_to_eoi) {
|
||||
if (cur != input.size()) {
|
||||
return false;
|
||||
}
|
||||
ii = cur;
|
||||
} else {
|
||||
if (!LiteralMatches(input, cur, anchor)) {
|
||||
return false;
|
||||
}
|
||||
ii = cur + anchor.size();
|
||||
}
|
||||
pi = anchor_end;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Variable-length classes: placeholder is non-empty; consume lazily,
|
||||
// stopping at the first cursor position where the anchor matches (or
|
||||
// at end-of-input when there is no trailing literal anchor).
|
||||
if (ii >= input.size()) {
|
||||
return false;
|
||||
}
|
||||
if (!ClassAllowsStart(cls, input[ii])) {
|
||||
return false;
|
||||
}
|
||||
std::size_t cur = ii + 1; // consumed first char
|
||||
if (consume_to_eoi) {
|
||||
while (cur < input.size()) {
|
||||
if (!ClassAllowsCont(cls, input[cur])) {
|
||||
return false;
|
||||
}
|
||||
++cur;
|
||||
}
|
||||
ii = cur;
|
||||
} else {
|
||||
while (true) {
|
||||
if (LiteralMatches(input, cur, anchor)) {
|
||||
break;
|
||||
}
|
||||
if (cur >= input.size()) {
|
||||
return false;
|
||||
}
|
||||
if (!ClassAllowsCont(cls, input[cur])) {
|
||||
return false;
|
||||
}
|
||||
++cur;
|
||||
}
|
||||
ii = cur + anchor.size();
|
||||
}
|
||||
pi = anchor_end;
|
||||
}
|
||||
|
||||
return ii == input.size();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
cmCacheDocumentationTable::LookupResult cmCachePatternTable::Match(
|
||||
cm::string_view varName)
|
||||
{
|
||||
for (auto const& entry : kPatterns) {
|
||||
if (TryMatch(entry.Pattern, varName)) {
|
||||
return { entry.Summary };
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
cmCachePatternTable::Entry const* cmCachePatternTable::EntriesBegin()
|
||||
{
|
||||
return std::begin(kPatterns);
|
||||
}
|
||||
|
||||
cmCachePatternTable::Entry const* cmCachePatternTable::EntriesEnd()
|
||||
{
|
||||
return std::end(kPatterns);
|
||||
}
|
||||
|
||||
std::size_t cmCachePatternTable::EntriesSize()
|
||||
{
|
||||
return static_cast<std::size_t>(std::end(kPatterns) - std::begin(kPatterns));
|
||||
}
|
||||
84
Source/cmCachePatternTable.h
Normal file
84
Source/cmCachePatternTable.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file LICENSE.rst or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <cm/string_view>
|
||||
|
||||
#include "cmCacheDocumentationTable.h"
|
||||
|
||||
/** \namespace cmCachePatternTable
|
||||
* \brief Compile-time pattern-matching fallback for built-in CMake cache
|
||||
* variable documentation.
|
||||
*
|
||||
* The pattern table is a hand-maintained list of placeholder-shaped
|
||||
* tooltips, e.g. ``CMAKE_<LANG>_FLAGS`` or
|
||||
* ``CMAKE_POLICY_DEFAULT_CMP<NNNN>``, that complement the exact-match
|
||||
* entries in ``cmCacheDocumentationTable``. It is consulted only on
|
||||
* the miss path: ``cmCacheDocumentationTable::Get`` first attempts an
|
||||
* exact-match lookup, then falls back to ``cmCachePatternTable::Match``
|
||||
* for names that follow a known template shape.
|
||||
*
|
||||
* Placeholder lexical classes recognized by the matcher (see
|
||||
* ``cmCachePatternTable.cxx`` for details):
|
||||
*
|
||||
* * ``<LANG>``, ``<CONFIG>``, ``<PackageName>``: identifier
|
||||
* (``[A-Za-z][A-Za-z0-9_]*``).
|
||||
* * ``<PROJECT-NAME>``, ``<an-attribute>``: identifier with
|
||||
* hyphens (``[A-Za-z][A-Za-z0-9_-]*``).
|
||||
* * ``<NNNN>``: exactly 4 ASCII digits (``[0-9]{4}``).
|
||||
* * ``<n>``: exactly 1 ASCII digit (``[0-9]``).
|
||||
*
|
||||
* Matching is leftmost-anchor, lazy on each placeholder, with full
|
||||
* input consumption required at the end. The matcher is intentionally
|
||||
* permissive: per-language or per-configuration restrictions documented
|
||||
* in the corresponding ``Help/variable/<NAME>.rst`` file are reproduced
|
||||
* in the entry's Summary prose, not enforced by the matcher. First
|
||||
* fully-matching entry in ``kPatterns[]`` wins; entries are kept in
|
||||
* ``(numPlaceholders ASC, totalLiteralLen DESC, Pattern ASC)`` order so
|
||||
* that more-specific patterns are tried before less specific ones.
|
||||
*/
|
||||
namespace cmCachePatternTable {
|
||||
|
||||
/** \brief A single row in the pattern documentation table.
|
||||
*
|
||||
* The ``Pattern`` and ``Summary`` views reference storage with static
|
||||
* lifetime. ``Pattern`` is a literal template string containing one or
|
||||
* more angle-bracketed placeholders such as ``<LANG>`` or ``<NNNN>``.
|
||||
*/
|
||||
struct Entry
|
||||
{
|
||||
cm::string_view Pattern;
|
||||
cm::string_view Summary;
|
||||
};
|
||||
|
||||
/** \brief Look up the built-in documentation for \a varName by pattern.
|
||||
*
|
||||
* Walks ``kPatterns[]`` in declaration order and returns the first
|
||||
* entry whose ``Pattern`` template fully matches \a varName under the
|
||||
* lexical classes above. On miss returns an empty ``Summary``.
|
||||
* Performs no allocation; runs in ``O(N * |varName|)`` for the small
|
||||
* (~30) table.
|
||||
*
|
||||
* The result type is reused from ``cmCacheDocumentationTable`` so that
|
||||
* the single call site in ``cmCacheDocumentationTable::Get`` can return
|
||||
* either an exact-match or a pattern-match result without translation.
|
||||
*/
|
||||
cmCacheDocumentationTable::LookupResult Match(cm::string_view varName);
|
||||
|
||||
/** \brief Iterate the underlying pattern table.
|
||||
*
|
||||
* Exposed for the ``testCacheDocumentationTable`` unit test in
|
||||
* ``Tests/CMakeLib``, which verifies that the entries are well-formed
|
||||
* and obey the canonical ordering rule. Callers should not rely on a
|
||||
* particular entry count or ordering beyond what the unit test
|
||||
* asserts.
|
||||
*/
|
||||
Entry const* EntriesBegin();
|
||||
Entry const* EntriesEnd();
|
||||
std::size_t EntriesSize();
|
||||
|
||||
}
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "cmBuildOptions.h"
|
||||
#include "cmCMakePath.h"
|
||||
#include "cmCMakePresetsGraph.h"
|
||||
#include "cmCacheDocumentationTable.h"
|
||||
#include "cmCommandLineArgument.h"
|
||||
#include "cmCommands.h"
|
||||
#include "cmDocumentation.h"
|
||||
@@ -850,8 +851,12 @@ void cmake::ProcessCacheArg(std::string const& var, std::string const& value,
|
||||
"Use -W[no-]error=deprecated instead.\n"_s;
|
||||
}
|
||||
|
||||
this->AddCacheEntry(
|
||||
var, value, "No help, variable specified on the command line.", type);
|
||||
auto const builtIn = cmCacheDocumentationTable::Get(var);
|
||||
std::string const helpString = builtIn.Summary.empty()
|
||||
? std::string("No help, variable specified on the command line.")
|
||||
: std::string(builtIn.Summary);
|
||||
|
||||
this->AddCacheEntry(var, value, helpString, type);
|
||||
|
||||
if (warnUnusedCli != cmDiagnostics::Ignore) {
|
||||
if (!haveValue ||
|
||||
|
||||
@@ -4,6 +4,7 @@ configure_file(testConfig.h.in testConfig.h @ONLY)
|
||||
set(CMakeLib_TESTS
|
||||
testAssert.cxx
|
||||
testArgumentParser.cxx
|
||||
testCacheDocumentationTable.cxx
|
||||
testCTestBinPacker.cxx
|
||||
testCTestResourceAllocator.cxx
|
||||
testCTestResourceSpec.cxx
|
||||
|
||||
496
Tests/CMakeLib/testCacheDocumentationTable.cxx
Normal file
496
Tests/CMakeLib/testCacheDocumentationTable.cxx
Normal file
@@ -0,0 +1,496 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file LICENSE.rst or https://cmake.org/licensing for details. */
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
#include <cm/string_view>
|
||||
|
||||
#include "cmCacheDocumentationTable.h"
|
||||
#include "cmCachePatternTable.h"
|
||||
|
||||
#include "testCommon.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// The table is consulted by cmake::ProcessCacheArg via a binary search
|
||||
// (std::lower_bound). That requires the entries to be sorted strictly
|
||||
// ascending by Name in byte-wise (ASCII) order. These tests are the
|
||||
// regression guard for that invariant against future hand-edits.
|
||||
|
||||
bool testNonEmpty()
|
||||
{
|
||||
ASSERT_TRUE(cmCacheDocumentationTable::EntriesSize() > 0);
|
||||
ASSERT_TRUE(cmCacheDocumentationTable::EntriesBegin() !=
|
||||
cmCacheDocumentationTable::EntriesEnd());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testSortedAndUnique()
|
||||
{
|
||||
auto const* const first = cmCacheDocumentationTable::EntriesBegin();
|
||||
auto const* const last = cmCacheDocumentationTable::EntriesEnd();
|
||||
for (auto const* it = first; it != last; ++it) {
|
||||
if (it == first) {
|
||||
continue;
|
||||
}
|
||||
auto const& prev = *(it - 1);
|
||||
auto const& curr = *it;
|
||||
if (!(prev.Name < curr.Name)) {
|
||||
std::cout << "Entries are not strictly ascending: '" << prev.Name
|
||||
<< "' is followed by '" << curr.Name << "' at index "
|
||||
<< static_cast<std::size_t>(it - first) << '\n';
|
||||
if (prev.Name == curr.Name) {
|
||||
std::cout << " (duplicate Name)\n";
|
||||
} else {
|
||||
std::cout << " (out-of-order Name)\n";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testNonEmptyFields()
|
||||
{
|
||||
for (auto const* it = cmCacheDocumentationTable::EntriesBegin();
|
||||
it != cmCacheDocumentationTable::EntriesEnd(); ++it) {
|
||||
if (it->Name.empty()) {
|
||||
std::cout << "Empty Name at index "
|
||||
<< static_cast<std::size_t>(
|
||||
it - cmCacheDocumentationTable::EntriesBegin())
|
||||
<< '\n';
|
||||
return false;
|
||||
}
|
||||
if (it->Summary.empty()) {
|
||||
std::cout << "Empty Summary for entry '" << it->Name << "'\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testNameCharacters()
|
||||
{
|
||||
// Names must be printable ASCII without whitespace. Anything else
|
||||
// would either be a copy/paste mishap or would cause std::lower_bound
|
||||
// to behave in surprising ways relative to user input.
|
||||
for (auto const* it = cmCacheDocumentationTable::EntriesBegin();
|
||||
it != cmCacheDocumentationTable::EntriesEnd(); ++it) {
|
||||
for (char const c : it->Name) {
|
||||
auto const u = static_cast<unsigned char>(c);
|
||||
if (u <= 0x20 || u >= 0x7f) {
|
||||
std::cout << "Entry '" << it->Name
|
||||
<< "' contains a non-printable or whitespace character\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testSummaryIsSingleLine()
|
||||
{
|
||||
// Summaries are rendered as one-line tooltips in cmake-gui / ccmake.
|
||||
// Embedded newlines or carriage returns break that rendering.
|
||||
for (auto const* it = cmCacheDocumentationTable::EntriesBegin();
|
||||
it != cmCacheDocumentationTable::EntriesEnd(); ++it) {
|
||||
for (char const c : it->Summary) {
|
||||
if (c == '\n' || c == '\r') {
|
||||
std::cout << "Summary for entry '" << it->Name
|
||||
<< "' contains an embedded newline or carriage return\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testGetRoundTrip()
|
||||
{
|
||||
// For every entry in the table, Get(Name) must return the same Summary.
|
||||
// This catches a regression where the binary-search predicate or the
|
||||
// sort invariant silently drifts apart.
|
||||
for (auto const* it = cmCacheDocumentationTable::EntriesBegin();
|
||||
it != cmCacheDocumentationTable::EntriesEnd(); ++it) {
|
||||
auto const got = cmCacheDocumentationTable::Get(it->Name);
|
||||
if (got.Summary != it->Summary) {
|
||||
std::cout << "Get(\"" << it->Name
|
||||
<< "\").Summary did not round-trip to the table's Summary\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// And an obviously-unknown key must return the sentinel.
|
||||
auto const missing = cmCacheDocumentationTable::Get(
|
||||
cm::string_view("__definitely_not_a_cmake_variable__"));
|
||||
if (!missing.Summary.empty()) {
|
||||
std::cout << "Get() returned a non-empty Summary for an unknown key\n";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Pattern table tests.
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// The pattern table is consulted by cmCacheDocumentationTable::Get on the
|
||||
// exact-match miss path. The tests below pin down its structural
|
||||
// invariants and the most important matcher behaviors (lazy
|
||||
// lookahead-anchored matching, fixed-length digit classes, exact wins over
|
||||
// pattern, permissive matching with restriction-in-prose).
|
||||
|
||||
// Count the angle-bracketed placeholders in a pattern string. A
|
||||
// placeholder is the inclusive run from a ``<`` to the next ``>``.
|
||||
std::size_t CountPlaceholders(cm::string_view pattern)
|
||||
{
|
||||
std::size_t n = 0;
|
||||
for (std::size_t i = 0; i < pattern.size(); ++i) {
|
||||
if (pattern[i] == '<') {
|
||||
++n;
|
||||
auto const close = pattern.find('>', i);
|
||||
if (close == cm::string_view::npos) {
|
||||
return n; // malformed; let testPatternTableFieldsValid flag it
|
||||
}
|
||||
i = close;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
// Total length of the literal (non-placeholder) characters in a pattern.
|
||||
std::size_t LiteralLength(cm::string_view pattern)
|
||||
{
|
||||
std::size_t total = 0;
|
||||
for (std::size_t i = 0; i < pattern.size(); ++i) {
|
||||
if (pattern[i] == '<') {
|
||||
auto const close = pattern.find('>', i);
|
||||
if (close == cm::string_view::npos) {
|
||||
break;
|
||||
}
|
||||
i = close;
|
||||
continue;
|
||||
}
|
||||
++total;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
bool testPatternTableNonEmpty()
|
||||
{
|
||||
ASSERT_TRUE(cmCachePatternTable::EntriesSize() > 0);
|
||||
ASSERT_TRUE(cmCachePatternTable::EntriesBegin() !=
|
||||
cmCachePatternTable::EntriesEnd());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testPatternTableFieldsValid()
|
||||
{
|
||||
// Per-entry invariants: non-empty Pattern and Summary, at least one
|
||||
// placeholder, single-line printable ASCII Summary of bounded length,
|
||||
// and (a stricter rule derived from the matcher design) no two adjacent
|
||||
// placeholders with no separating literal -- the matcher's
|
||||
// lookahead-anchored semantics require a literal anchor between
|
||||
// placeholders to be unambiguous.
|
||||
for (auto const* it = cmCachePatternTable::EntriesBegin();
|
||||
it != cmCachePatternTable::EntriesEnd(); ++it) {
|
||||
if (it->Pattern.empty()) {
|
||||
std::cout << "Empty Pattern at index "
|
||||
<< static_cast<std::size_t>(
|
||||
it - cmCachePatternTable::EntriesBegin())
|
||||
<< '\n';
|
||||
return false;
|
||||
}
|
||||
if (it->Summary.empty()) {
|
||||
std::cout << "Empty Summary for pattern '" << it->Pattern << "'\n";
|
||||
return false;
|
||||
}
|
||||
if (CountPlaceholders(it->Pattern) == 0) {
|
||||
std::cout << "Pattern '" << it->Pattern
|
||||
<< "' has no <...> placeholder; "
|
||||
"use cmCacheDocumentationTable for exact-match entries\n";
|
||||
return false;
|
||||
}
|
||||
if (it->Summary.size() > 200) {
|
||||
std::cout << "Summary for pattern '" << it->Pattern
|
||||
<< "' exceeds the 200-character tooltip limit\n";
|
||||
return false;
|
||||
}
|
||||
for (char const c : it->Summary) {
|
||||
auto const u = static_cast<unsigned char>(c);
|
||||
if (u < 0x20 || u >= 0x7f) {
|
||||
std::cout << "Summary for pattern '" << it->Pattern
|
||||
<< "' contains a non-printable or non-ASCII character\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Adjacent placeholders are forbidden (matcher cannot disambiguate
|
||||
// them without a separating literal anchor). Look for ``><``.
|
||||
for (std::size_t i = 1; i < it->Pattern.size(); ++i) {
|
||||
if (it->Pattern[i] == '<' && it->Pattern[i - 1] == '>') {
|
||||
std::cout << "Pattern '" << it->Pattern
|
||||
<< "' contains adjacent placeholders; insert a literal "
|
||||
"separator between them\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testPatternTableOrdered()
|
||||
{
|
||||
// kPatterns[] must obey ``(numPlaceholders ASC, totalLiteralLen DESC,
|
||||
// Pattern ASC)``. This determinism guarantees that a contributor
|
||||
// re-ordering the array cannot silently flip which of several equally
|
||||
// valid pattern matches wins for a given input.
|
||||
auto const* const first = cmCachePatternTable::EntriesBegin();
|
||||
auto const* const last = cmCachePatternTable::EntriesEnd();
|
||||
for (auto const* it = first; it != last; ++it) {
|
||||
if (it == first) {
|
||||
continue;
|
||||
}
|
||||
auto const& prev = *(it - 1);
|
||||
auto const& curr = *it;
|
||||
auto const np_prev = CountPlaceholders(prev.Pattern);
|
||||
auto const np_curr = CountPlaceholders(curr.Pattern);
|
||||
auto const ll_prev = LiteralLength(prev.Pattern);
|
||||
auto const ll_curr = LiteralLength(curr.Pattern);
|
||||
bool ordered;
|
||||
if (np_prev != np_curr) {
|
||||
ordered = np_prev < np_curr;
|
||||
} else if (ll_prev != ll_curr) {
|
||||
ordered = ll_prev > ll_curr;
|
||||
} else {
|
||||
ordered = prev.Pattern < curr.Pattern;
|
||||
}
|
||||
if (!ordered) {
|
||||
std::cout << "Pattern table out of canonical order between '"
|
||||
<< prev.Pattern << "' (placeholders=" << np_prev
|
||||
<< ", literal_len=" << ll_prev << ") and '" << curr.Pattern
|
||||
<< "' (placeholders=" << np_curr << ", literal_len=" << ll_curr
|
||||
<< "). Expected (numPlaceholders ASC, totalLiteralLen DESC, "
|
||||
"Pattern ASC).\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testPatternMatchLangPositive()
|
||||
{
|
||||
// CMAKE_<LANG>_CLANG_TIDY must match for several different <LANG>
|
||||
// values, and all must return the same static Summary pointer (the
|
||||
// permissive matcher returns the pattern entry's storage verbatim).
|
||||
auto const cxx = cmCacheDocumentationTable::Get("CMAKE_CXX_CLANG_TIDY");
|
||||
auto const hip = cmCacheDocumentationTable::Get("CMAKE_HIP_CLANG_TIDY");
|
||||
auto const fortran =
|
||||
cmCacheDocumentationTable::Get("CMAKE_Fortran_CLANG_TIDY");
|
||||
ASSERT_TRUE(!cxx.Summary.empty());
|
||||
ASSERT_TRUE(!hip.Summary.empty());
|
||||
ASSERT_TRUE(!fortran.Summary.empty());
|
||||
// Same static-storage Summary pointer.
|
||||
ASSERT_TRUE(cxx.Summary.data() == hip.Summary.data());
|
||||
ASSERT_TRUE(cxx.Summary.data() == fortran.Summary.data());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testPatternMatchConfigPositive()
|
||||
{
|
||||
// CMAKE_<LANG>_FLAGS_<CONFIG> matches both standard configurations and
|
||||
// user-defined ones (the matcher does not enforce a canonical CONFIG
|
||||
// set; it accepts any identifier).
|
||||
auto const debug = cmCacheDocumentationTable::Get("CMAKE_CXX_FLAGS_DEBUG");
|
||||
auto const release =
|
||||
cmCacheDocumentationTable::Get("CMAKE_CXX_FLAGS_RELEASE");
|
||||
auto const coverage =
|
||||
cmCacheDocumentationTable::Get("CMAKE_CXX_FLAGS_COVERAGE");
|
||||
ASSERT_TRUE(!debug.Summary.empty());
|
||||
ASSERT_TRUE(!release.Summary.empty());
|
||||
ASSERT_TRUE(!coverage.Summary.empty());
|
||||
ASSERT_TRUE(debug.Summary.data() == release.Summary.data());
|
||||
ASSERT_TRUE(debug.Summary.data() == coverage.Summary.data());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testPatternMatchNNNN()
|
||||
{
|
||||
// <NNNN> is exactly 4 ASCII digits. 3-digit, 5-digit, and non-digit
|
||||
// inputs must all miss.
|
||||
ASSERT_TRUE(!cmCacheDocumentationTable::Get("CMAKE_POLICY_DEFAULT_CMP0048")
|
||||
.Summary.empty());
|
||||
ASSERT_TRUE(cmCacheDocumentationTable::Get("CMAKE_POLICY_DEFAULT_CMP48")
|
||||
.Summary.empty());
|
||||
ASSERT_TRUE(cmCacheDocumentationTable::Get("CMAKE_POLICY_DEFAULT_CMP00048")
|
||||
.Summary.empty());
|
||||
ASSERT_TRUE(cmCacheDocumentationTable::Get("CMAKE_POLICY_DEFAULT_CMPxyz0")
|
||||
.Summary.empty());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testPatternMatchN()
|
||||
{
|
||||
// <n> is exactly 1 ASCII digit. Multi-digit and non-digit must miss.
|
||||
ASSERT_TRUE(
|
||||
!cmCacheDocumentationTable::Get("CMAKE_MATCH_5").Summary.empty());
|
||||
ASSERT_TRUE(
|
||||
cmCacheDocumentationTable::Get("CMAKE_MATCH_12").Summary.empty());
|
||||
ASSERT_TRUE(cmCacheDocumentationTable::Get("CMAKE_MATCH_a").Summary.empty());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testPatternMatchMultiPlaceholder()
|
||||
{
|
||||
// CMAKE_CXX_FLAGS_DEBUG must match the two-placeholder pattern
|
||||
// ``CMAKE_<LANG>_FLAGS_<CONFIG>``, not the one-placeholder pattern
|
||||
// ``CMAKE_<LANG>_FLAGS`` (which fails full-input consumption on a
|
||||
// longer input by design).
|
||||
auto const got = cmCacheDocumentationTable::Get("CMAKE_CXX_FLAGS_DEBUG");
|
||||
ASSERT_TRUE(!got.Summary.empty());
|
||||
// Locate the two-placeholder entry and assert pointer equality.
|
||||
cm::string_view two_ph_summary;
|
||||
for (auto const* it = cmCachePatternTable::EntriesBegin();
|
||||
it != cmCachePatternTable::EntriesEnd(); ++it) {
|
||||
if (it->Pattern == "CMAKE_<LANG>_FLAGS_<CONFIG>") {
|
||||
two_ph_summary = it->Summary;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT_TRUE(!two_ph_summary.empty());
|
||||
ASSERT_TRUE(got.Summary.data() == two_ph_summary.data());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testPatternMatchPackage()
|
||||
{
|
||||
// The single <PackageName>_ROOT pattern covers both mixed-case
|
||||
// (CMP0074) and upper-case (CMP0144) spellings: the identifier
|
||||
// lexical class ``[A-Za-z][A-Za-z0-9_]*`` accepts both.
|
||||
ASSERT_TRUE(!cmCacheDocumentationTable::Get("Boost_ROOT").Summary.empty());
|
||||
ASSERT_TRUE(!cmCacheDocumentationTable::Get("Qt6_ROOT").Summary.empty());
|
||||
ASSERT_TRUE(!cmCacheDocumentationTable::Get("BOOST_ROOT").Summary.empty());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testExactWinsOverPattern()
|
||||
{
|
||||
// CMAKE_CUDA_STANDARD is in the exact-match table and would also match
|
||||
// the pattern CMAKE_<LANG>_STANDARD. The exact entry must win.
|
||||
auto const got = cmCacheDocumentationTable::Get("CMAKE_CUDA_STANDARD");
|
||||
ASSERT_TRUE(!got.Summary.empty());
|
||||
// Find the exact entry's Summary in cmCacheDocumentationTable.
|
||||
cm::string_view exact_summary;
|
||||
for (auto const* it = cmCacheDocumentationTable::EntriesBegin();
|
||||
it != cmCacheDocumentationTable::EntriesEnd(); ++it) {
|
||||
if (it->Name == "CMAKE_CUDA_STANDARD") {
|
||||
exact_summary = it->Summary;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT_TRUE(!exact_summary.empty());
|
||||
// Pointer equality: the exact-match path returns the table's static
|
||||
// storage; the pattern-match path would return cmCachePatternTable's
|
||||
// (different) storage.
|
||||
ASSERT_TRUE(got.Summary.data() == exact_summary.data());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testPatternMatchNegativeUnknown()
|
||||
{
|
||||
// A name that matches no pattern at all returns the sentinel.
|
||||
auto const got =
|
||||
cmCacheDocumentationTable::Get("CMAKE_TOTAL_NONSENSE_VARIABLE_XYZZY");
|
||||
ASSERT_TRUE(got.Summary.empty());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testPatternUnderscoreInLang()
|
||||
{
|
||||
// The lazy matcher allows ``<LANG>`` to contain underscores (the
|
||||
// identifier class is ``[A-Za-z][A-Za-z0-9_]*``); the lookahead-anchor
|
||||
// search finds the right boundary. This pins the design decision:
|
||||
// permissive matching with restriction-in-prose, not regex-strict
|
||||
// language enforcement. A made-up ``MY_WEIRD_LANG`` is still picked
|
||||
// up by the CMAKE_<LANG>_CLANG_TIDY pattern.
|
||||
auto const got =
|
||||
cmCacheDocumentationTable::Get("CMAKE_MY_WEIRD_LANG_CLANG_TIDY");
|
||||
ASSERT_TRUE(!got.Summary.empty());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testEveryPatternReachable()
|
||||
{
|
||||
// For each pattern we synthesize a canonical instantiation by
|
||||
// replacing each placeholder with a class-appropriate token:
|
||||
// ``Aa`` for identifier-class placeholders (LANG / CONFIG /
|
||||
// PackageName / PROJECT-NAME / an-attribute / FEATURE / TYPE),
|
||||
// ``0000`` for the fixed-length ``<NNNN>``, and ``0`` for the
|
||||
// fixed-length ``<n>``. The matcher's lazy + lookahead-anchored
|
||||
// semantics then either commit (Summary non-empty -> reachable) or
|
||||
// reject (Summary empty -> dead pattern, test fails).
|
||||
for (auto const* it = cmCachePatternTable::EntriesBegin();
|
||||
it != cmCachePatternTable::EntriesEnd(); ++it) {
|
||||
std::string instance;
|
||||
cm::string_view const pat = it->Pattern;
|
||||
for (std::size_t i = 0; i < pat.size();) {
|
||||
if (pat[i] != '<') {
|
||||
instance.push_back(pat[i]);
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
auto const close = pat.find('>', i);
|
||||
if (close == cm::string_view::npos) {
|
||||
std::cout << "Malformed pattern '" << pat << "' (unterminated '<')\n";
|
||||
return false;
|
||||
}
|
||||
cm::string_view const ph = pat.substr(i, close - i + 1);
|
||||
if (ph == "<NNNN>") {
|
||||
instance += "0000";
|
||||
} else if (ph == "<n>") {
|
||||
instance += "0";
|
||||
} else {
|
||||
// Identifier-class placeholder (Ident or IdentHyphen). ``Aa``
|
||||
// satisfies both lexical classes and is short enough not to
|
||||
// accidentally collide with any anchor literal in the table.
|
||||
instance += "Aa";
|
||||
}
|
||||
i = close + 1;
|
||||
}
|
||||
auto const got = cmCacheDocumentationTable::Get(instance);
|
||||
if (got.Summary.empty()) {
|
||||
std::cout << "Dead pattern '" << pat << "': canonical instantiation '"
|
||||
<< instance
|
||||
<< "' is not matched by any entry in the pattern table\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int testCacheDocumentationTable(int /*unused*/, char* /*unused*/[])
|
||||
{
|
||||
return runTests({
|
||||
testNonEmpty,
|
||||
testSortedAndUnique,
|
||||
testNonEmptyFields,
|
||||
testNameCharacters,
|
||||
testSummaryIsSingleLine,
|
||||
testGetRoundTrip,
|
||||
// Pattern-table cases.
|
||||
testPatternTableNonEmpty,
|
||||
testPatternTableFieldsValid,
|
||||
testPatternTableOrdered,
|
||||
testPatternMatchLangPositive,
|
||||
testPatternMatchConfigPositive,
|
||||
testPatternMatchNNNN,
|
||||
testPatternMatchN,
|
||||
testPatternMatchMultiPlaceholder,
|
||||
testPatternMatchPackage,
|
||||
testExactWinsOverPattern,
|
||||
testPatternMatchNegativeUnknown,
|
||||
testPatternUnderscoreInLang,
|
||||
testEveryPatternReachable,
|
||||
});
|
||||
}
|
||||
@@ -1186,6 +1186,9 @@ endif()
|
||||
add_executable(print_stdin print_stdin.c)
|
||||
add_RunCMake_test(CTestCommandLine -DTEST_PRINT_STDIN=$<TARGET_FILE:print_stdin>)
|
||||
add_RunCMake_test(CacheNewline)
|
||||
add_RunCMake_test(CacheVarHelpFallback)
|
||||
add_RunCMake_test(CacheVarHelpCoverage
|
||||
-DCMake_SOURCE_DIR=${CMake_SOURCE_DIR})
|
||||
# Only run this test on unix platforms that support
|
||||
# symbolic links
|
||||
if(UNIX)
|
||||
|
||||
134
Tests/RunCMake/CacheVarHelpCoverage/RunCMakeTest.cmake
Normal file
134
Tests/RunCMake/CacheVarHelpCoverage/RunCMakeTest.cmake
Normal file
@@ -0,0 +1,134 @@
|
||||
# Built-in cache documentation structural-parity lint.
|
||||
#
|
||||
# The table ``Source/cmCacheDocumentationTable.cxx`` is hand-maintained;
|
||||
# its set of entries is the curated list of CMake cache variables for
|
||||
# which ``cmake-gui`` and ``ccmake`` surface a built-in tooltip when the
|
||||
# on-disk ``HELPSTRING`` is empty (the common case for variables a user
|
||||
# sets via ``-D`` without an accompanying docstring).
|
||||
#
|
||||
# The sibling table ``Source/cmCachePatternTable.cxx`` carries the
|
||||
# placeholder-shaped fallbacks (``CMAKE_<LANG>_FLAGS``,
|
||||
# ``CMAKE_POLICY_DEFAULT_CMP<NNNN>``, ``<PROJECT-NAME>_VERSION``, ...).
|
||||
# Patterns store their placeholder names with angle brackets; the
|
||||
# corresponding ``Help/variable/<NAME>.rst`` filenames carry the same
|
||||
# placeholder tokens with the brackets stripped.
|
||||
#
|
||||
# Drift between an entry's wording and its source ``Help/variable/*.rst``
|
||||
# manual is handled by reviewer discipline : when an ``.rst`` is reworded,
|
||||
# the matching table entry is reviewed in the same change. This test
|
||||
# therefore enforces only the one piece of drift that a human reviewer
|
||||
# would not naturally catch: that every entry NAME in both tables still
|
||||
# resolves to an existing ``Help/variable/<NAME>.rst`` file (so the
|
||||
# tooltip is never silently divorced from a real manual via a typo, a
|
||||
# rename, or a deletion).
|
||||
|
||||
if(NOT DEFINED CMake_SOURCE_DIR OR NOT IS_DIRECTORY "${CMake_SOURCE_DIR}")
|
||||
message(FATAL_ERROR
|
||||
"CacheVarHelpCoverage: CMake_SOURCE_DIR was not provided.")
|
||||
endif()
|
||||
|
||||
set(_help_dir "${CMake_SOURCE_DIR}/Help/variable")
|
||||
set(_table_file "${CMake_SOURCE_DIR}/Source/cmCacheDocumentationTable.cxx")
|
||||
set(_pattern_file "${CMake_SOURCE_DIR}/Source/cmCachePatternTable.cxx")
|
||||
|
||||
if(NOT IS_DIRECTORY "${_help_dir}")
|
||||
message(FATAL_ERROR
|
||||
"CacheVarHelpCoverage: ${_help_dir} does not exist.")
|
||||
endif()
|
||||
if(NOT EXISTS "${_table_file}")
|
||||
message(FATAL_ERROR
|
||||
"CacheVarHelpCoverage: ${_table_file} does not exist.")
|
||||
endif()
|
||||
if(NOT EXISTS "${_pattern_file}")
|
||||
message(FATAL_ERROR
|
||||
"CacheVarHelpCoverage: ${_pattern_file} does not exist.")
|
||||
endif()
|
||||
|
||||
# Extract entry names from the C++ exact-match table. Each entry begins
|
||||
# with the fixed pattern ``\n { "NAME",``; see the header comment in
|
||||
# cmCacheDocumentationTable.cxx for the layout convention.
|
||||
file(READ "${_table_file}" _table_text)
|
||||
string(REGEX MATCHALL "\n \\{ \"[^\"]+\"" _hits "${_table_text}")
|
||||
set(_table_names)
|
||||
foreach(_hit IN LISTS _hits)
|
||||
string(REGEX REPLACE "^\n \\{ \"" "" _name "${_hit}")
|
||||
string(REGEX REPLACE "\"$" "" _name "${_name}")
|
||||
list(APPEND _table_names "${_name}")
|
||||
endforeach()
|
||||
list(SORT _table_names)
|
||||
|
||||
# Extract entry patterns from the C++ pattern table. Same row shape as
|
||||
# above; the pattern strings carry angle-bracketed placeholders like
|
||||
# ``CMAKE_<LANG>_FLAGS`` or ``<PROJECT-NAME>_VERSION``. Strip the
|
||||
# angle brackets to derive the matching ``.rst`` basename
|
||||
# (``CMAKE_LANG_FLAGS.rst`` etc.).
|
||||
file(READ "${_pattern_file}" _pattern_text)
|
||||
string(REGEX MATCHALL "\n \\{ \"[^\"]+\"" _phits "${_pattern_text}")
|
||||
set(_pattern_names)
|
||||
foreach(_hit IN LISTS _phits)
|
||||
string(REGEX REPLACE "^\n \\{ \"" "" _name "${_hit}")
|
||||
string(REGEX REPLACE "\"$" "" _name "${_name}")
|
||||
list(APPEND _pattern_names "${_name}")
|
||||
endforeach()
|
||||
list(SORT _pattern_names)
|
||||
|
||||
# Table entries whose NAME does not match an existing
|
||||
# Help/variable/<NAME>.rst manual.
|
||||
set(_missing_exact)
|
||||
foreach(_name IN LISTS _table_names)
|
||||
if(NOT EXISTS "${_help_dir}/${_name}.rst")
|
||||
list(APPEND _missing_exact "${_name}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Pattern entries whose NAME (with ``<`` and ``>`` stripped) does not
|
||||
# match an existing Help/variable/<NAME>.rst manual.
|
||||
set(_missing_pattern)
|
||||
foreach(_name IN LISTS _pattern_names)
|
||||
string(REPLACE "<" "" _basename "${_name}")
|
||||
string(REPLACE ">" "" _basename "${_basename}")
|
||||
if(NOT EXISTS "${_help_dir}/${_basename}.rst")
|
||||
list(APPEND _missing_pattern "${_name}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(_missing_exact OR _missing_pattern)
|
||||
set(_msg "Built-in cache documentation coverage check failed.")
|
||||
if(_missing_exact)
|
||||
list(LENGTH _missing_exact _n)
|
||||
string(APPEND _msg
|
||||
"\n\n${_n} entry/entries in Source/cmCacheDocumentationTable.cxx"
|
||||
"\nhave no matching Help/variable/<NAME>.rst manual:")
|
||||
foreach(_name IN LISTS _missing_exact)
|
||||
string(APPEND _msg "\n ${_name}")
|
||||
endforeach()
|
||||
endif()
|
||||
if(_missing_pattern)
|
||||
list(LENGTH _missing_pattern _n)
|
||||
string(APPEND _msg
|
||||
"\n\n${_n} entry/entries in Source/cmCachePatternTable.cxx"
|
||||
"\nhave no matching Help/variable/<NAME>.rst manual (the "
|
||||
"placeholder tokens carry through verbatim with ``<``/``>`` "
|
||||
"stripped):")
|
||||
foreach(_name IN LISTS _missing_pattern)
|
||||
string(REPLACE "<" "" _basename "${_name}")
|
||||
string(REPLACE ">" "" _basename "${_basename}")
|
||||
string(APPEND _msg "\n ${_name} -> ${_basename}.rst")
|
||||
endforeach()
|
||||
endif()
|
||||
string(APPEND _msg
|
||||
"\n\nLikely causes and remedies:"
|
||||
"\n * The entry NAME / Pattern is misspelled -- fix the spelling."
|
||||
"\n * Help/variable/<NAME>.rst was renamed -- update the entry to"
|
||||
"\n match the new filename."
|
||||
"\n * Help/variable/<NAME>.rst was deleted intentionally -- remove"
|
||||
"\n the corresponding entry from the table.")
|
||||
message(FATAL_ERROR "${_msg}")
|
||||
endif()
|
||||
|
||||
list(LENGTH _table_names _n_tab)
|
||||
list(LENGTH _pattern_names _n_pat)
|
||||
message(STATUS
|
||||
"Built-in cache documentation coverage OK: "
|
||||
"${_n_tab} exact entry/entries + ${_n_pat} pattern entry/entries, "
|
||||
"all matched to Help/variable/*.rst.")
|
||||
3
Tests/RunCMake/CacheVarHelpFallback/CMakeLists.txt
Normal file
3
Tests/RunCMake/CacheVarHelpFallback/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
include(${RunCMake_TEST}.cmake)
|
||||
136
Tests/RunCMake/CacheVarHelpFallback/CheckCache.cmake
Normal file
136
Tests/RunCMake/CacheVarHelpFallback/CheckCache.cmake
Normal file
@@ -0,0 +1,136 @@
|
||||
# Inspects ${RunCMake_TEST_BINARY_DIR}/CMakeCache.txt and verifies that
|
||||
# ``cmake::ProcessCacheArg`` installed the expected HELPSTRING (from the
|
||||
# built-in documentation table) and preserved the cache entry's type
|
||||
# and value verbatim.
|
||||
#
|
||||
# Each entry's HELPSTRING is serialized as zero or more ``//``-prefixed
|
||||
# lines immediately preceding the ``KEY:TYPE=VALUE`` line.
|
||||
|
||||
set(_cache_file "${RunCMake_TEST_BINARY_DIR}/CMakeCache.txt")
|
||||
if(NOT EXISTS "${_cache_file}")
|
||||
set(RunCMake_TEST_FAILED "Missing cache file: ${_cache_file}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
file(READ "${_cache_file}" _cache_text)
|
||||
string(REGEX REPLACE "\r\n" "\n" _cache_text "${_cache_text}")
|
||||
string(REPLACE ";" "\\;" _cache_text "${_cache_text}")
|
||||
string(REPLACE "\n" ";" _cache_lines "${_cache_text}")
|
||||
|
||||
# Collect the contiguous run of ``//`` comment lines that immediately
|
||||
# precedes ``${entry_key}:`` and join their bodies (everything after the
|
||||
# leading ``//``) into a single string, one body per line. An entry
|
||||
# preceded by no ``//`` lines yields the empty string.
|
||||
function(_collect_help entry_key out_var)
|
||||
set(_collected "")
|
||||
set(_run "")
|
||||
foreach(_line IN LISTS _cache_lines)
|
||||
if(_line MATCHES "^//(.*)$")
|
||||
string(APPEND _run "${CMAKE_MATCH_1}\n")
|
||||
elseif(_line MATCHES "^${entry_key}:[A-Za-z]+=")
|
||||
set(_collected "${_run}")
|
||||
break()
|
||||
else()
|
||||
set(_run "")
|
||||
endif()
|
||||
endforeach()
|
||||
set(${out_var} "${_collected}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Find the ``${entry_key}:TYPE=VALUE`` line itself (the full type+value
|
||||
# record, without the leading ``//`` help block). Sets ``out_var`` to
|
||||
# the empty string if the entry is absent.
|
||||
function(_find_entry_line entry_key out_var)
|
||||
set(_found "")
|
||||
foreach(_line IN LISTS _cache_lines)
|
||||
if(_line MATCHES "^${entry_key}:[A-Za-z]+=")
|
||||
set(_found "${_line}")
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
set(${out_var} "${_found}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
if(test STREQUAL "DefineSetsTypeAndHelp")
|
||||
# Bare ``-D CMAKE_COMPILE_WARNING_AS_ERROR=ON`` -- ProcessCacheArg
|
||||
# must install the documentation-table summary as HELPSTRING and
|
||||
# leave the entry typed UNINITIALIZED (the user did not pin a type).
|
||||
_find_entry_line("CMAKE_COMPILE_WARNING_AS_ERROR" _line)
|
||||
_collect_help("CMAKE_COMPILE_WARNING_AS_ERROR" _help)
|
||||
if(NOT _line MATCHES "^CMAKE_COMPILE_WARNING_AS_ERROR:UNINITIALIZED=ON$")
|
||||
set(RunCMake_TEST_FAILED
|
||||
"ProcessCacheArg unexpectedly altered the bare -D entry's type "
|
||||
"or value.\nRecovered entry line:\n[${_line}]")
|
||||
elseif(NOT _help MATCHES "treat warnings on compile as errors")
|
||||
set(RunCMake_TEST_FAILED
|
||||
"ProcessCacheArg did not install HELPSTRING from documentation "
|
||||
"table.\nRecovered help block:\n[${_help}]")
|
||||
endif()
|
||||
elseif(test STREQUAL "DefineTypePreserved")
|
||||
# ``-D CMAKE_COMPILE_WARNING_AS_ERROR:STRING=ON`` -- the user's
|
||||
# explicit ``:STRING`` annotation is honored; HELPSTRING is still
|
||||
# populated from the table because the user supplied none.
|
||||
_find_entry_line("CMAKE_COMPILE_WARNING_AS_ERROR" _line)
|
||||
_collect_help("CMAKE_COMPILE_WARNING_AS_ERROR" _help)
|
||||
if(NOT _line MATCHES "^CMAKE_COMPILE_WARNING_AS_ERROR:STRING=ON$")
|
||||
set(RunCMake_TEST_FAILED
|
||||
"ProcessCacheArg overwrote user's explicit :STRING type pin.\n"
|
||||
"Recovered entry line:\n[${_line}]")
|
||||
elseif(NOT _help MATCHES "treat warnings on compile as errors")
|
||||
set(RunCMake_TEST_FAILED
|
||||
"ProcessCacheArg did not install HELPSTRING when user pinned a "
|
||||
"type.\nRecovered help block:\n[${_help}]")
|
||||
endif()
|
||||
elseif(test STREQUAL "DefineUnknownVarUninitialized")
|
||||
# ``-D MY_CUSTOM_VAR_XYZZY=x`` -- a project-specific name absent from
|
||||
# the documentation table. Type stays UNINITIALIZED and HELPSTRING
|
||||
# falls back to the legacy sentinel.
|
||||
_find_entry_line("MY_CUSTOM_VAR_XYZZY" _line)
|
||||
_collect_help("MY_CUSTOM_VAR_XYZZY" _help)
|
||||
if(NOT _line MATCHES "^MY_CUSTOM_VAR_XYZZY:UNINITIALIZED=x$")
|
||||
set(RunCMake_TEST_FAILED
|
||||
"ProcessCacheArg altered the unknown-variable entry.\n"
|
||||
"Recovered entry line:\n[${_line}]")
|
||||
elseif(NOT _help MATCHES "No help, variable specified on the command line")
|
||||
set(RunCMake_TEST_FAILED
|
||||
"ProcessCacheArg did not preserve sentinel HELPSTRING for unknown "
|
||||
"variable.\nRecovered help block:\n[${_help}]")
|
||||
endif()
|
||||
elseif(test STREQUAL "PatternCxxClangTidy")
|
||||
# ``-D CMAKE_CXX_CLANG_TIDY=clang-tidy`` -- no exact-match entry in
|
||||
# ``cmCacheDocumentationTable``; the pattern table's
|
||||
# ``CMAKE_<LANG>_CLANG_TIDY`` entry matches. ProcessCacheArg installs
|
||||
# the pattern's Summary as HELPSTRING; type stays UNINITIALIZED.
|
||||
_find_entry_line("CMAKE_CXX_CLANG_TIDY" _line)
|
||||
_collect_help("CMAKE_CXX_CLANG_TIDY" _help)
|
||||
if(NOT _line MATCHES "^CMAKE_CXX_CLANG_TIDY:UNINITIALIZED=clang-tidy$")
|
||||
set(RunCMake_TEST_FAILED
|
||||
"ProcessCacheArg unexpectedly altered the pattern-matched entry's "
|
||||
"type or value.\nRecovered entry line:\n[${_line}]")
|
||||
elseif(NOT _help MATCHES "clang-tidy command")
|
||||
set(RunCMake_TEST_FAILED
|
||||
"Pattern-table lookup did not install HELPSTRING from the "
|
||||
"CMAKE_<LANG>_CLANG_TIDY pattern.\n"
|
||||
"Recovered help block:\n[${_help}]")
|
||||
endif()
|
||||
elseif(test STREQUAL "PatternHipCppcheck")
|
||||
# ``-D CMAKE_HIP_CPPCHECK=anything`` -- the matcher is intentionally
|
||||
# permissive about ``<LANG>`` even though the cppcheck pattern's
|
||||
# Summary names a C/CXX restriction. Assert the value is preserved
|
||||
# verbatim, the type stays UNINITIALIZED, and the Summary's
|
||||
# restriction phrase appears in the HELPSTRING.
|
||||
_find_entry_line("CMAKE_HIP_CPPCHECK" _line)
|
||||
_collect_help("CMAKE_HIP_CPPCHECK" _help)
|
||||
if(NOT _line MATCHES "^CMAKE_HIP_CPPCHECK:UNINITIALIZED=anything$")
|
||||
set(RunCMake_TEST_FAILED
|
||||
"ProcessCacheArg unexpectedly altered the pattern-matched entry's "
|
||||
"type or value.\nRecovered entry line:\n[${_line}]")
|
||||
elseif(NOT _help MATCHES "C or CXX")
|
||||
set(RunCMake_TEST_FAILED
|
||||
"Pattern-table lookup did not surface the C/CXX restriction in "
|
||||
"the HELPSTRING for CMAKE_HIP_CPPCHECK.\n"
|
||||
"Recovered help block:\n[${_help}]")
|
||||
endif()
|
||||
else()
|
||||
set(RunCMake_TEST_FAILED "Unknown test case: ${test}")
|
||||
endif()
|
||||
@@ -0,0 +1,9 @@
|
||||
# Defines a built-in cache variable on the command line with no
|
||||
# ``:TYPE=`` annotation. ``cmake::ProcessCacheArg`` must consult the
|
||||
# built-in documentation table and install the table summary as the
|
||||
# entry's HELPSTRING. Type and value are preserved verbatim, so the
|
||||
# entry remains ``:UNINITIALIZED=`` (consistent with the project-side
|
||||
# behavior, which would re-type later in ``cmMakefile::AddCacheDefinition``
|
||||
# only if a ``set(... CACHE BOOL ...)`` call appeared in a listfile).
|
||||
# The project listfile itself does not ``set(...)`` the variable; the
|
||||
# cache entry materializes solely through ``-D``.
|
||||
@@ -0,0 +1,5 @@
|
||||
# Defines a built-in cache variable on the command line with an explicit
|
||||
# ``:STRING`` annotation. ``ProcessCacheArg`` honors the explicit type
|
||||
# (the entry must be persisted as ``:STRING=``) and still installs the
|
||||
# HELPSTRING from the documentation table because the user supplied
|
||||
# none.
|
||||
@@ -0,0 +1,4 @@
|
||||
# Defines a project-specific cache variable on the command line with no
|
||||
# ``:TYPE=`` annotation. The documentation table cannot match this
|
||||
# name, so the entry must remain ``:UNINITIALIZED=`` and receive the
|
||||
# generic sentinel help string preserved for backwards compatibility.
|
||||
@@ -0,0 +1,9 @@
|
||||
# Defines a placeholder-shaped built-in cache variable on the command
|
||||
# line with no ``:TYPE=`` annotation. No exact-match entry exists for
|
||||
# ``CMAKE_CXX_CLANG_TIDY`` in ``cmCacheDocumentationTable``;
|
||||
# ``cmake::ProcessCacheArg`` therefore consults the pattern table
|
||||
# (``cmCachePatternTable``), matches the ``CMAKE_<LANG>_CLANG_TIDY``
|
||||
# pattern, and installs the pattern's Summary as the entry's HELPSTRING.
|
||||
# Type and value are preserved verbatim. The project listfile itself
|
||||
# does not ``set(...)`` the variable; the cache entry materializes
|
||||
# solely through ``-D``.
|
||||
@@ -0,0 +1,9 @@
|
||||
# Defines a placeholder-shaped built-in cache variable on the command
|
||||
# line for a language combination the underlying ``.rst`` manual
|
||||
# explicitly excludes (``CMAKE_<LANG>_CPPCHECK`` applies only when
|
||||
# ``<LANG>`` is C or CXX; this test passes ``HIP``). The matcher is
|
||||
# intentionally permissive: it accepts the name and returns the
|
||||
# pattern's Summary, which is installed as the entry's HELPSTRING;
|
||||
# the per-language restriction is documented in the Summary prose,
|
||||
# not enforced by the matcher. This case validates the "permissive
|
||||
# matching with restriction-in-prose" design end-to-end.
|
||||
49
Tests/RunCMake/CacheVarHelpFallback/RunCMakeTest.cmake
Normal file
49
Tests/RunCMake/CacheVarHelpFallback/RunCMakeTest.cmake
Normal file
@@ -0,0 +1,49 @@
|
||||
include(RunCMake)
|
||||
|
||||
# All cases below exercise ``cmake::ProcessCacheArg``: when a built-in
|
||||
# cache variable is set via ``-D <var>=<value>`` with no ``:TYPE=`` and
|
||||
# no help text, ``ProcessCacheArg`` consults the built-in documentation
|
||||
# table (``cmCacheDocumentationTable`` and ``cmCachePatternTable``,
|
||||
# seeded from ``Help/variable/*.rst`` and the per-language pattern
|
||||
# manuals) and installs the table's Summary as the entry's HELPSTRING.
|
||||
# The cache entry's type and value are left untouched.
|
||||
function(run_define_case case)
|
||||
set(RunCMake-check-file CheckCache.cmake)
|
||||
run_cmake(${case})
|
||||
endfunction()
|
||||
|
||||
# Bare ``-D <var>=<value>`` of a documented built-in: HELPSTRING is
|
||||
# populated from the table's Summary; type stays UNINITIALIZED because
|
||||
# the user did not pin one.
|
||||
set(RunCMake_TEST_OPTIONS "-DCMAKE_COMPILE_WARNING_AS_ERROR=ON")
|
||||
run_define_case(DefineSetsTypeAndHelp)
|
||||
unset(RunCMake_TEST_OPTIONS)
|
||||
|
||||
# ``-D <var>:STRING=<value>`` of a documented built-in: user's explicit
|
||||
# type pin is honored; HELPSTRING is still populated from the table.
|
||||
set(RunCMake_TEST_OPTIONS "-DCMAKE_COMPILE_WARNING_AS_ERROR:STRING=ON")
|
||||
run_define_case(DefineTypePreserved)
|
||||
unset(RunCMake_TEST_OPTIONS)
|
||||
|
||||
# Bare ``-D <var>=<value>`` of a project-specific name: no table match,
|
||||
# so the entry stays ``:UNINITIALIZED=`` with the legacy sentinel
|
||||
# HELPSTRING preserved for backwards compatibility.
|
||||
set(RunCMake_TEST_OPTIONS "-DMY_CUSTOM_VAR_XYZZY=x")
|
||||
run_define_case(DefineUnknownVarUninitialized)
|
||||
unset(RunCMake_TEST_OPTIONS)
|
||||
|
||||
# A built-in variable name absent from the exact-match table but present
|
||||
# in the pattern table (``CMAKE_<LANG>_CLANG_TIDY``): HELPSTRING comes
|
||||
# from the pattern's Summary; type stays UNINITIALIZED.
|
||||
set(RunCMake_TEST_OPTIONS "-DCMAKE_CXX_CLANG_TIDY=clang-tidy")
|
||||
run_define_case(PatternCxxClangTidy)
|
||||
unset(RunCMake_TEST_OPTIONS)
|
||||
|
||||
# A built-in variable name matching a pattern whose manual documents a
|
||||
# per-language restriction CMake does not enforce at match time
|
||||
# (cppcheck applies only to C/CXX, but here we set HIP). The matcher
|
||||
# is intentionally permissive; the restriction text travels in the
|
||||
# Summary prose.
|
||||
set(RunCMake_TEST_OPTIONS "-DCMAKE_HIP_CPPCHECK=anything")
|
||||
run_define_case(PatternHipCppcheck)
|
||||
unset(RunCMake_TEST_OPTIONS)
|
||||
Reference in New Issue
Block a user