mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-14 02:08:27 +08:00
fileapi: Add codemodelVersion fields to target and directory objects
This will allow JSON schemas for these two types of files to describe the version-specific content without requiring any outside information. Fixes: #27031
This commit is contained in:
@@ -704,6 +704,19 @@ A codemodel "directory" object is referenced by a `"codemodel" version 2`_
|
||||
object's ``directories`` array. Each "directory" object is a JSON object
|
||||
with members:
|
||||
|
||||
``codemodelVersion``
|
||||
This specifies the codemodel version this file is part of. It will match
|
||||
the ``version`` field of the codemodel object kind that references this file.
|
||||
It is a JSON object with the following members:
|
||||
|
||||
``major``
|
||||
The codemodel major version.
|
||||
|
||||
``minor``
|
||||
The codemodel minor version.
|
||||
|
||||
This field was added in codemodel version 2.9.
|
||||
|
||||
``paths``
|
||||
A JSON object containing members:
|
||||
|
||||
@@ -980,6 +993,19 @@ A codemodel "target" object is referenced by a `"codemodel" version 2`_
|
||||
object's ``targets`` array. Each "target" object is a JSON object
|
||||
with members:
|
||||
|
||||
``codemodelVersion``
|
||||
This specifies the codemodel version this file is part of. It will match
|
||||
the ``version`` field of the codemodel object kind that references this file.
|
||||
It is a JSON object with the following members:
|
||||
|
||||
``major``
|
||||
The codemodel major version.
|
||||
|
||||
``minor``
|
||||
The codemodel minor version.
|
||||
|
||||
This field was added in codemodel version 2.9.
|
||||
|
||||
``name``
|
||||
A string specifying the logical name of the target.
|
||||
|
||||
|
@@ -0,0 +1,8 @@
|
||||
codemodel-version-directory-target-objects
|
||||
------------------------------------------
|
||||
|
||||
* The :manual:`cmake-file-api(7)` "codemodel" version 2 ``version`` field has
|
||||
been updated to 2.9.
|
||||
|
||||
* The :manual:`cmake-file-api(7)` "codemodel" version 2 "target" and
|
||||
"directory" objects gained a new ``codemodelVersion`` field.
|
@@ -789,8 +789,10 @@ std::string cmFileAPI::NoSupportedVersion(
|
||||
|
||||
// The "codemodel" object kind.
|
||||
|
||||
// Update Help/manual/cmake-file-api.7.rst when updating this constant.
|
||||
static unsigned int const CodeModelV2Minor = 8;
|
||||
// Update the following files as well when updating this constant:
|
||||
// Help/manual/cmake-file-api.7.rst
|
||||
// Tests/RunCMake/FileAPI/codemodel-v2-check.py (check_objects())
|
||||
static unsigned int const CodeModelV2Minor = 9;
|
||||
|
||||
void cmFileAPI::BuildClientRequestCodeModel(
|
||||
ClientRequest& r, std::vector<RequestVersion> const& versions)
|
||||
@@ -809,7 +811,9 @@ void cmFileAPI::BuildClientRequestCodeModel(
|
||||
|
||||
Json::Value cmFileAPI::BuildCodeModel(Object const& object)
|
||||
{
|
||||
Json::Value codemodel = cmFileAPICodemodelDump(*this, object.Version);
|
||||
assert(object.Version == 2);
|
||||
Json::Value codemodel =
|
||||
cmFileAPICodemodelDump(*this, object.Version, CodeModelV2Minor);
|
||||
codemodel["kind"] = this->ObjectKindName(object.Kind);
|
||||
|
||||
Json::Value& version = codemodel["version"];
|
||||
|
@@ -64,6 +64,9 @@ public:
|
||||
bool AddProjectQuery(ObjectKind kind, unsigned majorVersion,
|
||||
unsigned minorVersion);
|
||||
|
||||
/** Build a JSON object with major and minor fields. */
|
||||
static Json::Value BuildVersion(unsigned int major, unsigned int minor);
|
||||
|
||||
private:
|
||||
cmake* CMakeInstance;
|
||||
|
||||
@@ -196,8 +199,6 @@ private:
|
||||
static char const* ObjectKindName(ObjectKind kind);
|
||||
static std::string ObjectName(Object const& o);
|
||||
|
||||
static Json::Value BuildVersion(unsigned int major, unsigned int minor);
|
||||
|
||||
Json::Value BuildObject(Object const& object);
|
||||
|
||||
ClientRequests BuildClientRequests(Json::Value const& requests);
|
||||
|
@@ -223,21 +223,24 @@ Json::Value BacktraceData::Dump()
|
||||
class Codemodel
|
||||
{
|
||||
cmFileAPI& FileAPI;
|
||||
unsigned int Version;
|
||||
unsigned int VersionMajor;
|
||||
unsigned int VersionMinor;
|
||||
|
||||
Json::Value DumpPaths();
|
||||
Json::Value DumpConfigurations();
|
||||
Json::Value DumpConfiguration(std::string const& config);
|
||||
|
||||
public:
|
||||
Codemodel(cmFileAPI& fileAPI, unsigned int version);
|
||||
Codemodel(cmFileAPI& fileAPI, unsigned int versionMajor,
|
||||
unsigned int versionMinor);
|
||||
Json::Value Dump();
|
||||
};
|
||||
|
||||
class CodemodelConfig
|
||||
{
|
||||
cmFileAPI& FileAPI;
|
||||
unsigned int Version;
|
||||
unsigned int VersionMajor;
|
||||
unsigned int VersionMinor;
|
||||
std::string const& Config;
|
||||
std::string TopSource;
|
||||
std::string TopBuild;
|
||||
@@ -290,8 +293,8 @@ class CodemodelConfig
|
||||
Json::Value DumpMinimumCMakeVersion(cmStateSnapshot s);
|
||||
|
||||
public:
|
||||
CodemodelConfig(cmFileAPI& fileAPI, unsigned int version,
|
||||
std::string const& config);
|
||||
CodemodelConfig(cmFileAPI& fileAPI, unsigned int versionMajor,
|
||||
unsigned int versionMinor, std::string const& config);
|
||||
Json::Value Dump();
|
||||
};
|
||||
|
||||
@@ -392,6 +395,8 @@ namespace {
|
||||
class DirectoryObject
|
||||
{
|
||||
cmLocalGenerator const* LG = nullptr;
|
||||
unsigned int VersionMajor;
|
||||
unsigned int VersionMinor;
|
||||
std::string const& Config;
|
||||
TargetIndexMapType& TargetIndexMap;
|
||||
std::string TopSource;
|
||||
@@ -409,7 +414,8 @@ class DirectoryObject
|
||||
std::string const& toPath);
|
||||
|
||||
public:
|
||||
DirectoryObject(cmLocalGenerator const* lg, std::string const& config,
|
||||
DirectoryObject(cmLocalGenerator const* lg, unsigned int versionMajor,
|
||||
unsigned int versionMinor, std::string const& config,
|
||||
TargetIndexMapType& targetIndexMap);
|
||||
Json::Value Dump();
|
||||
};
|
||||
@@ -417,6 +423,8 @@ public:
|
||||
class Target
|
||||
{
|
||||
cmGeneratorTarget* GT;
|
||||
unsigned int VersionMajor;
|
||||
unsigned int VersionMinor;
|
||||
std::string const& Config;
|
||||
std::string TopSource;
|
||||
std::string TopBuild;
|
||||
@@ -511,13 +519,16 @@ class Target
|
||||
Json::Value DumpDebugger();
|
||||
|
||||
public:
|
||||
Target(cmGeneratorTarget* gt, std::string const& config);
|
||||
Target(cmGeneratorTarget* gt, unsigned int versionMajor,
|
||||
unsigned int versionMinor, std::string const& config);
|
||||
Json::Value Dump();
|
||||
};
|
||||
|
||||
Codemodel::Codemodel(cmFileAPI& fileAPI, unsigned int version)
|
||||
Codemodel::Codemodel(cmFileAPI& fileAPI, unsigned int versionMajor,
|
||||
unsigned int versionMinor)
|
||||
: FileAPI(fileAPI)
|
||||
, Version(version)
|
||||
, VersionMajor(versionMajor)
|
||||
, VersionMinor(versionMinor)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -557,19 +568,21 @@ Json::Value Codemodel::DumpConfigurations()
|
||||
|
||||
Json::Value Codemodel::DumpConfiguration(std::string const& config)
|
||||
{
|
||||
CodemodelConfig configuration(this->FileAPI, this->Version, config);
|
||||
CodemodelConfig configuration(this->FileAPI, this->VersionMajor,
|
||||
this->VersionMinor, config);
|
||||
return configuration.Dump();
|
||||
}
|
||||
|
||||
CodemodelConfig::CodemodelConfig(cmFileAPI& fileAPI, unsigned int version,
|
||||
CodemodelConfig::CodemodelConfig(cmFileAPI& fileAPI, unsigned int versionMajor,
|
||||
unsigned int versionMinor,
|
||||
std::string const& config)
|
||||
: FileAPI(fileAPI)
|
||||
, Version(version)
|
||||
, VersionMajor(versionMajor)
|
||||
, VersionMinor(versionMinor)
|
||||
, Config(config)
|
||||
, TopSource(this->FileAPI.GetCMakeInstance()->GetHomeDirectory())
|
||||
, TopBuild(this->FileAPI.GetCMakeInstance()->GetHomeOutputDirectory())
|
||||
{
|
||||
static_cast<void>(this->Version);
|
||||
}
|
||||
|
||||
Json::Value CodemodelConfig::Dump()
|
||||
@@ -701,7 +714,7 @@ Json::Value CodemodelConfig::DumpTargets()
|
||||
Json::Value CodemodelConfig::DumpTarget(cmGeneratorTarget* gt,
|
||||
Json::ArrayIndex ti)
|
||||
{
|
||||
Target t(gt, this->Config);
|
||||
Target t(gt, this->VersionMajor, this->VersionMinor, this->Config);
|
||||
std::string prefix = "target-" + gt->GetName();
|
||||
if (!this->Config.empty()) {
|
||||
prefix += "-" + this->Config;
|
||||
@@ -797,7 +810,8 @@ Json::Value CodemodelConfig::DumpDirectoryObject(Directory& d)
|
||||
prefix += "-" + this->Config;
|
||||
}
|
||||
|
||||
DirectoryObject dir(d.LocalGenerator, this->Config, this->TargetIndexMap);
|
||||
DirectoryObject dir(d.LocalGenerator, this->VersionMajor, this->VersionMinor,
|
||||
this->Config, this->TargetIndexMap);
|
||||
return this->FileAPI.MaybeJsonFile(dir.Dump(), prefix);
|
||||
}
|
||||
|
||||
@@ -844,9 +858,13 @@ Json::Value CodemodelConfig::DumpMinimumCMakeVersion(cmStateSnapshot s)
|
||||
}
|
||||
|
||||
DirectoryObject::DirectoryObject(cmLocalGenerator const* lg,
|
||||
unsigned int versionMajor,
|
||||
unsigned int versionMinor,
|
||||
std::string const& config,
|
||||
TargetIndexMapType& targetIndexMap)
|
||||
: LG(lg)
|
||||
, VersionMajor(versionMajor)
|
||||
, VersionMinor(versionMinor)
|
||||
, Config(config)
|
||||
, TargetIndexMap(targetIndexMap)
|
||||
, TopSource(lg->GetGlobalGenerator()->GetCMakeInstance()->GetHomeDirectory())
|
||||
@@ -859,6 +877,8 @@ DirectoryObject::DirectoryObject(cmLocalGenerator const* lg,
|
||||
Json::Value DirectoryObject::Dump()
|
||||
{
|
||||
Json::Value directoryObject = Json::objectValue;
|
||||
directoryObject["codemodelVersion"] =
|
||||
cmFileAPI::BuildVersion(this->VersionMajor, this->VersionMinor);
|
||||
directoryObject["paths"] = this->DumpPaths();
|
||||
directoryObject["installers"] = this->DumpInstallers();
|
||||
directoryObject["backtraceGraph"] = this->Backtraces.Dump();
|
||||
@@ -1186,8 +1206,11 @@ Json::Value DirectoryObject::DumpInstallerPath(std::string const& top,
|
||||
return installPath;
|
||||
}
|
||||
|
||||
Target::Target(cmGeneratorTarget* gt, std::string const& config)
|
||||
Target::Target(cmGeneratorTarget* gt, unsigned int versionMajor,
|
||||
unsigned int versionMinor, std::string const& config)
|
||||
: GT(gt)
|
||||
, VersionMajor(versionMajor)
|
||||
, VersionMinor(versionMinor)
|
||||
, Config(config)
|
||||
, TopSource(gt->GetGlobalGenerator()->GetCMakeInstance()->GetHomeDirectory())
|
||||
, TopBuild(
|
||||
@@ -1203,6 +1226,8 @@ Json::Value Target::Dump()
|
||||
|
||||
cmStateEnums::TargetType const type = this->GT->GetType();
|
||||
|
||||
target["codemodelVersion"] =
|
||||
cmFileAPI::BuildVersion(this->VersionMajor, this->VersionMinor);
|
||||
target["name"] = this->GT->GetName();
|
||||
target["type"] = cmState::GetTargetTypeName(type);
|
||||
target["id"] = TargetId(this->GT, this->TopBuild);
|
||||
@@ -2154,8 +2179,10 @@ Json::Value Target::DumpDebugger()
|
||||
return debuggerInformation;
|
||||
}
|
||||
|
||||
Json::Value cmFileAPICodemodelDump(cmFileAPI& fileAPI, unsigned int version)
|
||||
Json::Value cmFileAPICodemodelDump(cmFileAPI& fileAPI,
|
||||
unsigned int versionMajor,
|
||||
unsigned int versionMinor)
|
||||
{
|
||||
Codemodel codemodel(fileAPI, version);
|
||||
Codemodel codemodel(fileAPI, versionMajor, versionMinor);
|
||||
return codemodel.Dump();
|
||||
}
|
||||
|
@@ -9,4 +9,5 @@
|
||||
class cmFileAPI;
|
||||
|
||||
extern Json::Value cmFileAPICodemodelDump(cmFileAPI& fileAPI,
|
||||
unsigned int version);
|
||||
unsigned int majorVersion,
|
||||
unsigned int minorVersion);
|
||||
|
@@ -1 +1 @@
|
||||
^{"debugger":(true|false),"fileApi":{"requests":\[{"kind":"codemodel","version":\[{"major":2,"minor":8}]},{"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":{.*}}$
|
||||
^{"debugger":(true|false),"fileApi":{"requests":\[{"kind":"codemodel","version":\[{"major":2,"minor":9}]},{"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":{.*}}$
|
||||
|
@@ -12,7 +12,9 @@ def read_codemodel_json_data(filename):
|
||||
def check_objects(o, g):
|
||||
assert is_list(o)
|
||||
assert len(o) == 1
|
||||
check_index_object(o[0], "codemodel", 2, 8, check_object_codemodel(g))
|
||||
major = 2
|
||||
minor = 9
|
||||
check_index_object(o[0], "codemodel", major, minor, check_object_codemodel(g, major, minor))
|
||||
|
||||
def check_backtrace(t, b, backtrace):
|
||||
btg = t["backtraceGraph"]
|
||||
@@ -52,7 +54,7 @@ def check_backtraces(t, actual, expected):
|
||||
check_backtrace(t, actual[i], expected[i])
|
||||
i += 1
|
||||
|
||||
def check_directory(c):
|
||||
def check_directory(c, major, minor):
|
||||
def _check(actual, expected):
|
||||
assert is_dict(actual)
|
||||
expected_keys = ["build", "jsonFile", "source", "projectIndex"]
|
||||
@@ -100,7 +102,12 @@ def check_directory(c):
|
||||
d = json.load(f)
|
||||
|
||||
assert is_dict(d)
|
||||
assert sorted(d.keys()) == ["backtraceGraph", "installers", "paths"]
|
||||
assert sorted(d.keys()) == ["backtraceGraph", "codemodelVersion", "installers", "paths"]
|
||||
|
||||
# We get the values for major and minor directly rather than from the "expected" data.
|
||||
# This avoids having to update every data file any time the major or minor version changes.
|
||||
assert is_int(d["codemodelVersion"]["major"], major)
|
||||
assert is_int(d["codemodelVersion"]["minor"], minor)
|
||||
|
||||
assert is_string(d["paths"]["source"], actual["source"])
|
||||
assert is_string(d["paths"]["build"], actual["build"])
|
||||
@@ -266,7 +273,7 @@ def check_backtrace_graph(btg):
|
||||
|
||||
assert sorted(n.keys()) == sorted(expected_keys)
|
||||
|
||||
def check_target(c):
|
||||
def check_target(c, major, minor):
|
||||
def _check(actual, expected):
|
||||
assert is_dict(actual)
|
||||
assert sorted(actual.keys()) == ["directoryIndex", "id", "jsonFile", "name", "projectIndex"]
|
||||
@@ -281,7 +288,7 @@ def check_target(c):
|
||||
with open(filepath) as f:
|
||||
obj = json.load(f)
|
||||
|
||||
expected_keys = ["name", "id", "type", "backtraceGraph", "paths", "sources"]
|
||||
expected_keys = ["codemodelVersion", "name", "id", "type", "backtraceGraph", "paths", "sources"]
|
||||
assert is_dict(obj)
|
||||
assert is_string(obj["name"], expected["name"])
|
||||
assert matches(obj["id"], expected["id"])
|
||||
@@ -293,6 +300,13 @@ def check_target(c):
|
||||
assert matches(obj["paths"]["build"], expected["build"])
|
||||
assert matches(obj["paths"]["source"], expected["source"])
|
||||
|
||||
# We get the values for major and minor directly rather than from the "expected" data.
|
||||
# This avoids having to update every data file any time the major or minor version changes.
|
||||
assert is_dict(obj["codemodelVersion"])
|
||||
assert sorted(obj["codemodelVersion"].keys()) == ["major", "minor"]
|
||||
assert is_int(obj["codemodelVersion"]["major"], major)
|
||||
assert is_int(obj["codemodelVersion"]["minor"], minor)
|
||||
|
||||
def check_file_set(actual, expected):
|
||||
assert is_dict(actual)
|
||||
expected_keys = ["name", "type", "visibility", "baseDirectories"]
|
||||
@@ -794,9 +808,9 @@ def gen_check_directories(c, g):
|
||||
|
||||
return expected
|
||||
|
||||
def check_directories(c, g):
|
||||
def check_directories(c, g, major, minor):
|
||||
check_list_match(lambda a, e: matches(a["source"], e["source"]), c["directories"], gen_check_directories(c, g),
|
||||
check=check_directory(c),
|
||||
check=check_directory(c, major, minor),
|
||||
check_exception=lambda a, e: "Directory source: %s" % a["source"],
|
||||
missing_exception=lambda e: "Directory source: %s" % e["source"],
|
||||
extra_exception=lambda a: "Directory source: %s" % a["source"])
|
||||
@@ -1001,10 +1015,10 @@ def gen_check_targets(c, g, inSource):
|
||||
|
||||
return expected
|
||||
|
||||
def check_targets(c, g, inSource):
|
||||
def check_targets(c, g, major, minor, inSource):
|
||||
check_list_match(lambda a, e: matches(a["id"], e["id"]),
|
||||
c["targets"], gen_check_targets(c, g, inSource),
|
||||
check=check_target(c),
|
||||
check=check_target(c, major, minor),
|
||||
check_exception=lambda a, e: "Target ID: %s" % a["id"],
|
||||
missing_exception=lambda e: "Target ID: %s" % e["id"],
|
||||
extra_exception=lambda a: "Target ID: %s" % a["id"])
|
||||
@@ -1045,14 +1059,14 @@ def check_projects(c, g):
|
||||
missing_exception=lambda e: "Project name: %s" % e["name"],
|
||||
extra_exception=lambda a: "Project name: %s" % a["name"])
|
||||
|
||||
def check_object_codemodel_configuration(c, g, inSource):
|
||||
def check_object_codemodel_configuration(c, g, major, minor, inSource):
|
||||
assert sorted(c.keys()) == ["directories", "name", "projects", "targets"]
|
||||
assert is_string(c["name"])
|
||||
check_directories(c, g)
|
||||
check_targets(c, g, inSource)
|
||||
check_directories(c, g, major, minor)
|
||||
check_targets(c, g, major, minor, inSource)
|
||||
check_projects(c, g)
|
||||
|
||||
def check_object_codemodel(g):
|
||||
def check_object_codemodel(g, major, minor):
|
||||
def _check(o):
|
||||
assert sorted(o.keys()) == ["configurations", "kind", "paths", "version"]
|
||||
# The "kind" and "version" members are handled by check_index_object.
|
||||
@@ -1070,7 +1084,7 @@ def check_object_codemodel(g):
|
||||
assert o["configurations"][0]["name"] in ("", "Debug", "Release", "RelWithDebInfo", "MinSizeRel")
|
||||
|
||||
for c in o["configurations"]:
|
||||
check_object_codemodel_configuration(c, g, inSource)
|
||||
check_object_codemodel_configuration(c, g, major, minor, inSource)
|
||||
return _check
|
||||
|
||||
cxx_compiler_id = sys.argv[2]
|
||||
|
Reference in New Issue
Block a user