summaryrefslogtreecommitdiffstats
path: root/Source/cmGlobalNinjaGenerator.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmGlobalNinjaGenerator.cxx')
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx422
1 files changed, 37 insertions, 385 deletions
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 077de42..c24b1e3 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -25,8 +25,7 @@
#include "cmsys/FStream.hxx"
#include "cmCxxModuleMapper.h"
-#include "cmDocumentationEntry.h"
-#include "cmFileSet.h"
+#include "cmDyndepCollation.h"
#include "cmFortranParser.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpressionEvaluationFile.h"
@@ -554,10 +553,10 @@ codecvt::Encoding cmGlobalNinjaGenerator::GetMakefileEncoding() const
return this->NinjaExpectedEncoding;
}
-void cmGlobalNinjaGenerator::GetDocumentation(cmDocumentationEntry& entry)
+cmDocumentationEntry cmGlobalNinjaGenerator::GetDocumentation()
{
- entry.Name = cmGlobalNinjaGenerator::GetActualName();
- entry.Brief = "Generates build.ninja files.";
+ return { cmGlobalNinjaGenerator::GetActualName(),
+ "Generates build.ninja files." };
}
// Implemented in all cmGlobaleGenerator sub-classes.
@@ -592,7 +591,9 @@ void cmGlobalNinjaGenerator::Generate()
this->TargetAll = this->NinjaOutputPath("all");
this->CMakeCacheFile = this->NinjaOutputPath("CMakeCache.txt");
this->DisableCleandead = false;
- this->DiagnosedCxxModuleSupport = false;
+ this->DiagnosedCxxModuleNinjaSupport = false;
+ this->ClangTidyExportFixesDirs.clear();
+ this->ClangTidyExportFixesFiles.clear();
this->PolicyCMP0058 =
this->LocalGenerators[0]->GetMakefile()->GetPolicyStatus(
@@ -633,6 +634,8 @@ void cmGlobalNinjaGenerator::Generate()
{
this->CleanMetaData();
}
+
+ this->RemoveUnknownClangTidyExportFixesFiles();
}
void cmGlobalNinjaGenerator::CleanMetaData()
@@ -851,18 +854,12 @@ bool cmGlobalNinjaGenerator::CheckLanguages(
bool cmGlobalNinjaGenerator::CheckCxxModuleSupport()
{
- bool const diagnose = !this->DiagnosedCxxModuleSupport &&
- !this->CMakeInstance->GetIsInTryCompile();
- if (diagnose) {
- this->DiagnosedCxxModuleSupport = true;
- this->GetCMakeInstance()->IssueMessage(
- MessageType::AUTHOR_WARNING,
- "C++20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP "
- "is experimental. It is meant only for compiler developers to try.");
- }
+ this->CxxModuleSupportCheck();
if (this->NinjaSupportsDyndeps) {
return true;
}
+ bool const diagnose = !this->DiagnosedCxxModuleNinjaSupport &&
+ !this->CMakeInstance->GetIsInTryCompile();
if (diagnose) {
std::ostringstream e;
/* clang-format off */
@@ -1171,7 +1168,8 @@ void cmGlobalNinjaGenerator::AddAdditionalCleanFile(std::string fileName,
}
void cmGlobalNinjaGenerator::AddCXXCompileCommand(
- const std::string& commandLine, const std::string& sourceFile)
+ const std::string& commandLine, const std::string& sourceFile,
+ const std::string& objPath)
{
// Compute Ninja's build file path.
std::string buildFileDir =
@@ -1205,7 +1203,9 @@ void cmGlobalNinjaGenerator::AddCXXCompileCommand(
<< R"( "command": ")"
<< cmGlobalGenerator::EscapeJSON(commandLine) << "\",\n"
<< R"( "file": ")"
- << cmGlobalGenerator::EscapeJSON(sourceFileName) << "\"\n"
+ << cmGlobalGenerator::EscapeJSON(sourceFileName) << "\",\n"
+ << R"( "output": ")"
+ << cmGlobalGenerator::EscapeJSON(objPath) << "\"\n"
<< "}";
/* clang-format on */
}
@@ -1254,7 +1254,7 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
cmGeneratorTarget const* target, cmNinjaDeps& outputs,
const std::string& config, cmNinjaTargetDepends depends) const
{
- // for frameworks, we want the real name, not smple name
+ // for frameworks, we want the real name, not sample name
// frameworks always appear versioned, and the build.ninja
// will always attempt to manage symbolic links instead
// of letting cmOSXBundleGenerator do it.
@@ -2098,6 +2098,7 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
}
std::vector<std::string> byproducts;
+ byproducts.reserve(this->CrossConfigs.size());
for (auto const& config : this->CrossConfigs) {
byproducts.push_back(
this->BuildAlias(GetByproductsForCleanTargetName(), config));
@@ -2472,45 +2473,6 @@ cm::optional<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran(
}
}
-struct CxxModuleFileSet
-{
- std::string Name;
- std::string RelativeDirectory;
- std::string SourcePath;
- std::string Type;
- cmFileSetVisibility Visibility;
- cm::optional<std::string> Destination;
-};
-
-struct CxxModuleBmiInstall
-{
- std::string Component;
- std::string Destination;
- bool ExcludeFromAll;
- bool Optional;
- std::string Permissions;
- std::string MessageLevel;
- std::string ScriptLocation;
-};
-
-struct CxxModuleExport
-{
- std::string Name;
- std::string Destination;
- std::string Prefix;
- std::string CxxModuleInfoDir;
- std::string Namespace;
- bool Install;
-};
-
-struct cmGlobalNinjaGenerator::CxxModuleExportInfo
-{
- std::map<std::string, CxxModuleFileSet> ObjectToFileSet;
- cm::optional<CxxModuleBmiInstall> BmiInstallation;
- std::vector<CxxModuleExport> Exports;
- std::string Config;
-};
-
bool cmGlobalNinjaGenerator::WriteDyndepFile(
std::string const& dir_top_src, std::string const& dir_top_bld,
std::string const& dir_cur_src, std::string const& dir_cur_bld,
@@ -2518,7 +2480,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
std::string const& module_dir,
std::vector<std::string> const& linked_target_dirs,
std::string const& arg_lang, std::string const& arg_modmapfmt,
- CxxModuleExportInfo const& export_info)
+ cmCxxModuleExportInfo const& export_info)
{
// Setup path conversions.
{
@@ -2610,6 +2572,8 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
cm::optional<CxxModuleMapFormat> modmap_fmt;
if (arg_modmapfmt.empty()) {
// nothing to do.
+ } else if (arg_modmapfmt == "clang") {
+ modmap_fmt = CxxModuleMapFormat::Clang;
} else if (arg_modmapfmt == "gcc") {
modmap_fmt = CxxModuleMapFormat::Gcc;
} else if (arg_modmapfmt == "msvc") {
@@ -2753,279 +2717,18 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
cmGeneratedFileStream tmf(target_mods_file);
tmf << target_module_info;
- bool result = true;
-
- // Fortran doesn't support any of the file-set or BMI installation considered
- // below.
- if (arg_lang != "Fortran"_s) {
- // Prepare the export information blocks.
- std::string const config_upper =
- cmSystemTools::UpperCase(export_info.Config);
- std::vector<std::pair<std::unique_ptr<cmGeneratedFileStream>,
- CxxModuleExport const*>>
- exports;
- for (auto const& exp : export_info.Exports) {
- std::unique_ptr<cmGeneratedFileStream> properties;
-
- std::string const export_dir =
- cmStrCat(exp.Prefix, '/', exp.CxxModuleInfoDir, '/');
- std::string const property_file_path = cmStrCat(
- export_dir, "target-", exp.Name, '-', export_info.Config, ".cmake");
- properties = cm::make_unique<cmGeneratedFileStream>(property_file_path);
-
- // Set up the preamble.
- *properties << "set_property(TARGET \"" << exp.Namespace << exp.Name
- << "\"\n"
- << " PROPERTY IMPORTED_CXX_MODULES_" << config_upper
- << '\n';
-
- exports.emplace_back(std::move(properties), &exp);
+ cmDyndepMetadataCallbacks cb;
+ cb.ModuleFile =
+ [mod_files](std::string const& name) -> cm::optional<std::string> {
+ auto m = mod_files.find(name);
+ if (m != mod_files.end()) {
+ return m->second;
}
+ return {};
+ };
- std::unique_ptr<cmGeneratedFileStream> bmi_install_script;
- if (export_info.BmiInstallation) {
- bmi_install_script = cm::make_unique<cmGeneratedFileStream>(
- export_info.BmiInstallation->ScriptLocation);
- }
-
- auto cmEscape = [](cm::string_view str) {
- return cmOutputConverter::EscapeForCMake(
- str, cmOutputConverter::WrapQuotes::NoWrap);
- };
- auto install_destination =
- [&cmEscape](std::string const& dest) -> std::pair<bool, std::string> {
- if (cmSystemTools::FileIsFullPath(dest)) {
- return std::make_pair(true, cmEscape(dest));
- }
- return std::make_pair(false,
- cmStrCat("${_IMPORT_PREFIX}/", cmEscape(dest)));
- };
-
- // public/private requirement tracking.
- std::set<std::string> private_modules;
- std::map<std::string, std::set<std::string>> public_source_requires;
-
- for (cmScanDepInfo const& object : objects) {
- // Convert to forward slashes.
- auto output_path = object.PrimaryOutput;
-# ifdef _WIN32
- cmSystemTools::ConvertToUnixSlashes(output_path);
-# endif
- // Find the fileset for this object.
- auto fileset_info_itr = export_info.ObjectToFileSet.find(output_path);
- bool const has_provides = !object.Provides.empty();
- if (fileset_info_itr == export_info.ObjectToFileSet.end()) {
- // If it provides anything, it should have a `CXX_MODULES` or
- // `CXX_MODULE_INTERNAL_PARTITIONS` type and be present.
- if (has_provides) {
- // Take the first module provided to provide context.
- auto const& provides = object.Provides[0];
- char const* ok_types = "`CXX_MODULES`";
- if (provides.LogicalName.find(':') != std::string::npos) {
- ok_types = "`CXX_MODULES` (or `CXX_MODULE_INTERNAL_PARTITIONS` if "
- "it is not `export`ed)";
- }
- cmSystemTools::Error(
- cmStrCat("Output ", object.PrimaryOutput, " provides the `",
- provides.LogicalName,
- "` module but it is not found in a `FILE_SET` of type ",
- ok_types));
- result = false;
- }
-
- // This object file does not provide anything, so nothing more needs to
- // be done.
- continue;
- }
-
- auto const& file_set = fileset_info_itr->second;
-
- // Verify the fileset type for the object.
- if (file_set.Type == "CXX_MODULES"_s) {
- if (!has_provides) {
- cmSystemTools::Error(cmStrCat(
- "Output ", object.PrimaryOutput,
- " is of type `CXX_MODULES` but does not provide a module"));
- result = false;
- continue;
- }
- } else if (file_set.Type == "CXX_MODULE_INTERNAL_PARTITIONS"_s) {
- if (!has_provides) {
- cmSystemTools::Error(cmStrCat(
- "Source ", file_set.SourcePath,
- " is of type `CXX_MODULE_INTERNAL_PARTITIONS` but does not "
- "provide a module"));
- result = false;
- continue;
- }
- auto const& provides = object.Provides[0];
- if (provides.LogicalName.find(':') == std::string::npos) {
- cmSystemTools::Error(cmStrCat(
- "Source ", file_set.SourcePath,
- " is of type `CXX_MODULE_INTERNAL_PARTITIONS` but does not "
- "provide a module partition"));
- result = false;
- continue;
- }
- } else if (file_set.Type == "CXX_MODULE_HEADERS"_s) {
- // TODO.
- } else {
- if (has_provides) {
- auto const& provides = object.Provides[0];
- char const* ok_types = "`CXX_MODULES`";
- if (provides.LogicalName.find(':') != std::string::npos) {
- ok_types = "`CXX_MODULES` (or `CXX_MODULE_INTERNAL_PARTITIONS` if "
- "it is not `export`ed)";
- }
- cmSystemTools::Error(cmStrCat(
- "Source ", file_set.SourcePath, " provides the `",
- provides.LogicalName, "` C++ module but is of type `",
- file_set.Type, "` module but must be of type ", ok_types));
- result = false;
- }
-
- // Not a C++ module; ignore.
- continue;
- }
-
- if (!cmFileSetVisibilityIsForInterface(file_set.Visibility)) {
- // Nothing needs to be conveyed about non-`PUBLIC` modules.
- for (auto const& p : object.Provides) {
- private_modules.insert(p.LogicalName);
- }
- continue;
- }
-
- // The module is public. Record what it directly requires.
- {
- auto& reqs = public_source_requires[file_set.SourcePath];
- for (auto const& r : object.Requires) {
- reqs.insert(r.LogicalName);
- }
- }
-
- // Write out properties and install rules for any exports.
- for (auto const& p : object.Provides) {
- bool bmi_dest_is_abs = false;
- std::string bmi_destination;
- if (export_info.BmiInstallation) {
- auto dest =
- install_destination(export_info.BmiInstallation->Destination);
- bmi_dest_is_abs = dest.first;
- bmi_destination = cmStrCat(dest.second, '/');
- }
-
- std::string install_bmi_path;
- std::string build_bmi_path;
- auto m = mod_files.find(p.LogicalName);
- if (m != mod_files.end()) {
- install_bmi_path =
- cmStrCat(bmi_destination,
- cmEscape(cmSystemTools::GetFilenameName(m->second)));
- build_bmi_path = cmEscape(m->second);
- }
-
- for (auto const& exp : exports) {
- std::string iface_source;
- if (exp.second->Install && file_set.Destination) {
- auto dest = install_destination(*file_set.Destination);
- iface_source = cmStrCat(
- dest.second, '/', cmEscape(file_set.RelativeDirectory),
- cmEscape(cmSystemTools::GetFilenameName(file_set.SourcePath)));
- } else {
- iface_source = cmEscape(file_set.SourcePath);
- }
-
- std::string bmi_path;
- if (exp.second->Install && export_info.BmiInstallation) {
- bmi_path = install_bmi_path;
- } else if (!exp.second->Install) {
- bmi_path = build_bmi_path;
- }
-
- if (iface_source.empty()) {
- // No destination for the C++ module source; ignore this property
- // value.
- continue;
- }
-
- *exp.first << " \"" << cmEscape(p.LogicalName) << '='
- << iface_source;
- if (!bmi_path.empty()) {
- *exp.first << ',' << bmi_path;
- }
- *exp.first << "\"\n";
- }
-
- if (bmi_install_script) {
- auto const& bmi_install = *export_info.BmiInstallation;
-
- *bmi_install_script << "if (CMAKE_INSTALL_COMPONENT STREQUAL \""
- << cmEscape(bmi_install.Component) << '\"';
- if (!bmi_install.ExcludeFromAll) {
- *bmi_install_script << " OR NOT CMAKE_INSTALL_COMPONENT";
- }
- *bmi_install_script << ")\n";
- *bmi_install_script << " file(INSTALL\n"
- " DESTINATION \"";
- if (!bmi_dest_is_abs) {
- *bmi_install_script << "${CMAKE_INSTALL_PREFIX}/";
- }
- *bmi_install_script << cmEscape(bmi_install.Destination)
- << "\"\n"
- " TYPE FILE\n";
- if (bmi_install.Optional) {
- *bmi_install_script << " OPTIONAL\n";
- }
- if (!bmi_install.MessageLevel.empty()) {
- *bmi_install_script << " " << bmi_install.MessageLevel << "\n";
- }
- if (!bmi_install.Permissions.empty()) {
- *bmi_install_script << " PERMISSIONS" << bmi_install.Permissions
- << "\n";
- }
- *bmi_install_script << " FILES \"" << m->second << "\")\n";
- if (bmi_dest_is_abs) {
- *bmi_install_script
- << " list(APPEND CMAKE_ABSOLUTE_DESTINATION_FILES\n"
- " \""
- << cmEscape(cmSystemTools::GetFilenameName(m->second))
- << "\")\n"
- " if (CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION)\n"
- " message(WARNING\n"
- " \"ABSOLUTE path INSTALL DESTINATION : "
- "${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n"
- " endif ()\n"
- " if (CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)\n"
- " message(FATAL_ERROR\n"
- " \"ABSOLUTE path INSTALL DESTINATION forbidden (by "
- "caller): ${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n"
- " endif ()\n";
- }
- *bmi_install_script << "endif ()\n";
- }
- }
- }
-
- // Add trailing parenthesis for the `set_property` call.
- for (auto const& exp : exports) {
- *exp.first << ")\n";
- }
-
- // Check that public sources only require public modules.
- for (auto const& pub_reqs : public_source_requires) {
- for (auto const& req : pub_reqs.second) {
- if (private_modules.count(req)) {
- cmSystemTools::Error(cmStrCat(
- "Public C++ module source `", pub_reqs.first, "` requires the `",
- req, "` C++ module which is provided by a private source"));
- result = false;
- }
- }
- }
- }
-
- return result;
+ return cmDyndepCollation::WriteDyndepMetadata(arg_lang, objects, export_info,
+ cb);
}
int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
@@ -3099,58 +2802,7 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
}
}
- cmGlobalNinjaGenerator::CxxModuleExportInfo export_info;
- export_info.Config = tdi["config"].asString();
- if (export_info.Config.empty()) {
- export_info.Config = "noconfig";
- }
- Json::Value const& tdi_exports = tdi["exports"];
- if (tdi_exports.isArray()) {
- for (auto const& tdi_export : tdi_exports) {
- CxxModuleExport exp;
- exp.Install = tdi_export["install"].asBool();
- exp.Name = tdi_export["export-name"].asString();
- exp.Destination = tdi_export["destination"].asString();
- exp.Prefix = tdi_export["export-prefix"].asString();
- exp.CxxModuleInfoDir = tdi_export["cxx-module-info-dir"].asString();
- exp.Namespace = tdi_export["namespace"].asString();
-
- export_info.Exports.push_back(exp);
- }
- }
- auto const& bmi_installation = tdi["bmi-installation"];
- if (bmi_installation.isObject()) {
- CxxModuleBmiInstall bmi_install;
-
- bmi_install.Component = bmi_installation["component"].asString();
- bmi_install.Destination = bmi_installation["destination"].asString();
- bmi_install.ExcludeFromAll = bmi_installation["exclude-from-all"].asBool();
- bmi_install.Optional = bmi_installation["optional"].asBool();
- bmi_install.Permissions = bmi_installation["permissions"].asString();
- bmi_install.MessageLevel = bmi_installation["message-level"].asString();
- bmi_install.ScriptLocation =
- bmi_installation["script-location"].asString();
-
- export_info.BmiInstallation = bmi_install;
- }
- Json::Value const& tdi_cxx_modules = tdi["cxx-modules"];
- if (tdi_cxx_modules.isObject()) {
- for (auto i = tdi_cxx_modules.begin(); i != tdi_cxx_modules.end(); ++i) {
- CxxModuleFileSet& fsi = export_info.ObjectToFileSet[i.key().asString()];
- auto const& tdi_cxx_module_info = *i;
- fsi.Name = tdi_cxx_module_info["name"].asString();
- fsi.RelativeDirectory =
- tdi_cxx_module_info["relative-directory"].asString();
- fsi.SourcePath = tdi_cxx_module_info["source"].asString();
- fsi.Type = tdi_cxx_module_info["type"].asString();
- fsi.Visibility = cmFileSetVisibilityFromName(
- tdi_cxx_module_info["visibility"].asString(), nullptr);
- auto const& tdi_fs_dest = tdi_cxx_module_info["destination"];
- if (tdi_fs_dest.isString()) {
- fsi.Destination = tdi_fs_dest.asString();
- }
- }
- }
+ auto export_info = cmDyndepCollation::ParseExportInfo(tdi);
cmake cm(cmake::RoleInternal, cmState::Unknown);
cm.SetHomeDirectory(dir_top_src);
@@ -3160,7 +2812,7 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
!cm::static_reference_cast<cmGlobalNinjaGenerator>(ggd).WriteDyndepFile(
dir_top_src, dir_top_bld, dir_cur_src, dir_cur_bld, arg_dd, arg_ddis,
module_dir, linked_target_dirs, arg_lang, arg_modmapfmt,
- export_info)) {
+ *export_info)) {
return 1;
}
return 0;
@@ -3208,10 +2860,10 @@ cmGlobalNinjaMultiGenerator::cmGlobalNinjaMultiGenerator(cmake* cm)
cm->GetState()->SetNinjaMulti(true);
}
-void cmGlobalNinjaMultiGenerator::GetDocumentation(cmDocumentationEntry& entry)
+cmDocumentationEntry cmGlobalNinjaMultiGenerator::GetDocumentation()
{
- entry.Name = cmGlobalNinjaMultiGenerator::GetActualName();
- entry.Brief = "Generates build-<Config>.ninja files.";
+ return { cmGlobalNinjaMultiGenerator::GetActualName(),
+ "Generates build-<Config>.ninja files." };
}
std::string cmGlobalNinjaMultiGenerator::ExpandCFGIntDir(