summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/manual/cmake-file-api.7.rst56
-rw-r--r--Source/cmFileAPICodemodel.cxx86
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-check.py261
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2.cmake1
4 files changed, 401 insertions, 3 deletions
diff --git a/Help/manual/cmake-file-api.7.rst b/Help/manual/cmake-file-api.7.rst
index 0dbdfd7..f35e351 100644
--- a/Help/manual/cmake-file-api.7.rst
+++ b/Help/manual/cmake-file-api.7.rst
@@ -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
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index 3d4a7cf..d432c1e 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -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)
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
index e82bddd..8111c79 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
@@ -39,9 +39,12 @@ def check_backtrace(t, b, backtrace):
def check_directory(c):
def _check(actual, expected):
assert is_dict(actual)
- expected_keys = ["build", "source"]
+ expected_keys = ["build", "source", "projectIndex"]
assert matches(actual["build"], expected["build"])
+ assert is_int(actual["projectIndex"])
+ assert is_string(c["projects"][actual["projectIndex"]]["name"], expected["projectName"])
+
if expected["parentSource"] is not None:
expected_keys.append("parentIndex")
assert is_int(actual["parentIndex"])
@@ -102,11 +105,13 @@ def check_target_backtrace_graph(t):
def check_target(c):
def _check(actual, expected):
assert is_dict(actual)
- assert sorted(actual.keys()) == ["directoryIndex", "id", "jsonFile", "name"]
+ assert sorted(actual.keys()) == ["directoryIndex", "id", "jsonFile", "name", "projectIndex"]
assert is_int(actual["directoryIndex"])
assert matches(c["directories"][actual["directoryIndex"]]["source"], expected["directorySource"])
assert is_string(actual["name"], expected["name"])
assert is_string(actual["jsonFile"])
+ assert is_int(actual["projectIndex"])
+ assert is_string(c["projects"][actual["projectIndex"]]["name"], expected["projectName"])
filepath = os.path.join(reply_dir, actual["jsonFile"])
with open(filepath) as f:
@@ -383,6 +388,39 @@ def check_target(c):
return _check
+def check_project(c):
+ def _check(actual, expected):
+ assert is_dict(actual)
+ expected_keys = ["name", "directoryIndexes"]
+
+ check_list_match(lambda a, e: matches(c["directories"][a]["source"], e),
+ actual["directoryIndexes"], expected["directorySources"],
+ missing_exception=lambda e: "Directory source: %s" % e,
+ extra_exception=lambda a: "Directory source: %s" % c["directories"][a]["source"])
+
+ if expected["parentName"] is not None:
+ expected_keys.append("parentIndex")
+ assert is_int(actual["parentIndex"])
+ assert is_string(c["projects"][actual["parentIndex"]]["name"], expected["parentName"])
+
+ if expected["childNames"] is not None:
+ expected_keys.append("childIndexes")
+ check_list_match(lambda a, e: is_string(c["projects"][a]["name"], e),
+ actual["childIndexes"], expected["childNames"],
+ missing_exception=lambda e: "Child name: %s" % e,
+ extra_exception=lambda a: "Child name: %s" % c["projects"][a]["name"])
+
+ if expected["targetIds"] is not None:
+ expected_keys.append("targetIndexes")
+ check_list_match(lambda a, e: matches(c["targets"][a]["id"], e),
+ actual["targetIndexes"], expected["targetIds"],
+ missing_exception=lambda e: "Target ID: %s" % e,
+ extra_exception=lambda a: "Target ID: %s" % c["targets"][a]["id"])
+
+ assert sorted(actual.keys()) == sorted(expected_keys)
+
+ return _check
+
def gen_check_directories(c, g):
expected = [
{
@@ -396,6 +434,7 @@ def gen_check_directories(c, g):
"^imported$",
"^object$",
"^.*/Tests/RunCMake/FileAPIExternalSource$",
+ "^dir$",
],
"targetIds": [
"^ALL_BUILD::@6890427a1f51a3e7e1df$",
@@ -408,6 +447,7 @@ def gen_check_directories(c, g):
"^c_static_lib::@6890427a1f51a3e7e1df$",
"^interface_exe::@6890427a1f51a3e7e1df$",
],
+ "projectName": "codemodel-v2",
},
{
"source": "^alias$",
@@ -420,6 +460,7 @@ def gen_check_directories(c, g):
"^c_alias_exe::@53632cba2752272bb008$",
"^cxx_alias_exe::@53632cba2752272bb008$",
],
+ "projectName": "Alias",
},
{
"source": "^custom$",
@@ -432,6 +473,7 @@ def gen_check_directories(c, g):
"^custom_exe::@c11385ffed57b860da63$",
"^custom_tgt::@c11385ffed57b860da63$",
],
+ "projectName": "Custom",
},
{
"source": "^cxx$",
@@ -448,6 +490,7 @@ def gen_check_directories(c, g):
"^cxx_static_exe::@a56b12a3f5c0529fb296$",
"^cxx_static_lib::@a56b12a3f5c0529fb296$",
],
+ "projectName": "Cxx",
},
{
"source": "^imported$",
@@ -463,6 +506,7 @@ def gen_check_directories(c, g):
"^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
"^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
],
+ "projectName": "Imported",
},
{
"source": "^object$",
@@ -477,6 +521,27 @@ def gen_check_directories(c, g):
"^cxx_object_exe::@5ed5358f70faf8d8af7a$",
"^cxx_object_lib::@5ed5358f70faf8d8af7a$",
],
+ "projectName": "Object",
+ },
+ {
+ "source": "^dir$",
+ "build": "^dir$",
+ "parentSource": "^\\.$",
+ "childSources": [
+ "^dir/dir$",
+ ],
+ "targetIds": None,
+ "projectName": "codemodel-v2",
+ "minimumCMakeVersion": "3.12",
+ "hasInstallRule": None,
+ },
+ {
+ "source": "^dir/dir$",
+ "build": "^dir/dir$",
+ "parentSource": "^dir$",
+ "childSources": None,
+ "targetIds": None,
+ "projectName": "codemodel-v2",
},
{
"source": "^.*/Tests/RunCMake/FileAPIExternalSource$",
@@ -488,6 +553,7 @@ def gen_check_directories(c, g):
"^ZERO_CHECK::@[0-9a-f]+$",
"^generated_exe::@[0-9a-f]+$",
],
+ "projectName": "External",
},
]
@@ -520,6 +586,7 @@ def gen_check_targets(c, g, inSource):
"name": "ALL_BUILD",
"id": "^ALL_BUILD::@6890427a1f51a3e7e1df$",
"directorySource": "^\\.$",
+ "projectName": "codemodel-v2",
"type": "UTILITY",
"isGeneratorProvided": True,
"sources": [
@@ -698,6 +765,7 @@ def gen_check_targets(c, g, inSource):
"name": "ZERO_CHECK",
"id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
"directorySource": "^\\.$",
+ "projectName": "codemodel-v2",
"type": "UTILITY",
"isGeneratorProvided": True,
"sources": [
@@ -767,6 +835,7 @@ def gen_check_targets(c, g, inSource):
"name": "interface_exe",
"id": "^interface_exe::@6890427a1f51a3e7e1df$",
"directorySource": "^\\.$",
+ "projectName": "codemodel-v2",
"type": "EXECUTABLE",
"isGeneratorProvided": None,
"sources": [
@@ -911,6 +980,7 @@ def gen_check_targets(c, g, inSource):
"name": "c_lib",
"id": "^c_lib::@6890427a1f51a3e7e1df$",
"directorySource": "^\\.$",
+ "projectName": "codemodel-v2",
"type": "STATIC_LIBRARY",
"isGeneratorProvided": None,
"sources": [
@@ -1017,6 +1087,7 @@ def gen_check_targets(c, g, inSource):
"name": "c_exe",
"id": "^c_exe::@6890427a1f51a3e7e1df$",
"directorySource": "^\\.$",
+ "projectName": "codemodel-v2",
"type": "EXECUTABLE",
"isGeneratorProvided": None,
"sources": [
@@ -1157,6 +1228,7 @@ def gen_check_targets(c, g, inSource):
"name": "c_shared_lib",
"id": "^c_shared_lib::@6890427a1f51a3e7e1df$",
"directorySource": "^\\.$",
+ "projectName": "codemodel-v2",
"type": "SHARED_LIBRARY",
"isGeneratorProvided": None,
"sources": [
@@ -1277,6 +1349,7 @@ def gen_check_targets(c, g, inSource):
"name": "c_shared_exe",
"id": "^c_shared_exe::@6890427a1f51a3e7e1df$",
"directorySource": "^\\.$",
+ "projectName": "codemodel-v2",
"type": "EXECUTABLE",
"isGeneratorProvided": None,
"sources": [
@@ -1417,6 +1490,7 @@ def gen_check_targets(c, g, inSource):
"name": "c_static_lib",
"id": "^c_static_lib::@6890427a1f51a3e7e1df$",
"directorySource": "^\\.$",
+ "projectName": "codemodel-v2",
"type": "STATIC_LIBRARY",
"isGeneratorProvided": None,
"sources": [
@@ -1523,6 +1597,7 @@ def gen_check_targets(c, g, inSource):
"name": "c_static_exe",
"id": "^c_static_exe::@6890427a1f51a3e7e1df$",
"directorySource": "^\\.$",
+ "projectName": "codemodel-v2",
"type": "EXECUTABLE",
"isGeneratorProvided": None,
"sources": [
@@ -1663,6 +1738,7 @@ def gen_check_targets(c, g, inSource):
"name": "ALL_BUILD",
"id": "^ALL_BUILD::@a56b12a3f5c0529fb296$",
"directorySource": "^cxx$",
+ "projectName": "Cxx",
"type": "UTILITY",
"isGeneratorProvided": True,
"sources": [
@@ -1761,6 +1837,7 @@ def gen_check_targets(c, g, inSource):
"name": "ZERO_CHECK",
"id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
"directorySource": "^cxx$",
+ "projectName": "Cxx",
"type": "UTILITY",
"isGeneratorProvided": True,
"sources": [
@@ -1830,6 +1907,7 @@ def gen_check_targets(c, g, inSource):
"name": "cxx_lib",
"id": "^cxx_lib::@a56b12a3f5c0529fb296$",
"directorySource": "^cxx$",
+ "projectName": "Cxx",
"type": "STATIC_LIBRARY",
"isGeneratorProvided": None,
"sources": [
@@ -1912,6 +1990,7 @@ def gen_check_targets(c, g, inSource):
"name": "cxx_exe",
"id": "^cxx_exe::@a56b12a3f5c0529fb296$",
"directorySource": "^cxx$",
+ "projectName": "Cxx",
"type": "EXECUTABLE",
"isGeneratorProvided": None,
"sources": [
@@ -2016,6 +2095,7 @@ def gen_check_targets(c, g, inSource):
"name": "cxx_shared_lib",
"id": "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
"directorySource": "^cxx$",
+ "projectName": "Cxx",
"type": "SHARED_LIBRARY",
"isGeneratorProvided": None,
"sources": [
@@ -2112,6 +2192,7 @@ def gen_check_targets(c, g, inSource):
"name": "cxx_shared_exe",
"id": "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
"directorySource": "^cxx$",
+ "projectName": "Cxx",
"type": "EXECUTABLE",
"isGeneratorProvided": None,
"sources": [
@@ -2216,6 +2297,7 @@ def gen_check_targets(c, g, inSource):
"name": "cxx_static_lib",
"id": "^cxx_static_lib::@a56b12a3f5c0529fb296$",
"directorySource": "^cxx$",
+ "projectName": "Cxx",
"type": "STATIC_LIBRARY",
"isGeneratorProvided": None,
"sources": [
@@ -2298,6 +2380,7 @@ def gen_check_targets(c, g, inSource):
"name": "cxx_static_exe",
"id": "^cxx_static_exe::@a56b12a3f5c0529fb296$",
"directorySource": "^cxx$",
+ "projectName": "Cxx",
"type": "EXECUTABLE",
"isGeneratorProvided": None,
"sources": [
@@ -2402,6 +2485,7 @@ def gen_check_targets(c, g, inSource):
"name": "ALL_BUILD",
"id": "^ALL_BUILD::@53632cba2752272bb008$",
"directorySource": "^alias$",
+ "projectName": "Alias",
"type": "UTILITY",
"isGeneratorProvided": True,
"sources": [
@@ -2484,6 +2568,7 @@ def gen_check_targets(c, g, inSource):
"name": "ZERO_CHECK",
"id": "^ZERO_CHECK::@53632cba2752272bb008$",
"directorySource": "^alias$",
+ "projectName": "Alias",
"type": "UTILITY",
"isGeneratorProvided": True,
"sources": [
@@ -2553,6 +2638,7 @@ def gen_check_targets(c, g, inSource):
"name": "c_alias_exe",
"id": "^c_alias_exe::@53632cba2752272bb008$",
"directorySource": "^alias$",
+ "projectName": "Alias",
"type": "EXECUTABLE",
"isGeneratorProvided": None,
"sources": [
@@ -2657,6 +2743,7 @@ def gen_check_targets(c, g, inSource):
"name": "cxx_alias_exe",
"id": "^cxx_alias_exe::@53632cba2752272bb008$",
"directorySource": "^alias$",
+ "projectName": "Alias",
"type": "EXECUTABLE",
"isGeneratorProvided": None,
"sources": [
@@ -2761,6 +2848,7 @@ def gen_check_targets(c, g, inSource):
"name": "ALL_BUILD",
"id": "^ALL_BUILD::@5ed5358f70faf8d8af7a$",
"directorySource": "^object$",
+ "projectName": "Object",
"type": "UTILITY",
"isGeneratorProvided": True,
"sources": [
@@ -2851,6 +2939,7 @@ def gen_check_targets(c, g, inSource):
"name": "ZERO_CHECK",
"id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
"directorySource": "^object$",
+ "projectName": "Object",
"type": "UTILITY",
"isGeneratorProvided": True,
"sources": [
@@ -2920,6 +3009,7 @@ def gen_check_targets(c, g, inSource):
"name": "c_object_lib",
"id": "^c_object_lib::@5ed5358f70faf8d8af7a$",
"directorySource": "^object$",
+ "projectName": "Object",
"type": "OBJECT_LIBRARY",
"isGeneratorProvided": None,
"sources": [
@@ -3000,6 +3090,7 @@ def gen_check_targets(c, g, inSource):
"name": "c_object_exe",
"id": "^c_object_exe::@5ed5358f70faf8d8af7a$",
"directorySource": "^object$",
+ "projectName": "Object",
"type": "EXECUTABLE",
"isGeneratorProvided": None,
"sources": [
@@ -3141,6 +3232,7 @@ def gen_check_targets(c, g, inSource):
"name": "cxx_object_lib",
"id": "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
"directorySource": "^object$",
+ "projectName": "Object",
"type": "OBJECT_LIBRARY",
"isGeneratorProvided": None,
"sources": [
@@ -3221,6 +3313,7 @@ def gen_check_targets(c, g, inSource):
"name": "cxx_object_exe",
"id": "^cxx_object_exe::@5ed5358f70faf8d8af7a$",
"directorySource": "^object$",
+ "projectName": "Object",
"type": "EXECUTABLE",
"isGeneratorProvided": None,
"sources": [
@@ -3362,6 +3455,7 @@ def gen_check_targets(c, g, inSource):
"name": "ALL_BUILD",
"id": "^ALL_BUILD::@ba7eb709d0b48779c6c8$",
"directorySource": "^imported$",
+ "projectName": "Imported",
"type": "UTILITY",
"isGeneratorProvided": True,
"sources": [
@@ -3456,6 +3550,7 @@ def gen_check_targets(c, g, inSource):
"name": "ZERO_CHECK",
"id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
"directorySource": "^imported$",
+ "projectName": "Imported",
"type": "UTILITY",
"isGeneratorProvided": True,
"sources": [
@@ -3525,6 +3620,7 @@ def gen_check_targets(c, g, inSource):
"name": "link_imported_exe",
"id": "^link_imported_exe::@ba7eb709d0b48779c6c8$",
"directorySource": "^imported$",
+ "projectName": "Imported",
"type": "EXECUTABLE",
"isGeneratorProvided": None,
"sources": [
@@ -3612,6 +3708,7 @@ def gen_check_targets(c, g, inSource):
"name": "link_imported_shared_exe",
"id": "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
"directorySource": "^imported$",
+ "projectName": "Imported",
"type": "EXECUTABLE",
"isGeneratorProvided": None,
"sources": [
@@ -3699,6 +3796,7 @@ def gen_check_targets(c, g, inSource):
"name": "link_imported_static_exe",
"id": "^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
"directorySource": "^imported$",
+ "projectName": "Imported",
"type": "EXECUTABLE",
"isGeneratorProvided": None,
"sources": [
@@ -3786,6 +3884,7 @@ def gen_check_targets(c, g, inSource):
"name": "link_imported_object_exe",
"id": "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
"directorySource": "^imported$",
+ "projectName": "Imported",
"type": "EXECUTABLE",
"isGeneratorProvided": None,
"sources": [
@@ -3873,6 +3972,7 @@ def gen_check_targets(c, g, inSource):
"name": "link_imported_interface_exe",
"id": "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$",
"directorySource": "^imported$",
+ "projectName": "Imported",
"type": "EXECUTABLE",
"isGeneratorProvided": None,
"sources": [
@@ -3960,6 +4060,7 @@ def gen_check_targets(c, g, inSource):
"name": "ALL_BUILD",
"id": "^ALL_BUILD::@c11385ffed57b860da63$",
"directorySource": "^custom$",
+ "projectName": "Custom",
"type": "UTILITY",
"isGeneratorProvided": True,
"sources": [
@@ -4038,6 +4139,7 @@ def gen_check_targets(c, g, inSource):
"name": "ZERO_CHECK",
"id": "^ZERO_CHECK::@c11385ffed57b860da63$",
"directorySource": "^custom$",
+ "projectName": "Custom",
"type": "UTILITY",
"isGeneratorProvided": True,
"sources": [
@@ -4107,6 +4209,7 @@ def gen_check_targets(c, g, inSource):
"name": "custom_tgt",
"id": "^custom_tgt::@c11385ffed57b860da63$",
"directorySource": "^custom$",
+ "projectName": "Custom",
"type": "UTILITY",
"isGeneratorProvided": None,
"sources": [
@@ -4193,6 +4296,7 @@ def gen_check_targets(c, g, inSource):
"name": "custom_exe",
"id": "^custom_exe::@c11385ffed57b860da63$",
"directorySource": "^custom$",
+ "projectName": "Custom",
"type": "EXECUTABLE",
"isGeneratorProvided": None,
"sources": [
@@ -4297,6 +4401,7 @@ def gen_check_targets(c, g, inSource):
"name": "ALL_BUILD",
"id": "^ALL_BUILD::@[0-9a-f]+$",
"directorySource": "^.*/Tests/RunCMake/FileAPIExternalSource$",
+ "projectName": "External",
"type": "UTILITY",
"isGeneratorProvided": True,
"sources": [
@@ -4375,6 +4480,7 @@ def gen_check_targets(c, g, inSource):
"name": "ZERO_CHECK",
"id": "^ZERO_CHECK::@[0-9a-f]+$",
"directorySource": "^.*/Tests/RunCMake/FileAPIExternalSource$",
+ "projectName": "External",
"type": "UTILITY",
"isGeneratorProvided": True,
"sources": [
@@ -4444,6 +4550,7 @@ def gen_check_targets(c, g, inSource):
"name": "generated_exe",
"id": "^generated_exe::@[0-9a-f]+$",
"directorySource": "^.*/Tests/RunCMake/FileAPIExternalSource$",
+ "projectName": "External",
"type": "EXECUTABLE",
"isGeneratorProvided": None,
"sources": [
@@ -4772,11 +4879,159 @@ def check_targets(c, g, inSource):
missing_exception=lambda e: "Target ID: %s" % e["id"],
extra_exception=lambda a: "Target ID: %s" % a["id"])
+def gen_check_projects(c, g):
+ expected = [
+ {
+ "name": "codemodel-v2",
+ "parentName": None,
+ "childNames": [
+ "Alias",
+ "Custom",
+ "Cxx",
+ "Imported",
+ "Object",
+ "External",
+ ],
+ "directorySources": [
+ "^\\.$",
+ "^dir$",
+ "^dir/dir$",
+ ],
+ "targetIds": [
+ "^ALL_BUILD::@6890427a1f51a3e7e1df$",
+ "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+ "^interface_exe::@6890427a1f51a3e7e1df$",
+ "^c_lib::@6890427a1f51a3e7e1df$",
+ "^c_exe::@6890427a1f51a3e7e1df$",
+ "^c_shared_lib::@6890427a1f51a3e7e1df$",
+ "^c_shared_exe::@6890427a1f51a3e7e1df$",
+ "^c_static_lib::@6890427a1f51a3e7e1df$",
+ "^c_static_exe::@6890427a1f51a3e7e1df$",
+ ],
+ },
+ {
+ "name": "Cxx",
+ "parentName": "codemodel-v2",
+ "childNames": None,
+ "directorySources": [
+ "^cxx$",
+ ],
+ "targetIds": [
+ "^ALL_BUILD::@a56b12a3f5c0529fb296$",
+ "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+ "^cxx_lib::@a56b12a3f5c0529fb296$",
+ "^cxx_exe::@a56b12a3f5c0529fb296$",
+ "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
+ "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
+ "^cxx_static_lib::@a56b12a3f5c0529fb296$",
+ "^cxx_static_exe::@a56b12a3f5c0529fb296$",
+ ],
+ },
+ {
+ "name": "Alias",
+ "parentName": "codemodel-v2",
+ "childNames": None,
+ "directorySources": [
+ "^alias$",
+ ],
+ "targetIds": [
+ "^ALL_BUILD::@53632cba2752272bb008$",
+ "^ZERO_CHECK::@53632cba2752272bb008$",
+ "^c_alias_exe::@53632cba2752272bb008$",
+ "^cxx_alias_exe::@53632cba2752272bb008$",
+ ],
+ },
+ {
+ "name": "Object",
+ "parentName": "codemodel-v2",
+ "childNames": None,
+ "directorySources": [
+ "^object$",
+ ],
+ "targetIds": [
+ "^ALL_BUILD::@5ed5358f70faf8d8af7a$",
+ "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
+ "^c_object_lib::@5ed5358f70faf8d8af7a$",
+ "^c_object_exe::@5ed5358f70faf8d8af7a$",
+ "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
+ "^cxx_object_exe::@5ed5358f70faf8d8af7a$",
+ ],
+ },
+ {
+ "name": "Imported",
+ "parentName": "codemodel-v2",
+ "childNames": None,
+ "directorySources": [
+ "^imported$",
+ ],
+ "targetIds": [
+ "^ALL_BUILD::@ba7eb709d0b48779c6c8$",
+ "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
+ "^link_imported_exe::@ba7eb709d0b48779c6c8$",
+ "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
+ "^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
+ "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
+ "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$",
+ ],
+ },
+ {
+ "name": "Custom",
+ "parentName": "codemodel-v2",
+ "childNames": None,
+ "directorySources": [
+ "^custom$",
+ ],
+ "targetIds": [
+ "^ALL_BUILD::@c11385ffed57b860da63$",
+ "^ZERO_CHECK::@c11385ffed57b860da63$",
+ "^custom_tgt::@c11385ffed57b860da63$",
+ "^custom_exe::@c11385ffed57b860da63$",
+ ],
+ },
+ {
+ "name": "External",
+ "parentName": "codemodel-v2",
+ "childNames": None,
+ "directorySources": [
+ "^.*/Tests/RunCMake/FileAPIExternalSource$",
+ ],
+ "targetIds": [
+ "^ALL_BUILD::@[0-9a-f]+$",
+ "^ZERO_CHECK::@[0-9a-f]+$",
+ "^generated_exe::@[0-9a-f]+$",
+ ],
+ },
+ ]
+
+ if matches(g, "^Visual Studio "):
+ for e in expected:
+ if e["parentName"] is not None:
+ e["targetIds"] = filter_list(lambda t: not matches(t, "^\\^ZERO_CHECK"), e["targetIds"])
+
+ elif g == "Xcode":
+ if ';' in os.environ.get("CMAKE_OSX_ARCHITECTURES", ""):
+ for e in expected:
+ e["targetIds"] = filter_list(lambda t: not matches(t, "^\\^(link_imported_object_exe)"), e["targetIds"])
+
+ else:
+ for e in expected:
+ e["targetIds"] = filter_list(lambda t: not matches(t, "^\\^(ALL_BUILD|ZERO_CHECK)"), e["targetIds"])
+
+ return expected
+
+def check_projects(c, g):
+ check_list_match(lambda a, e: is_string(a["name"], e["name"]), c["projects"], gen_check_projects(c, g),
+ check=check_project(c),
+ check_exception=lambda a, e: "Project name: %s" % a["name"],
+ 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):
- assert sorted(c.keys()) == ["directories", "name", "targets"]
+ assert sorted(c.keys()) == ["directories", "name", "projects", "targets"]
assert is_string(c["name"])
check_directories(c, g)
check_targets(c, g, inSource)
+ check_projects(c, g)
def check_object_codemodel(g):
def _check(o):
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2.cmake b/Tests/RunCMake/FileAPI/codemodel-v2.cmake
index dca1dd1..72073d5 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2.cmake
+++ b/Tests/RunCMake/FileAPI/codemodel-v2.cmake
@@ -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)