fileapi: Add support for user-wide queries

Fixes: #19168
This commit is contained in:
Martin Duffy 2024-08-16 08:49:10 -04:00 committed by Brad King
parent a991a5019b
commit 1df94443fe
13 changed files with 72 additions and 4 deletions

View File

@ -0,0 +1,18 @@
CMAKE_CONFIG_DIR
----------------
.. versionadded:: 3.31
.. include:: ENV_VAR.txt
Specify a CMake user-wide configuration directory for
:manual:`cmake-file-api(7)` queries.
If this environment variable is not set, the default user-wide
configuration directory is platform-specific:
- Windows: ``%LOCALAPPDATA%\CMake``
- macOS: ``$XDG_CONFIG_HOME/CMake`` if set, otherwise
``$HOME/Library/Application Support/CMake``
- Linux/Other: ``$XDG_CONFIG_HOME/cmake`` if set, otherwise
``$HOME/.config/cmake``

View File

@ -43,8 +43,9 @@ Environment Variables that Control the Build
/envvar/CMAKE_BUILD_PARALLEL_LEVEL
/envvar/CMAKE_BUILD_TYPE
/envvar/CMAKE_COLOR_DIAGNOSTICS
/envvar/CMAKE_CONFIGURATION_TYPES
/envvar/CMAKE_CONFIG_DIR
/envvar/CMAKE_CONFIG_TYPE
/envvar/CMAKE_CONFIGURATION_TYPES
/envvar/CMAKE_CROSSCOMPILING_EMULATOR
/envvar/CMAKE_EXPORT_COMPILE_COMMANDS
/envvar/CMAKE_GENERATOR

View File

@ -50,6 +50,10 @@ It has the following subdirectories:
Clients may optionally create the ``reply/`` directory at any time
and monitor it for the appearance of a new reply index file.
.. versionadded:: 3.31
Users can add query files to ``api/v1/query`` inside the
:envvar:`CMAKE_CONFIG_DIR` to create user-wide queries for all CMake projects.
v1 Shared Stateless Query Files
-------------------------------

View File

@ -266,6 +266,14 @@ Options
from the top of a binary tree for a CMake project it will dump
additional information such as the cache, log files etc.
.. option:: --print-config-dir
.. versionadded:: 3.31
Print CMake config directory for user-wide FileAPI queries.
See :envvar:`CMAKE_CONFIG_DIR` for more details.
.. option:: --log-level=<level>
.. versionadded:: 3.16

View File

@ -7,9 +7,13 @@
#include <chrono>
#include <ctime>
#include <iomanip>
#include <iterator>
#include <sstream>
#include <utility>
#include <cm/optional>
#include <cmext/string_view>
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
@ -29,7 +33,12 @@ cmFileAPI::cmFileAPI(cmake* cm)
: CMakeInstance(cm)
{
this->APIv1 =
this->CMakeInstance->GetHomeOutputDirectory() + "/.cmake/api/v1";
cmStrCat(this->CMakeInstance->GetHomeOutputDirectory(), "/.cmake/api/v1");
if (cm::optional<std::string> cmakeConfigDir =
cmSystemTools::GetCMakeConfigDirectory()) {
this->UserAPIv1 = cmStrCat(std::move(*cmakeConfigDir), "/api/v1"_s);
}
Json::CharReaderBuilder rbuilder;
rbuilder["collectComments"] = false;
@ -47,14 +56,24 @@ cmFileAPI::cmFileAPI(cmake* cm)
void cmFileAPI::ReadQueries()
{
std::string const query_dir = this->APIv1 + "/query";
std::string const query_dir = cmStrCat(this->APIv1, "/query");
std::string const user_query_dir = cmStrCat(this->UserAPIv1, "/query");
this->QueryExists = cmSystemTools::FileIsDirectory(query_dir);
if (!this->UserAPIv1.empty()) {
this->QueryExists =
this->QueryExists || cmSystemTools::FileIsDirectory(user_query_dir);
}
if (!this->QueryExists) {
return;
}
// Load queries at the top level.
std::vector<std::string> queries = cmFileAPI::LoadDir(query_dir);
if (!this->UserAPIv1.empty()) {
std::vector<std::string> user_queries = cmFileAPI::LoadDir(user_query_dir);
std::move(user_queries.begin(), user_queries.end(),
std::back_inserter(queries));
}
// Read the queries and save for later.
for (std::string& query : queries) {

View File

@ -61,6 +61,9 @@ private:
/** The api/v1 directory location. */
std::string APIv1;
/** api/v1 directory in the user's shared CMake config directory. */
std::string UserAPIv1;
/** The set of files we have just written to the reply directory. */
std::unordered_set<std::string> ReplyFiles;

View File

@ -71,7 +71,7 @@ const cmDocumentationEntry cmDocumentationUsageNote = {
"Run 'cmake --help' for more information."
};
const cmDocumentationEntry cmDocumentationOptions[33] = {
const cmDocumentationEntry cmDocumentationOptions[34] = {
{ "--preset <preset>,--preset=<preset>", "Specify a configure preset." },
{ "--list-presets[=<type>]", "List available presets." },
{ "--workflow [<options>]", "Run a workflow preset." },
@ -90,6 +90,8 @@ const cmDocumentationEntry cmDocumentationOptions[33] = {
"Generate graphviz of dependencies, see CMakeGraphVizOptions.cmake for "
"more." },
{ "--system-information [file]", "Dump information about this system." },
{ "--print-config-dir",
"Print CMake config directory for user-wide FileAPI queries." },
{ "--log-level=<ERROR|WARNING|NOTICE|STATUS|VERBOSE|DEBUG|TRACE>",
"Set the verbosity of messages from CMake files. "
"--loglevel is also accepted for backward compatibility reasons." },

View File

@ -408,6 +408,7 @@ if(CMAKE_USE_SYSTEM_JSONCPP)
endif()
add_RunCMake_test(FileAPI -DPython_EXECUTABLE=${Python_EXECUTABLE}
-DCMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID})
add_RunCMake_test(ConfigDir)
add_RunCMake_test(FindBoost)
add_RunCMake_test(FindLua)
add_RunCMake_test(FindOpenGL)

View File

@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.30)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)

View File

@ -0,0 +1,6 @@
include(RunCMake)
set(ENV{CMAKE_CONFIG_DIR} ${CMAKE_CURRENT_LIST_DIR}/config)
set(RunCMake-check-file check-reply.cmake)
run_cmake(config)
unset(RunCMake-check-file)

View File

@ -0,0 +1,3 @@
if (NOT EXISTS ${RunCMake_TEST_BINARY_DIR}/.cmake/api/v1/reply)
set(RunCMake_TEST_FAILED "Failed to read FileAPI query from user config directory")
endif()

View File