Skip to content
Snippets Groups Projects
Commit eb8c7676 authored by Brad King's avatar Brad King Committed by Kyle Edwards
Browse files

fileapi: extend codemodel v2 with a project model

Offer clients a `project()`-centric view of the build system.  This is
similar to the directory-centric view but consolidates subdirectories
that do not call `project()` with a new project name.

Issue: #18398
Co-Author: Kyle Edwards <kyle.edwards@kitware.com>
parent 42f0125c
No related branches found
No related tags found
No related merge requests found
......@@ -432,24 +432,35 @@ Version 1 does not exist to avoid confusion with that from
"source": ".",
"build": ".",
"childIndexes": [ 1 ],
"projectIndex": 0,
"targetIndexes": [ 0 ]
},
{
"source": "sub",
"build": "sub",
"parentIndex": 0,
"projectIndex": 0,
"targetIndexes": [ 1 ]
}
],
"projects": [
{
"name": "MyProject",
"directoryIndexes": [ 0, 1 ],
"targetIndexes": [ 0, 1 ]
}
],
"targets": [
{
"name": "MyExecutable",
"directoryIndex": 0,
"projectIndex": 0,
"jsonFile": "<file>"
},
{
"name": "MyLibrary",
"directoryIndex": 1,
"projectIndex": 0,
"jsonFile": "<file>"
}
]
......@@ -514,12 +525,53 @@ The members specific to ``codemodel`` objects are:
command. Each entry is an unsigned integer 0-based index of another
entry in the main ``directories`` array.
``projectIndex``
An unsigned integer 0-based index into the main ``projects`` array
indicating the build system project to which the this directory belongs.
``targetIndexes``
Optional member that is present when the directory itself has targets,
excluding those belonging to subdirectories. The value is a JSON
array of entries corresponding to the targets. Each entry is an
unsigned integer 0-based index into the main ``targets`` array.
``projects``
A JSON array of entries corresponding to the top-level project
and sub-projects defined in the build system. Each (sub-)project
corresponds to a source directory whose ``CMakeLists.txt`` file
calls the :command:`project` command with a project name different
from its parent directory. The first entry corresponds to the
top-level project.
Each entry is a JSON object containing members:
``name``
A string specifying the name given to the :command:`project` command.
``parentIndex``
Optional member that is present when the project is not top-level.
The value is an unsigned integer 0-based index of another entry in
the main ``projects`` array that corresponds to the parent project
that added this project as a sub-project.
``childIndexes``
Optional member that is present when the project has sub-projects.
The value is a JSON array of entries corresponding to the sub-projects.
Each entry is an unsigned integer 0-based index of another
entry in the main ``projects`` array.
``directoryIndexes``
A JSON array of entries corresponding to build system directories
that are part of the project. The first entry corresponds to the
top-level directory of the project. Each entry is an unsigned
integer 0-based index into the main ``directories`` array.
``targetIndexes``
Optional member that is present when the project itself has targets,
excluding those belonging to sub-projects. The value is a JSON
array of entries corresponding to the targets. Each entry is an
unsigned integer 0-based index into the main ``targets`` array.
``targets``
A JSON array of entries corresponding to the build system targets.
Such targets are created by calls to :command:`add_executable`,
......@@ -538,6 +590,10 @@ The members specific to ``codemodel`` objects are:
An unsigned integer 0-based index into the main ``directories`` array
indicating the build system directory in which the target is defined.
``projectIndex``
An unsigned integer 0-based index into the main ``projects`` array
indicating the build system project in which the target is defined.
``jsonFile``
A JSON string specifying a path relative to the codemodel file
to another JSON file containing a
......
......@@ -63,22 +63,42 @@ class CodemodelConfig
{
cmStateSnapshot Snapshot;
Json::Value TargetIndexes = Json::arrayValue;
Json::ArrayIndex ProjectIndex;
};
std::map<cmStateSnapshot, Json::ArrayIndex, cmStateSnapshot::StrictWeakOrder>
DirectoryMap;
std::vector<Directory> Directories;
struct Project
{
cmStateSnapshot Snapshot;
static const Json::ArrayIndex NoParentIndex =
static_cast<Json::ArrayIndex>(-1);
Json::ArrayIndex ParentIndex = NoParentIndex;
Json::Value ChildIndexes = Json::arrayValue;
Json::Value DirectoryIndexes = Json::arrayValue;
Json::Value TargetIndexes = Json::arrayValue;
};
std::map<cmStateSnapshot, Json::ArrayIndex, cmStateSnapshot::StrictWeakOrder>
ProjectMap;
std::vector<Project> Projects;
void ProcessDirectories();
Json::ArrayIndex GetDirectoryIndex(cmLocalGenerator const* lg);
Json::ArrayIndex GetDirectoryIndex(cmStateSnapshot s);
Json::ArrayIndex AddProject(cmStateSnapshot s);
Json::Value DumpTargets();
Json::Value DumpTarget(cmGeneratorTarget* gt, Json::ArrayIndex ti);
Json::Value DumpDirectories();
Json::Value DumpDirectory(Directory& d);
Json::Value DumpProjects();
Json::Value DumpProject(Project& p);
public:
CodemodelConfig(cmFileAPI& fileAPI, unsigned long version,
std::string const& config);
......@@ -358,6 +378,7 @@ Json::Value CodemodelConfig::Dump()
this->ProcessDirectories();
configuration["targets"] = this->DumpTargets();
configuration["directories"] = this->DumpDirectories();
configuration["projects"] = this->DumpProjects();
return configuration;
}
......@@ -376,6 +397,9 @@ void CodemodelConfig::ProcessDirectories()
Directory& d = this->Directories[directoryIndex];
d.Snapshot = lg->GetStateSnapshot().GetBuildsystemDirectory();
this->DirectoryMap[d.Snapshot] = directoryIndex;
d.ProjectIndex = this->AddProject(d.Snapshot);
this->Projects[d.ProjectIndex].DirectoryIndexes.append(directoryIndex);
}
}
......@@ -392,6 +416,29 @@ Json::ArrayIndex CodemodelConfig::GetDirectoryIndex(cmStateSnapshot s)
return i->second;
}
Json::ArrayIndex CodemodelConfig::AddProject(cmStateSnapshot s)
{
cmStateSnapshot ps = s.GetBuildsystemDirectoryParent();
if (ps.IsValid() && ps.GetProjectName() == s.GetProjectName()) {
// This directory is part of its parent directory project.
Json::ArrayIndex const parentDirIndex = this->GetDirectoryIndex(ps);
return this->Directories[parentDirIndex].ProjectIndex;
}
// This directory starts a new project.
auto projectIndex = static_cast<Json::ArrayIndex>(this->Projects.size());
this->Projects.emplace_back();
Project& p = this->Projects[projectIndex];
p.Snapshot = s;
this->ProjectMap[s] = projectIndex;
if (ps.IsValid()) {
Json::ArrayIndex const parentDirIndex = this->GetDirectoryIndex(ps);
p.ParentIndex = this->Directories[parentDirIndex].ProjectIndex;
this->Projects[p.ParentIndex].ChildIndexes.append(projectIndex);
}
return projectIndex;
}
Json::Value CodemodelConfig::DumpTargets()
{
Json::Value targets = Json::arrayValue;
......@@ -437,6 +484,11 @@ Json::Value CodemodelConfig::DumpTarget(cmGeneratorTarget* gt,
target["directoryIndex"] = di;
this->Directories[di].TargetIndexes.append(ti);
// Cross-reference project containing target.
Json::ArrayIndex pi = this->Directories[di].ProjectIndex;
target["projectIndex"] = pi;
this->Projects[pi].TargetIndexes.append(ti);
return target;
}
......@@ -473,6 +525,8 @@ Json::Value CodemodelConfig::DumpDirectory(Directory& d)
directory["childIndexes"] = std::move(childIndexes);
}
directory["projectIndex"] = d.ProjectIndex;
if (!d.TargetIndexes.empty()) {
directory["targetIndexes"] = std::move(d.TargetIndexes);
}
......@@ -480,6 +534,38 @@ Json::Value CodemodelConfig::DumpDirectory(Directory& d)
return directory;
}
Json::Value CodemodelConfig::DumpProjects()
{
Json::Value projects = Json::arrayValue;
for (Project& p : this->Projects) {
projects.append(this->DumpProject(p));
}
return projects;
}
Json::Value CodemodelConfig::DumpProject(Project& p)
{
Json::Value project = Json::objectValue;
project["name"] = p.Snapshot.GetProjectName();
if (p.ParentIndex != Project::NoParentIndex) {
project["parentIndex"] = p.ParentIndex;
}
if (!p.ChildIndexes.empty()) {
project["childIndexes"] = std::move(p.ChildIndexes);
}
project["directoryIndexes"] = std::move(p.DirectoryIndexes);
if (!p.TargetIndexes.empty()) {
project["targetIndexes"] = std::move(p.TargetIndexes);
}
return project;
}
Target::Target(cmGeneratorTarget* gt, std::string const& config)
: GT(gt)
, Config(config)
......
This diff is collapsed.
......@@ -20,6 +20,7 @@ add_subdirectory(object)
add_subdirectory(imported)
add_subdirectory(custom)
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../FileAPIExternalSource" "${CMAKE_CURRENT_BINARY_DIR}/../FileAPIExternalBuild")
add_subdirectory(dir)
set_property(TARGET c_shared_lib PROPERTY LIBRARY_OUTPUT_DIRECTORY lib)
set_property(TARGET c_shared_lib PROPERTY RUNTIME_OUTPUT_DIRECTORY lib)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment