mirror of
https://github.com/Kitware/CMake.git
synced 2025-12-31 02:39:48 -06:00
cmCxxModuleMapper: support MSVC module map format
THis is a set of flags stored in a response file which informs the compiler about where to place output BMI files as well as find the required BMIs.
This commit is contained in:
@@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -54,6 +56,80 @@ std::string CxxModuleMapContentGcc(CxxModuleLocations const& loc,
|
|||||||
|
|
||||||
return mm.str();
|
return mm.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string CxxModuleMapContentMsvc(CxxModuleLocations const& loc,
|
||||||
|
cmScanDepInfo const& obj,
|
||||||
|
CxxModuleUsage const& usages)
|
||||||
|
{
|
||||||
|
std::stringstream mm;
|
||||||
|
|
||||||
|
// A response file of `-reference NAME=PATH` arguments.
|
||||||
|
|
||||||
|
// MSVC's command line only supports a single output. If more than one is
|
||||||
|
// expected, we cannot make a useful module map file.
|
||||||
|
if (obj.Provides.size() > 1) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto flag_for_method = [](LookupMethod method) -> cm::static_string_view {
|
||||||
|
switch (method) {
|
||||||
|
case LookupMethod::ByName:
|
||||||
|
return "-reference"_s;
|
||||||
|
case LookupMethod::IncludeAngle:
|
||||||
|
return "-headerUnit:angle"_s;
|
||||||
|
case LookupMethod::IncludeQuote:
|
||||||
|
return "-headerUnit:quote"_s;
|
||||||
|
}
|
||||||
|
assert(false && "unsupported lookup method");
|
||||||
|
return ""_s;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto const& p : obj.Provides) {
|
||||||
|
if (p.IsInterface) {
|
||||||
|
mm << "-interface\n";
|
||||||
|
} else {
|
||||||
|
mm << "-internalPartition\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto bmi_loc = loc.BmiGeneratorPathForModule(p.LogicalName)) {
|
||||||
|
mm << "-ifcOutput " << *bmi_loc << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::string> transitive_usage_directs;
|
||||||
|
std::set<std::string> transitive_usage_names;
|
||||||
|
|
||||||
|
for (auto const& r : obj.Requires) {
|
||||||
|
if (auto bmi_loc = loc.BmiGeneratorPathForModule(r.LogicalName)) {
|
||||||
|
auto flag = flag_for_method(r.Method);
|
||||||
|
|
||||||
|
mm << flag << ' ' << r.LogicalName << '=' << *bmi_loc << "\n";
|
||||||
|
transitive_usage_directs.insert(r.LogicalName);
|
||||||
|
|
||||||
|
// Insert transitive usages.
|
||||||
|
auto transitive_usages = usages.Usage.find(r.LogicalName);
|
||||||
|
if (transitive_usages != usages.Usage.end()) {
|
||||||
|
transitive_usage_names.insert(transitive_usages->second.begin(),
|
||||||
|
transitive_usages->second.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto const& transitive_name : transitive_usage_names) {
|
||||||
|
if (transitive_usage_directs.count(transitive_name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto module_ref = usages.Reference.find(transitive_name);
|
||||||
|
if (module_ref != usages.Reference.end()) {
|
||||||
|
auto flag = flag_for_method(module_ref->second.Method);
|
||||||
|
mm << flag << ' ' << transitive_name << '=' << module_ref->second.Path
|
||||||
|
<< "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mm.str();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CxxModuleUsage::AddReference(std::string const& logical,
|
bool CxxModuleUsage::AddReference(std::string const& logical,
|
||||||
@@ -105,6 +181,8 @@ cm::static_string_view CxxModuleMapExtension(
|
|||||||
switch (*format) {
|
switch (*format) {
|
||||||
case CxxModuleMapFormat::Gcc:
|
case CxxModuleMapFormat::Gcc:
|
||||||
return ".gcm"_s;
|
return ".gcm"_s;
|
||||||
|
case CxxModuleMapFormat::Msvc:
|
||||||
|
return ".ifc"_s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,11 +293,14 @@ std::set<std::string> CxxModuleUsageSeed(
|
|||||||
|
|
||||||
std::string CxxModuleMapContent(CxxModuleMapFormat format,
|
std::string CxxModuleMapContent(CxxModuleMapFormat format,
|
||||||
CxxModuleLocations const& loc,
|
CxxModuleLocations const& loc,
|
||||||
cmScanDepInfo const& obj)
|
cmScanDepInfo const& obj,
|
||||||
|
CxxModuleUsage const& usages)
|
||||||
{
|
{
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case CxxModuleMapFormat::Gcc:
|
case CxxModuleMapFormat::Gcc:
|
||||||
return CxxModuleMapContentGcc(loc, obj);
|
return CxxModuleMapContentGcc(loc, obj);
|
||||||
|
case CxxModuleMapFormat::Msvc:
|
||||||
|
return CxxModuleMapContentMsvc(loc, obj, usages);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
enum class CxxModuleMapFormat
|
enum class CxxModuleMapFormat
|
||||||
{
|
{
|
||||||
Gcc,
|
Gcc,
|
||||||
|
Msvc,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CxxModuleLocations
|
struct CxxModuleLocations
|
||||||
@@ -80,4 +81,5 @@ std::set<std::string> CxxModuleUsageSeed(
|
|||||||
// object file.
|
// object file.
|
||||||
std::string CxxModuleMapContent(CxxModuleMapFormat format,
|
std::string CxxModuleMapContent(CxxModuleMapFormat format,
|
||||||
CxxModuleLocations const& loc,
|
CxxModuleLocations const& loc,
|
||||||
cmScanDepInfo const& obj);
|
cmScanDepInfo const& obj,
|
||||||
|
CxxModuleUsage const& usages);
|
||||||
|
|||||||
@@ -2625,6 +2625,8 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
|
|||||||
// nothing to do.
|
// nothing to do.
|
||||||
} else if (arg_modmapfmt == "gcc") {
|
} else if (arg_modmapfmt == "gcc") {
|
||||||
modmap_fmt = CxxModuleMapFormat::Gcc;
|
modmap_fmt = CxxModuleMapFormat::Gcc;
|
||||||
|
} else if (arg_modmapfmt == "msvc") {
|
||||||
|
modmap_fmt = CxxModuleMapFormat::Msvc;
|
||||||
} else {
|
} else {
|
||||||
cmSystemTools::Error(
|
cmSystemTools::Error(
|
||||||
cmStrCat("-E cmake_ninja_dyndep does not understand the ", arg_modmapfmt,
|
cmStrCat("-E cmake_ninja_dyndep does not understand the ", arg_modmapfmt,
|
||||||
@@ -2712,7 +2714,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (modmap_fmt) {
|
if (modmap_fmt) {
|
||||||
auto mm = CxxModuleMapContent(*modmap_fmt, locs, object);
|
auto mm = CxxModuleMapContent(*modmap_fmt, locs, object, usages);
|
||||||
|
|
||||||
// XXX(modmap): If changing this path construction, change
|
// XXX(modmap): If changing this path construction, change
|
||||||
// `cmNinjaTargetGenerator::WriteObjectBuildStatements` to generate the
|
// `cmNinjaTargetGenerator::WriteObjectBuildStatements` to generate the
|
||||||
|
|||||||
Reference in New Issue
Block a user