1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-17 07:11:52 +08:00

fileapi: extend codemodel v2 with directory details

Issue: #18398
Co-Author: Kyle Edwards <kyle.edwards@kitware.com>
This commit is contained in:
Brad King
2018-11-13 09:34:10 -05:00
committed by Kyle Edwards
parent eb8c7676a4
commit 4b6b2a571c
3 changed files with 106 additions and 2 deletions

View File

@@ -433,14 +433,21 @@ Version 1 does not exist to avoid confusion with that from
"build": ".",
"childIndexes": [ 1 ],
"projectIndex": 0,
"targetIndexes": [ 0 ]
"targetIndexes": [ 0 ],
"hasInstallRule": true,
"minimumCMakeVersion": {
"string": "3.14"
}
},
{
"source": "sub",
"build": "sub",
"parentIndex": 0,
"projectIndex": 0,
"targetIndexes": [ 1 ]
"targetIndexes": [ 1 ],
"minimumCMakeVersion": {
"string": "3.14"
}
}
],
"projects": [
@@ -535,6 +542,27 @@ The members specific to ``codemodel`` objects are:
array of entries corresponding to the targets. Each entry is an
unsigned integer 0-based index into the main ``targets`` array.
``minimumCMakeVersion``
Optional member present when a minimum required version of CMake is
known for the directory. This is the ``<min>`` version given to the
most local call to the :command:`cmake_minimum_required(VERSION)`
command in the directory itself or one of its ancestors.
The value is a JSON object with one member:
``string``
A string specifying the minimum required version in the format::
<major>.<minor>[.<patch>[.<tweak>]][<suffix>]
Each component is an unsigned integer and the suffix may be an
arbitrary string.
``hasInstallRule``
Optional member that is present with boolean value ``true`` when
the directory or one of its subdirectories contains any
:command:`install` rules, i.e. whether a ``make install``
or equivalent rule is available.
``projects``
A JSON array of entries corresponding to the top-level project
and sub-projects defined in the build system. Each (sub-)project

View File

@@ -8,6 +8,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmInstallGenerator.h"
#include "cmInstallSubdirectoryGenerator.h"
#include "cmInstallTargetGenerator.h"
#include "cmLinkLineComputer.h"
#include "cmListFileCache.h"
@@ -62,8 +63,10 @@ class CodemodelConfig
struct Directory
{
cmStateSnapshot Snapshot;
cmLocalGenerator const* LocalGenerator = nullptr;
Json::Value TargetIndexes = Json::arrayValue;
Json::ArrayIndex ProjectIndex;
bool HasInstallRule = false;
};
std::map<cmStateSnapshot, Json::ArrayIndex, cmStateSnapshot::StrictWeakOrder>
DirectoryMap;
@@ -99,6 +102,8 @@ class CodemodelConfig
Json::Value DumpProjects();
Json::Value DumpProject(Project& p);
Json::Value DumpMinimumCMakeVersion(cmStateSnapshot s);
public:
CodemodelConfig(cmFileAPI& fileAPI, unsigned long version,
std::string const& config);
@@ -396,11 +401,36 @@ void CodemodelConfig::ProcessDirectories()
this->Directories.emplace_back();
Directory& d = this->Directories[directoryIndex];
d.Snapshot = lg->GetStateSnapshot().GetBuildsystemDirectory();
d.LocalGenerator = lg;
this->DirectoryMap[d.Snapshot] = directoryIndex;
d.ProjectIndex = this->AddProject(d.Snapshot);
this->Projects[d.ProjectIndex].DirectoryIndexes.append(directoryIndex);
}
// Update directories in reverse order to process children before parents.
for (auto di = this->Directories.rbegin(); di != this->Directories.rend();
++di) {
Directory& d = *di;
// Accumulate the presence of install rules on the way up.
for (auto gen : d.LocalGenerator->GetMakefile()->GetInstallGenerators()) {
if (!dynamic_cast<cmInstallSubdirectoryGenerator*>(gen)) {
d.HasInstallRule = true;
break;
}
}
if (!d.HasInstallRule) {
for (cmStateSnapshot const& child : d.Snapshot.GetChildren()) {
cmStateSnapshot childDir = child.GetBuildsystemDirectory();
Json::ArrayIndex const childIndex = this->GetDirectoryIndex(childDir);
if (this->Directories[childIndex].HasInstallRule) {
d.HasInstallRule = true;
break;
}
}
}
}
}
Json::ArrayIndex CodemodelConfig::GetDirectoryIndex(cmLocalGenerator const* lg)
@@ -531,6 +561,15 @@ Json::Value CodemodelConfig::DumpDirectory(Directory& d)
directory["targetIndexes"] = std::move(d.TargetIndexes);
}
Json::Value minimumCMakeVersion = this->DumpMinimumCMakeVersion(d.Snapshot);
if (!minimumCMakeVersion.isNull()) {
directory["minimumCMakeVersion"] = std::move(minimumCMakeVersion);
}
if (d.HasInstallRule) {
directory["hasInstallRule"] = true;
}
return directory;
}
@@ -566,6 +605,17 @@ Json::Value CodemodelConfig::DumpProject(Project& p)
return project;
}
Json::Value CodemodelConfig::DumpMinimumCMakeVersion(cmStateSnapshot s)
{
Json::Value minimumCMakeVersion;
if (std::string const* def =
s.GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION")) {
minimumCMakeVersion = Json::objectValue;
minimumCMakeVersion["string"] = *def;
}
return minimumCMakeVersion;
}
Target::Target(cmGeneratorTarget* gt, std::string const& config)
: GT(gt)
, Config(config)

