fileapi: Add CONFIGURE_DEPENDS glob info to cmakeFiles object
Fixes: #25668 Co-authored-by: Brad King <brad.king@kitware.com>
This commit is contained in:
parent
f578515d02
commit
6116bcb066
@ -1489,7 +1489,7 @@ There is only one ``cmakeFiles`` object major version, version 1.
|
||||
|
||||
{
|
||||
"kind": "cmakeFiles",
|
||||
"version": { "major": 1, "minor": 0 },
|
||||
"version": { "major": 1, "minor": 1 },
|
||||
"paths": {
|
||||
"build": "/path/to/top-level-build-dir",
|
||||
"source": "/path/to/top-level-source-dir"
|
||||
@ -1511,6 +1511,16 @@ There is only one ``cmakeFiles`` object major version, version 1.
|
||||
"isExternal": true,
|
||||
"path": "/path/to/cmake/Modules/CMakeGenericSystem.cmake"
|
||||
}
|
||||
],
|
||||
"globsDependent": [
|
||||
{
|
||||
"expression": "src/*.cxx",
|
||||
"recurse": true,
|
||||
"files": [
|
||||
"src/foo.cxx",
|
||||
"src/bar.cxx"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -1553,6 +1563,44 @@ The members specific to ``cmakeFiles`` objects are:
|
||||
Optional member that is present with boolean value ``true``
|
||||
if the path specifies a file in the CMake installation.
|
||||
|
||||
``globsDependent``
|
||||
Optional member that is present when the project calls :command:`file(GLOB)`
|
||||
or :command:`file(GLOB_RECURSE)` with the ``CONFIGURE_DEPENDS`` option.
|
||||
The value is a JSON array of JSON objects, each specifying a globbing
|
||||
expression and the list of paths it matched. If the globbing expression
|
||||
no longer matches the same list of paths, CMake considers the build system
|
||||
to be out of date.
|
||||
|
||||
This field was added in ``cmakeFiles`` version 1.1.
|
||||
|
||||
The members of each entry are:
|
||||
|
||||
``expression``
|
||||
A string specifying the globbing expression.
|
||||
|
||||
``recurse``
|
||||
Optional member that is present with boolean value ``true``
|
||||
if the entry corresponds to a :command:`file(GLOB_RECURSE)` call.
|
||||
Otherwise the entry corresponds to a :command:`file(GLOB)` call.
|
||||
|
||||
``listDirectories``
|
||||
Optional member that is present with boolean value ``true`` if
|
||||
:command:`file(GLOB)` was called without ``LIST_DIRECTORIES false`` or
|
||||
:command:`file(GLOB_RECURSE)` was called with ``LIST_DIRECTORIES true``.
|
||||
|
||||
``followSymlinks``
|
||||
Optional member that is present with boolean value ``true`` if
|
||||
:command:`file(GLOB)` was called with the ``FOLLOW_SYMLINKS`` option.
|
||||
|
||||
``relative``
|
||||
Optional member that is present if :command:`file(GLOB)` was called
|
||||
with the ``RELATIVE <path>`` option. The value is a string containing
|
||||
the ``<path>`` given.
|
||||
|
||||
``paths``
|
||||
A JSON array of strings specifying the paths matched by the call
|
||||
to :command:`file(GLOB)` or :command:`file(GLOB_RECURSE)`.
|
||||
|
||||
Object Kind "toolchains"
|
||||
------------------------
|
||||
|
||||
|
9
Help/release/dev/fileapi-provide-glob-dependent.rst
Normal file
9
Help/release/dev/fileapi-provide-glob-dependent.rst
Normal file
@ -0,0 +1,9 @@
|
||||
fileapi-provide-glob-dependent
|
||||
------------------------------
|
||||
|
||||
* The :manual:`cmake-file-api(7)` "cmakeFiles" version 1 object's ``version``
|
||||
field has been updated to 1.1.
|
||||
|
||||
* The :manual:`cmake-file-api(7)` "cmakeFiles" version 1 object gained a
|
||||
``globsDependent`` field to report :command:`file(GLOB)` calls using
|
||||
``CONFIGURE_DEPENDS``.
|
@ -830,7 +830,7 @@ Json::Value cmFileAPI::BuildCache(Object const& object)
|
||||
|
||||
// The "cmakeFiles" object kind.
|
||||
|
||||
static unsigned int const CMakeFilesV1Minor = 0;
|
||||
static unsigned int const CMakeFilesV1Minor = 1;
|
||||
|
||||
void cmFileAPI::BuildClientRequestCMakeFiles(
|
||||
ClientRequest& r, std::vector<RequestVersion> const& versions)
|
||||
|
@ -31,6 +31,8 @@ class CMakeFiles
|
||||
Json::Value DumpPaths();
|
||||
Json::Value DumpInputs();
|
||||
Json::Value DumpInput(std::string const& file);
|
||||
Json::Value DumpGlobsDependent();
|
||||
Json::Value DumpGlobDependent(cmGlobCacheEntry const& entry);
|
||||
|
||||
public:
|
||||
CMakeFiles(cmFileAPI& fileAPI, unsigned long version);
|
||||
@ -53,6 +55,10 @@ Json::Value CMakeFiles::Dump()
|
||||
Json::Value cmakeFiles = Json::objectValue;
|
||||
cmakeFiles["paths"] = this->DumpPaths();
|
||||
cmakeFiles["inputs"] = this->DumpInputs();
|
||||
Json::Value globsDependent = this->DumpGlobsDependent();
|
||||
if (!globsDependent.empty()) {
|
||||
cmakeFiles["globsDependent"] = std::move(globsDependent);
|
||||
}
|
||||
return cmakeFiles;
|
||||
}
|
||||
|
||||
@ -108,6 +114,40 @@ Json::Value CMakeFiles::DumpInput(std::string const& file)
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
Json::Value CMakeFiles::DumpGlobsDependent()
|
||||
{
|
||||
Json::Value globsDependent = Json::arrayValue;
|
||||
for (cmGlobCacheEntry const& entry :
|
||||
this->FileAPI.GetCMakeInstance()->GetGlobCacheEntries()) {
|
||||
globsDependent.append(this->DumpGlobDependent(entry));
|
||||
}
|
||||
return globsDependent;
|
||||
}
|
||||
|
||||
Json::Value CMakeFiles::DumpGlobDependent(cmGlobCacheEntry const& entry)
|
||||
{
|
||||
Json::Value globDependent = Json::objectValue;
|
||||
globDependent["expression"] = entry.Expression;
|
||||
if (entry.Recurse) {
|
||||
globDependent["recurse"] = true;
|
||||
}
|
||||
if (entry.ListDirectories) {
|
||||
globDependent["listDirectories"] = true;
|
||||
}
|
||||
if (entry.FollowSymlinks) {
|
||||
globDependent["followSymlinks"] = true;
|
||||
}
|
||||
if (!entry.Relative.empty()) {
|
||||
globDependent["relative"] = entry.Relative;
|
||||
}
|
||||
Json::Value paths = Json::arrayValue;
|
||||
for (std::string const& file : entry.Files) {
|
||||
paths.append(file);
|
||||
}
|
||||
globDependent["paths"] = std::move(paths);
|
||||
return globDependent;
|
||||
}
|
||||
}
|
||||
|
||||
Json::Value cmFileAPICMakeFilesDump(cmFileAPI& fileAPI, unsigned long version)
|
||||
|
@ -176,6 +176,21 @@ void cmGlobVerificationManager::AddCacheEntry(
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<cmGlobCacheEntry> cmGlobVerificationManager::GetCacheEntries()
|
||||
const
|
||||
{
|
||||
std::vector<cmGlobCacheEntry> entries;
|
||||
for (auto const& i : this->Cache) {
|
||||
CacheEntryKey k = std::get<0>(i);
|
||||
CacheEntryValue v = std::get<1>(i);
|
||||
if (v.Initialized) {
|
||||
entries.emplace_back(k.Recurse, k.ListDirectories, k.FollowSymlinks,
|
||||
k.Relative, k.Expression, v.Files);
|
||||
}
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
void cmGlobVerificationManager::Reset()
|
||||
{
|
||||
this->Cache.clear();
|
||||
|
@ -33,6 +33,9 @@ protected:
|
||||
const std::string& variable,
|
||||
const cmListFileBacktrace& bt, cmMessenger* messenger);
|
||||
|
||||
//! Get all cache entries
|
||||
std::vector<cmGlobCacheEntry> GetCacheEntries() const;
|
||||
|
||||
//! Clear the glob cache for state reset.
|
||||
void Reset();
|
||||
|
||||
|
@ -248,6 +248,11 @@ void cmState::AddGlobCacheEntry(const cmGlobCacheEntry& entry,
|
||||
messenger);
|
||||
}
|
||||
|
||||
std::vector<cmGlobCacheEntry> cmState::GetGlobCacheEntries() const
|
||||
{
|
||||
return this->GlobVerificationManager->GetCacheEntries();
|
||||
}
|
||||
|
||||
void cmState::RemoveCacheEntry(std::string const& key)
|
||||
{
|
||||
this->CacheManager->RemoveCacheEntry(key);
|
||||
|
@ -268,6 +268,7 @@ private:
|
||||
const std::string& variable,
|
||||
cmListFileBacktrace const& bt,
|
||||
cmMessenger* messenger);
|
||||
std::vector<cmGlobCacheEntry> GetGlobCacheEntries() const;
|
||||
|
||||
cmPropertyDefinitionMap PropertyDefinitions;
|
||||
std::vector<std::string> EnabledLanguages;
|
||||
|
@ -2958,6 +2958,11 @@ void cmake::AddGlobCacheEntry(const cmGlobCacheEntry& entry,
|
||||
this->Messenger.get());
|
||||
}
|
||||
|
||||
std::vector<cmGlobCacheEntry> cmake::GetGlobCacheEntries() const
|
||||
{
|
||||
return this->State->GetGlobCacheEntries();
|
||||
}
|
||||
|
||||
std::vector<std::string> cmake::GetAllExtensions() const
|
||||
{
|
||||
std::vector<std::string> allExt = this->CLikeSourceFileExtensions.ordered;
|
||||
|
@ -355,6 +355,7 @@ public:
|
||||
void AddGlobCacheEntry(const cmGlobCacheEntry& entry,
|
||||
const std::string& variable,
|
||||
cmListFileBacktrace const& bt);
|
||||
std::vector<cmGlobCacheEntry> GetGlobCacheEntries() const;
|
||||
|
||||
/**
|
||||
* Get the system information and write it to the file specified
|
||||
|
@ -1 +1 @@
|
||||
^{"debugger":(true|false),"fileApi":{"requests":\[{"kind":"codemodel","version":\[{"major":2,"minor":7}]},{"kind":"configureLog","version":\[{"major":1,"minor":0}]},{"kind":"cache","version":\[{"major":2,"minor":0}]},{"kind":"cmakeFiles","version":\[{"major":1,"minor":0}]},{"kind":"toolchains","version":\[{"major":1,"minor":0}]}]},"generators":\[.*\],"serverMode":false,"tls":(true|false),"version":{.*}}$
|
||||
^{"debugger":(true|false),"fileApi":{"requests":\[{"kind":"codemodel","version":\[{"major":2,"minor":7}]},{"kind":"configureLog","version":\[{"major":1,"minor":0}]},{"kind":"cache","version":\[{"major":2,"minor":0}]},{"kind":"cmakeFiles","version":\[{"major":1,"minor":1}]},{"kind":"toolchains","version":\[{"major":1,"minor":0}]}]},"generators":\[.*\],"serverMode":false,"tls":(true|false),"version":{.*}}$
|
||||
|
@ -3,7 +3,7 @@ from check_index import *
|
||||
def check_objects(o):
|
||||
assert is_list(o)
|
||||
assert len(o) == 1
|
||||
check_index_object(o[0], "cmakeFiles", 1, 0, check_object_cmakeFiles)
|
||||
check_index_object(o[0], "cmakeFiles", 1, 1, check_object_cmakeFiles)
|
||||
|
||||
def check_input(actual, expected):
|
||||
assert is_dict(actual)
|
||||
@ -23,8 +23,27 @@ def check_input(actual, expected):
|
||||
|
||||
assert sorted(actual.keys()) == sorted(expected_keys)
|
||||
|
||||
def check_glob_dependent(actual, expected):
|
||||
assert is_dict(actual)
|
||||
|
||||
if "followSymlinks" in expected:
|
||||
assert is_bool(actual["followSymlinks"], expected["followSymlinks"])
|
||||
|
||||
if "listDirectories" in expected:
|
||||
assert is_bool(actual["listDirectories"], expected["listDirectories"])
|
||||
|
||||
if "recurse" in expected:
|
||||
assert is_bool(actual["recurse"], expected["recurse"])
|
||||
|
||||
if "relative" in expected:
|
||||
assert matches(actual["relative"], expected["relative"])
|
||||
|
||||
check_list_match(lambda a, e: matches(a, e), actual["paths"], expected["paths"], allow_extra=True)
|
||||
|
||||
assert sorted(actual.keys()) == sorted(expected.keys())
|
||||
|
||||
def check_object_cmakeFiles(o):
|
||||
assert sorted(o.keys()) == ["inputs", "kind", "paths", "version"]
|
||||
assert sorted(o.keys()) == ["globsDependent", "inputs", "kind", "paths", "version"]
|
||||
# The "kind" and "version" members are handled by check_index_object.
|
||||
assert is_dict(o["paths"])
|
||||
assert sorted(o["paths"].keys()) == ["build", "source"]
|
||||
@ -82,12 +101,33 @@ def check_object_cmakeFiles(o):
|
||||
},
|
||||
]
|
||||
|
||||
expected_globs = [
|
||||
{
|
||||
"expression": "^.*/Tests/RunCMake/FileAPI/dir/\\*$",
|
||||
"paths": [
|
||||
"^.*/Tests/RunCMake/FileAPI/dir/dir$",
|
||||
"^.*/Tests/RunCMake/FileAPI/dir/dirtest\\.cmake$"
|
||||
],
|
||||
"listDirectories": True,
|
||||
},
|
||||
{
|
||||
"expression": "^.*/Tests/RunCMake/FileAPI/dir/\\*\\.cmake$",
|
||||
"paths": [
|
||||
"^dir/dirtest\\.cmake$"
|
||||
],
|
||||
"followSymlinks": True,
|
||||
"recurse": True,
|
||||
"relative": "^.*/Tests/RunCMake/FileAPI$"
|
||||
}
|
||||
]
|
||||
|
||||
inSource = os.path.dirname(o["paths"]["build"]) == o["paths"]["source"]
|
||||
if inSource:
|
||||
for e in expected:
|
||||
e["path"] = e["path"].replace("^.*/Tests/RunCMake/FileAPI/", "^", 1)
|
||||
|
||||
check_list_match(lambda a, e: matches(a["path"], e["path"]), o["inputs"], expected, check=check_input, allow_extra=True)
|
||||
check_list_match(lambda a, e: matches(a["expression"], e["expression"]), o["globsDependent"], expected_globs, check=check_glob_dependent, allow_extra=True)
|
||||
|
||||
assert is_dict(index)
|
||||
assert sorted(index.keys()) == ["cmake", "objects", "reply"]
|
||||
|
@ -5,4 +5,14 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/generated.cmake" "")
|
||||
include("${CMAKE_CURRENT_BINARY_DIR}/generated.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/../FileAPIDummyFile.cmake")
|
||||
|
||||
file(GLOB var
|
||||
CONFIGURE_DEPENDS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dir/*")
|
||||
|
||||
file(GLOB_RECURSE var
|
||||
FOLLOW_SYMLINKS
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
CONFIGURE_DEPENDS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dir/*.cmake")
|
||||
|
||||
add_subdirectory(dir)
|
||||
|
Loading…
Reference in New Issue
Block a user