View File

@@ -64,6 +64,16 @@ def check_directory(c):
missing_exception=lambda e: "Target ID: %s" % e,
extra_exception=lambda a: "Target ID: %s" % c["targets"][a]["id"])
if expected["minimumCMakeVersion"] is not None:
expected_keys.append("minimumCMakeVersion")
assert is_dict(actual["minimumCMakeVersion"])
assert sorted(actual["minimumCMakeVersion"].keys()) == ["string"]
assert is_string(actual["minimumCMakeVersion"]["string"], expected["minimumCMakeVersion"])
if expected["hasInstallRule"] is not None:
expected_keys.append("hasInstallRule")
assert is_bool(actual["hasInstallRule"], expected["hasInstallRule"])
assert sorted(actual.keys()) == sorted(expected_keys)
return _check
@@ -448,6 +458,8 @@ def gen_check_directories(c, g):
"^interface_exe::@6890427a1f51a3e7e1df$",
],
"projectName": "codemodel-v2",
"minimumCMakeVersion": "3.12",
"hasInstallRule": True,
},
{
"source": "^alias$",
@@ -461,6 +473,8 @@ def gen_check_directories(c, g):
"^cxx_alias_exe::@53632cba2752272bb008$",
],
"projectName": "Alias",
"minimumCMakeVersion": "3.12",
"hasInstallRule": None,
},
{
"source": "^custom$",
@@ -474,6 +488,8 @@ def gen_check_directories(c, g):
"^custom_tgt::@c11385ffed57b860da63$",
],
"projectName": "Custom",
"minimumCMakeVersion": "3.12",
"hasInstallRule": None,
},
{
"source": "^cxx$",
@@ -491,6 +507,8 @@ def gen_check_directories(c, g):
"^cxx_static_lib::@a56b12a3f5c0529fb296$",
],
"projectName": "Cxx",
"minimumCMakeVersion": "3.12",
"hasInstallRule": None,
},
{
"source": "^imported$",
@@ -507,6 +525,8 @@ def gen_check_directories(c, g):
"^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
],
"projectName": "Imported",
"minimumCMakeVersion": "3.12",
"hasInstallRule": None,
},
{
"source": "^object$",
@@ -522,6 +542,8 @@ def gen_check_directories(c, g):
"^cxx_object_lib::@5ed5358f70faf8d8af7a$",
],
"projectName": "Object",
"minimumCMakeVersion": "3.13",
"hasInstallRule": True,
},
{
"source": "^dir$",
@@ -542,6 +564,8 @@ def gen_check_directories(c, g):
"childSources": None,
"targetIds": None,
"projectName": "codemodel-v2",
"minimumCMakeVersion": "3.12",
"hasInstallRule": None,
},
{
"source": "^.*/Tests/RunCMake/FileAPIExternalSource$",
@@ -554,6 +578,8 @@ def gen_check_directories(c, g):
"^generated_exe::@[0-9a-f]+$",
],
"projectName": "External",
"minimumCMakeVersion": "3.12",
"hasInstallRule": None,
},
]