mirror of
https://github.com/Kitware/CMake.git
synced 2026-04-23 22:58:37 -05:00
Merge topic 'cxxmodules-no-longer-experimental'
437280b127cxxmodules: scan C++ sources for imports by default3cddd11649Ninja: message about not compiled sources explicitly068fde1c34cmGeneratorTarget: use `this->` for method calls197a6bf171cxxmodules: rework control logic for scanning regular C++ sources5eb7bd641aTests/RunCMake/CXXModules: remove rules file requirementff18acc301CXXModules: remove `EXPERIMENTAL` from C++ module variable names0c07f39006cmExperimental: remove the flag for C++ modules68caec9137Help: add a manpage for cxxmodule support Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Pavel Solodovnikov <hellyeahdominate@gmail.com> Merge-request: !8828
This commit is contained in:
+11
-13
@@ -235,25 +235,16 @@ ArgumentParser::Continue cmCoreTryCompile::Arguments::SetSourceType(
|
||||
this->SourceTypeContext = SourceType::Normal;
|
||||
matched = true;
|
||||
} else if (sourceType == "CXX_MODULE"_s) {
|
||||
bool const supportCxxModuleSources = cmExperimental::HasSupportEnabled(
|
||||
*this->Makefile, cmExperimental::Feature::CxxModuleCMakeApi);
|
||||
if (supportCxxModuleSources) {
|
||||
this->SourceTypeContext = SourceType::CxxModule;
|
||||
matched = true;
|
||||
}
|
||||
this->SourceTypeContext = SourceType::CxxModule;
|
||||
matched = true;
|
||||
}
|
||||
|
||||
if (!matched && this->SourceTypeError.empty()) {
|
||||
bool const supportCxxModuleSources = cmExperimental::HasSupportEnabled(
|
||||
*this->Makefile, cmExperimental::Feature::CxxModuleCMakeApi);
|
||||
auto const* message = "'SOURCE'";
|
||||
if (supportCxxModuleSources) {
|
||||
message = "one of 'SOURCE' or 'CXX_MODULE'";
|
||||
}
|
||||
// Only remember one error at a time; all other errors related to argument
|
||||
// parsing are "indicate one error and return" anyways.
|
||||
this->SourceTypeError =
|
||||
cmStrCat("Invalid 'SOURCE_TYPE' '", sourceType, "'; must be ", message);
|
||||
cmStrCat("Invalid 'SOURCE_TYPE' '", sourceType,
|
||||
"'; must be one of 'SOURCE' or 'CXX_MODULE'");
|
||||
}
|
||||
return ArgumentParser::Continue::Yes;
|
||||
}
|
||||
@@ -880,6 +871,13 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
|
||||
? "NEW"
|
||||
: "OLD");
|
||||
|
||||
/* Set the appropriate policy information for C++ module support */
|
||||
fprintf(fout, "cmake_policy(SET CMP0155 %s)\n",
|
||||
this->Makefile->GetPolicyStatus(cmPolicies::CMP0155) ==
|
||||
cmPolicies::NEW
|
||||
? "NEW"
|
||||
: "OLD");
|
||||
|
||||
// Workaround for -Wl,-headerpad_max_install_names issue until we can avoid
|
||||
// adding that flag in the platform and compiler language files
|
||||
fprintf(fout,
|
||||
|
||||
@@ -19,17 +19,6 @@ namespace {
|
||||
* up-to-date.
|
||||
*/
|
||||
cmExperimental::FeatureData LookupTable[] = {
|
||||
// CxxModuleCMakeApi
|
||||
{ "CxxModuleCMakeApi",
|
||||
"ac01f462-0f5f-432a-86aa-acef252918a6",
|
||||
"CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API",
|
||||
"CMake's C++ module support is experimental. It is meant only for "
|
||||
"experimentation and feedback to CMake developers.",
|
||||
{ "CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE",
|
||||
"CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT",
|
||||
"CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG" },
|
||||
cmExperimental::TryCompileCondition::SkipCompilerChecks,
|
||||
false },
|
||||
// WindowsKernelModeDriver
|
||||
{ "WindowsKernelModeDriver",
|
||||
"5c2d848d-4efa-4529-a768-efd57171bf68",
|
||||
|
||||
@@ -15,7 +15,6 @@ class cmExperimental
|
||||
public:
|
||||
enum class Feature
|
||||
{
|
||||
CxxModuleCMakeApi,
|
||||
WindowsKernelModeDriver,
|
||||
|
||||
Sentinel,
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "cmArgumentParserTypes.h"
|
||||
#include "cmCryptoHash.h"
|
||||
#include "cmExecutionStatus.h"
|
||||
#include "cmExperimental.h"
|
||||
#include "cmExportBuildAndroidMKGenerator.h"
|
||||
#include "cmExportBuildFileGenerator.h"
|
||||
#include "cmExportSet.h"
|
||||
@@ -69,15 +68,11 @@ bool cmExportCommand(std::vector<std::string> const& args,
|
||||
bool ExportOld = false;
|
||||
};
|
||||
|
||||
auto parser = cmArgumentParser<Arguments>{}
|
||||
.Bind("NAMESPACE"_s, &Arguments::Namespace)
|
||||
.Bind("FILE"_s, &Arguments::Filename);
|
||||
|
||||
bool const supportCxx20FileSetTypes = cmExperimental::HasSupportEnabled(
|
||||
status.GetMakefile(), cmExperimental::Feature::CxxModuleCMakeApi);
|
||||
if (supportCxx20FileSetTypes) {
|
||||
parser.Bind("CXX_MODULES_DIRECTORY"_s, &Arguments::CxxModulesDirectory);
|
||||
}
|
||||
auto parser =
|
||||
cmArgumentParser<Arguments>{}
|
||||
.Bind("NAMESPACE"_s, &Arguments::Namespace)
|
||||
.Bind("FILE"_s, &Arguments::Filename)
|
||||
.Bind("CXX_MODULES_DIRECTORY"_s, &Arguments::CxxModulesDirectory);
|
||||
|
||||
if (args[0] == "EXPORT") {
|
||||
parser.Bind("EXPORT"_s, &Arguments::ExportSetName);
|
||||
|
||||
+112
-43
@@ -31,7 +31,6 @@
|
||||
#include "cmCustomCommandGenerator.h"
|
||||
#include "cmCxxModuleUsageEffects.h"
|
||||
#include "cmEvaluatedTargetProperty.h"
|
||||
#include "cmExperimental.h"
|
||||
#include "cmFileSet.h"
|
||||
#include "cmFileTimes.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
@@ -9047,7 +9046,7 @@ std::string cmGeneratorTarget::GetImportedXcFrameworkPath(
|
||||
|
||||
bool cmGeneratorTarget::HaveFortranSources(std::string const& config) const
|
||||
{
|
||||
auto sources = cmGeneratorTarget::GetSourceFiles(config);
|
||||
auto sources = this->GetSourceFiles(config);
|
||||
return std::any_of(sources.begin(), sources.end(),
|
||||
[](BT<cmSourceFile*> const& sf) -> bool {
|
||||
return sf.Value->GetLanguage() == "Fortran"_s;
|
||||
@@ -9106,54 +9105,93 @@ cmGeneratorTarget::Cxx20SupportLevel cmGeneratorTarget::HaveCxxModuleSupport(
|
||||
// Else, an empty CMAKE_CXX_STANDARD_DEFAULT means CMake does not detect and
|
||||
// set a default standard level for this compiler, so assume all standards
|
||||
// are available.
|
||||
if (!cmExperimental::HasSupportEnabled(
|
||||
*this->Makefile, cmExperimental::Feature::CxxModuleCMakeApi)) {
|
||||
return Cxx20SupportLevel::MissingExperimentalFlag;
|
||||
cmValue scandepRule =
|
||||
this->Target->GetMakefile()->GetDefinition("CMAKE_CXX_SCANDEP_SOURCE");
|
||||
if (!scandepRule) {
|
||||
return Cxx20SupportLevel::MissingRule;
|
||||
}
|
||||
return Cxx20SupportLevel::Supported;
|
||||
}
|
||||
|
||||
void cmGeneratorTarget::CheckCxxModuleStatus(std::string const& config) const
|
||||
{
|
||||
bool haveScannableSources = false;
|
||||
|
||||
// Check for `CXX_MODULE*` file sets and a lack of support.
|
||||
if (this->HaveCxx20ModuleSources()) {
|
||||
switch (this->HaveCxxModuleSupport(config)) {
|
||||
case cmGeneratorTarget::Cxx20SupportLevel::MissingCxx:
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("The target named \"", this->GetName(),
|
||||
"\" has C++ sources that export modules but the \"CXX\" "
|
||||
"language has not been enabled"));
|
||||
break;
|
||||
case cmGeneratorTarget::Cxx20SupportLevel::MissingExperimentalFlag:
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("The target named \"", this->GetName(),
|
||||
"\" has C++ sources that export modules but its "
|
||||
"experimental support has not been requested"));
|
||||
break;
|
||||
case cmGeneratorTarget::Cxx20SupportLevel::NoCxx20: {
|
||||
cmStandardLevelResolver standardResolver(this->Makefile);
|
||||
auto effStandard =
|
||||
standardResolver.GetEffectiveStandard(this, "CXX", config);
|
||||
if (effStandard.empty()) {
|
||||
effStandard = "; no C++ standard found";
|
||||
} else {
|
||||
effStandard = cmStrCat("; found \"cxx_std_", effStandard, '"');
|
||||
}
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat(
|
||||
"The target named \"", this->GetName(),
|
||||
"\" has C++ sources that export modules but does not include "
|
||||
"\"cxx_std_20\" (or newer) among its `target_compile_features`",
|
||||
effStandard));
|
||||
} break;
|
||||
case cmGeneratorTarget::Cxx20SupportLevel::Supported:
|
||||
// All is well.
|
||||
break;
|
||||
haveScannableSources = true;
|
||||
}
|
||||
|
||||
if (!haveScannableSources) {
|
||||
// Check to see if there are regular sources that have requested scanning.
|
||||
auto sources = this->GetSourceFiles(config);
|
||||
for (auto const& source : sources) {
|
||||
auto const* sf = source.Value;
|
||||
auto const& lang = sf->GetLanguage();
|
||||
if (lang != "CXX"_s) {
|
||||
continue;
|
||||
}
|
||||
// Ignore sources which do not need dyndep.
|
||||
if (this->NeedDyndepForSource(lang, config, sf)) {
|
||||
haveScannableSources = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there isn't anything scannable, ignore it.
|
||||
if (!haveScannableSources) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the generator doesn't support modules at all, error that we have
|
||||
// sources that require the support.
|
||||
if (!this->GetGlobalGenerator()->CheckCxxModuleSupport()) {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat(
|
||||
"The target named \"", this->GetName(),
|
||||
"\" contains C++ "
|
||||
"sources that use modules which is not supported by the generator"));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (this->HaveCxxModuleSupport(config)) {
|
||||
case cmGeneratorTarget::Cxx20SupportLevel::MissingCxx:
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("The target named \"", this->GetName(),
|
||||
"\" has C++ sources that use modules but the \"CXX\" "
|
||||
"language has not been enabled"));
|
||||
break;
|
||||
case cmGeneratorTarget::Cxx20SupportLevel::NoCxx20: {
|
||||
cmStandardLevelResolver standardResolver(this->Makefile);
|
||||
auto effStandard =
|
||||
standardResolver.GetEffectiveStandard(this, "CXX", config);
|
||||
if (effStandard.empty()) {
|
||||
effStandard = "; no C++ standard found";
|
||||
} else {
|
||||
effStandard = cmStrCat("; found \"cxx_std_", effStandard, '"');
|
||||
}
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat(
|
||||
"The target named \"", this->GetName(),
|
||||
"\" has C++ sources that use modules but does not include "
|
||||
"\"cxx_std_20\" (or newer) among its `target_compile_features`",
|
||||
effStandard));
|
||||
} break;
|
||||
case cmGeneratorTarget::Cxx20SupportLevel::MissingRule: {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("The target named \"", this->GetName(),
|
||||
"\" has C++ sources that use modules but the compiler does "
|
||||
"not provide a way to discover the import graph "
|
||||
"dependencies"));
|
||||
} break;
|
||||
case cmGeneratorTarget::Cxx20SupportLevel::Supported:
|
||||
// All is well.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool cmGeneratorTarget::NeedCxxModuleSupport(std::string const& lang,
|
||||
@@ -9191,14 +9229,30 @@ bool cmGeneratorTarget::NeedDyndepForSource(std::string const& lang,
|
||||
std::string const& config,
|
||||
cmSourceFile const* sf) const
|
||||
{
|
||||
bool const needDyndep = this->NeedDyndep(lang, config);
|
||||
if (!needDyndep) {
|
||||
// Fortran always needs to be scanned.
|
||||
if (lang == "Fortran"_s) {
|
||||
return true;
|
||||
}
|
||||
// Only C++ code needs scanned otherwise.
|
||||
if (lang != "CXX"_s) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Any file in `CXX_MODULES` file sets need scanned (it being `CXX` is
|
||||
// enforced elsewhere).
|
||||
auto const* fs = this->GetFileSetForSource(config, sf);
|
||||
if (fs && fs->GetType() == "CXX_MODULES"_s) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (this->HaveCxxModuleSupport(config)) {
|
||||
case Cxx20SupportLevel::MissingCxx:
|
||||
case Cxx20SupportLevel::NoCxx20:
|
||||
return false;
|
||||
case Cxx20SupportLevel::MissingRule:
|
||||
case Cxx20SupportLevel::Supported:
|
||||
break;
|
||||
}
|
||||
auto const sfProp = sf->GetProperty("CXX_SCAN_FOR_MODULES");
|
||||
if (sfProp.IsSet()) {
|
||||
return sfProp.IsOn();
|
||||
@@ -9207,7 +9261,22 @@ bool cmGeneratorTarget::NeedDyndepForSource(std::string const& lang,
|
||||
if (tgtProp.IsSet()) {
|
||||
return tgtProp.IsOn();
|
||||
}
|
||||
return true;
|
||||
|
||||
bool policyAnswer = false;
|
||||
switch (this->GetPolicyStatusCMP0155()) {
|
||||
case cmPolicies::WARN:
|
||||
case cmPolicies::OLD:
|
||||
// The OLD behavior is to not scan the source.
|
||||
policyAnswer = false;
|
||||
break;
|
||||
case cmPolicies::REQUIRED_ALWAYS:
|
||||
case cmPolicies::REQUIRED_IF_USED:
|
||||
case cmPolicies::NEW:
|
||||
// The NEW behavior is to scan the source.
|
||||
policyAnswer = true;
|
||||
break;
|
||||
}
|
||||
return policyAnswer;
|
||||
}
|
||||
|
||||
void cmGeneratorTarget::BuildFileSetInfoCache(std::string const& config) const
|
||||
|
||||
@@ -1288,10 +1288,10 @@ public:
|
||||
{
|
||||
// C++ is not available.
|
||||
MissingCxx,
|
||||
// The experimental feature is not available.
|
||||
MissingExperimentalFlag,
|
||||
// The target does not require at least C++20.
|
||||
NoCxx20,
|
||||
// C++20 module scanning rules are not present.
|
||||
MissingRule,
|
||||
// C++20 modules are available and working.
|
||||
Supported,
|
||||
};
|
||||
|
||||
@@ -435,14 +435,6 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
|
||||
target->CheckCxxModuleStatus(c);
|
||||
}
|
||||
|
||||
if (target->HaveCxx20ModuleSources() && !this->SupportsCxxModuleDyndep()) {
|
||||
root->GetMakefile()->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("The target named \"", target->GetName(),
|
||||
"\" contains C++ sources that export modules which is not "
|
||||
"supported by the generator"));
|
||||
}
|
||||
|
||||
// handle external vc project files
|
||||
cmValue expath = target->GetProperty("EXTERNAL_MSPROJECT");
|
||||
if (expath) {
|
||||
|
||||
@@ -1384,14 +1384,6 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
|
||||
gtgt->CheckCxxModuleStatus(configName);
|
||||
}
|
||||
|
||||
if (gtgt->HaveCxx20ModuleSources()) {
|
||||
gtgt->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("The target named \"", gtgt->GetName(),
|
||||
"\" contains C++ sources that export modules which is not "
|
||||
"supported by the generator"));
|
||||
}
|
||||
|
||||
auto& gtgt_visited = this->CommandsVisited[gtgt];
|
||||
auto const& deps = this->GetTargetDirectDepends(gtgt);
|
||||
for (auto const& d : deps) {
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "cmArgumentParser.h"
|
||||
#include "cmArgumentParserTypes.h"
|
||||
#include "cmExecutionStatus.h"
|
||||
#include "cmExperimental.h"
|
||||
#include "cmExportSet.h"
|
||||
#include "cmFileSet.h"
|
||||
#include "cmGeneratorExpression.h"
|
||||
@@ -491,6 +490,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
||||
publicHeaderArgs.Parse(argVectors.PublicHeader, &unknownArgs);
|
||||
resourceArgs.Parse(argVectors.Resource, &unknownArgs);
|
||||
includesArgs.Parse(&argVectors.Includes, &unknownArgs);
|
||||
cxxModuleBmiArgs.Parse(argVectors.CxxModulesBmi, &unknownArgs);
|
||||
for (std::size_t i = 0; i < argVectors.FileSets.size(); i++) {
|
||||
// We have to create a separate object for the parsing because
|
||||
// cmArgumentParser<void>::Bind() binds to a specific address, but the
|
||||
@@ -501,15 +501,6 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
||||
fileSetArgs[i] = std::move(fileSetArg);
|
||||
}
|
||||
|
||||
bool const supportCxx20FileSetTypes = cmExperimental::HasSupportEnabled(
|
||||
*helper.Makefile, cmExperimental::Feature::CxxModuleCMakeApi);
|
||||
if (!supportCxx20FileSetTypes) {
|
||||
std::copy(argVectors.CxxModulesBmi.begin(), argVectors.CxxModulesBmi.end(),
|
||||
std::back_inserter(unknownArgs));
|
||||
} else {
|
||||
cxxModuleBmiArgs.Parse(argVectors.CxxModulesBmi, &unknownArgs);
|
||||
}
|
||||
|
||||
if (!unknownArgs.empty()) {
|
||||
// Unknown argument.
|
||||
status.SetError(
|
||||
@@ -541,12 +532,10 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
||||
success = success && privateHeaderArgs.Finalize();
|
||||
success = success && publicHeaderArgs.Finalize();
|
||||
success = success && resourceArgs.Finalize();
|
||||
success = success && cxxModuleBmiArgs.Finalize();
|
||||
for (auto& fileSetArg : fileSetArgs) {
|
||||
success = success && fileSetArg.Finalize();
|
||||
}
|
||||
if (supportCxx20FileSetTypes) {
|
||||
success = success && cxxModuleBmiArgs.Finalize();
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
return false;
|
||||
@@ -1173,8 +1162,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
||||
}
|
||||
}
|
||||
|
||||
if (supportCxx20FileSetTypes &&
|
||||
!cxxModuleBmiArgs.GetDestination().empty()) {
|
||||
if (!cxxModuleBmiArgs.GetDestination().empty()) {
|
||||
cxxModuleBmiGenerator = cm::make_unique<cmInstallCxxModuleBmiGenerator>(
|
||||
target.GetName(),
|
||||
helper.GetCxxModulesBmiDestination(&cxxModuleBmiArgs),
|
||||
@@ -2071,12 +2059,7 @@ bool HandleExportMode(std::vector<std::string> const& args,
|
||||
ica.Bind("NAMESPACE"_s, name_space);
|
||||
ica.Bind("EXPORT_LINK_INTERFACE_LIBRARIES"_s, exportOld);
|
||||
ica.Bind("FILE"_s, filename);
|
||||
|
||||
bool const supportCxx20FileSetTypes = cmExperimental::HasSupportEnabled(
|
||||
*helper.Makefile, cmExperimental::Feature::CxxModuleCMakeApi);
|
||||
if (supportCxx20FileSetTypes) {
|
||||
ica.Bind("CXX_MODULES_DIRECTORY"_s, cxx_modules_directory);
|
||||
}
|
||||
ica.Bind("CXX_MODULES_DIRECTORY"_s, cxx_modules_directory);
|
||||
|
||||
std::vector<std::string> unknownArgs;
|
||||
ica.Parse(args, &unknownArgs);
|
||||
|
||||
@@ -204,14 +204,6 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
|
||||
{
|
||||
this->GeneratorTarget->CheckCxxModuleStatus(this->GetConfigName());
|
||||
|
||||
if (this->GeneratorTarget->HaveCxx20ModuleSources()) {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("The target named \"", this->GeneratorTarget->GetName(),
|
||||
"\" contains C++ sources that export modules which is not "
|
||||
"supported by the generator"));
|
||||
}
|
||||
|
||||
// -- Write the custom commands for this target
|
||||
|
||||
// Evaluates generator expressions and expands prop_value
|
||||
|
||||
@@ -266,7 +266,7 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
|
||||
|
||||
if (!this->GeneratorTarget->Target->IsNormal()) {
|
||||
auto flag = this->GetMakefile()->GetSafeDefinition(
|
||||
"CMAKE_EXPERIMENTAL_CXX_MODULE_BMI_ONLY_FLAG");
|
||||
"CMAKE_CXX_MODULE_BMI_ONLY_FLAG");
|
||||
cmRulePlaceholderExpander::RuleVariables compileObjectVars;
|
||||
compileObjectVars.Object = objectFileName.c_str();
|
||||
auto rulePlaceholderExpander =
|
||||
@@ -710,7 +710,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
|
||||
}
|
||||
}
|
||||
std::string const modmapFormatVar =
|
||||
cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_MODULE_MAP_FORMAT");
|
||||
cmStrCat("CMAKE_", lang, "_MODULE_MAP_FORMAT");
|
||||
std::string const modmapFormat =
|
||||
this->Makefile->GetSafeDefinition(modmapFormatVar);
|
||||
|
||||
@@ -734,7 +734,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
|
||||
|
||||
if (withScanning == WithScanning::Yes) {
|
||||
const auto& scanDepType = this->GetMakefile()->GetSafeDefinition(
|
||||
cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_SCANDEP_DEPFILE_FORMAT"));
|
||||
cmStrCat("CMAKE_", lang, "_SCANDEP_DEPFILE_FORMAT"));
|
||||
|
||||
// Rule to scan dependencies of sources that need preprocessing.
|
||||
{
|
||||
@@ -745,7 +745,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
|
||||
scanRuleName = this->LanguageScanRule(lang, config);
|
||||
ppFileName = "$PREPROCESSED_OUTPUT_FILE";
|
||||
std::string const& scanCommand = mf->GetRequiredDefinition(
|
||||
cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_SCANDEP_SOURCE"));
|
||||
cmStrCat("CMAKE_", lang, "_SCANDEP_SOURCE"));
|
||||
scanCommands.assign(scanCommand);
|
||||
for (auto& i : scanCommands) {
|
||||
i = cmStrCat(launcher, i);
|
||||
@@ -893,8 +893,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
|
||||
}
|
||||
|
||||
if (withScanning == WithScanning::Yes && !modmapFormat.empty()) {
|
||||
std::string modmapFlags = mf->GetRequiredDefinition(
|
||||
cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_MODULE_MAP_FLAG"));
|
||||
std::string modmapFlags =
|
||||
mf->GetRequiredDefinition(cmStrCat("CMAKE_", lang, "_MODULE_MAP_FLAG"));
|
||||
cmSystemTools::ReplaceString(modmapFlags, "<MODULE_MAP_FILE>",
|
||||
"$DYNDEP_MODULE_MAP_FILE");
|
||||
flags += cmStrCat(' ', modmapFlags);
|
||||
@@ -1143,6 +1143,30 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
|
||||
}
|
||||
}
|
||||
|
||||
// Detect sources in `CXX_MODULES` which are not compiled.
|
||||
{
|
||||
std::vector<cmSourceFile*> sources;
|
||||
this->GeneratorTarget->GetSourceFiles(sources, config);
|
||||
for (cmSourceFile const* sf : sources) {
|
||||
cmFileSet const* fs =
|
||||
this->GeneratorTarget->GetFileSetForSource(config, sf);
|
||||
if (!fs) {
|
||||
continue;
|
||||
}
|
||||
if (fs->GetType() != "CXX_MODULES"_s) {
|
||||
continue;
|
||||
}
|
||||
if (sf->GetLanguage().empty()) {
|
||||
this->GeneratorTarget->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("Target \"", this->GeneratorTarget->GetName(),
|
||||
"\" has source file\n ", sf->GetFullPath(),
|
||||
"\nin a \"FILE_SET TYPE CXX_MODULES\" but it is not "
|
||||
"scheduled for compilation."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto const& langScanningFiles : this->Configs[config].ScanningInfo) {
|
||||
std::string const& language = langScanningFiles.first;
|
||||
std::vector<ScanningFiles> const& scanningFiles = langScanningFiles.second;
|
||||
@@ -1477,7 +1501,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
||||
std::string modmapFormat;
|
||||
if (needDyndep) {
|
||||
std::string const modmapFormatVar =
|
||||
cmStrCat("CMAKE_EXPERIMENTAL_", language, "_MODULE_MAP_FORMAT");
|
||||
cmStrCat("CMAKE_", language, "_MODULE_MAP_FORMAT");
|
||||
modmapFormat = this->Makefile->GetSafeDefinition(modmapFormatVar);
|
||||
}
|
||||
|
||||
@@ -1758,7 +1782,7 @@ void cmNinjaTargetGenerator::WriteCxxModuleBmiBuildStatement(
|
||||
std::string modmapFormat;
|
||||
if (true) {
|
||||
std::string const modmapFormatVar =
|
||||
cmStrCat("CMAKE_EXPERIMENTAL_", language, "_MODULE_MAP_FORMAT");
|
||||
cmStrCat("CMAKE_", language, "_MODULE_MAP_FORMAT");
|
||||
modmapFormat = this->Makefile->GetSafeDefinition(modmapFormatVar);
|
||||
}
|
||||
|
||||
@@ -1969,12 +1993,12 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
|
||||
bool const needDyndep =
|
||||
this->GetGeneratorTarget()->NeedDyndep(language, outputConfig);
|
||||
std::string const modmapFormatVar =
|
||||
cmStrCat("CMAKE_EXPERIMENTAL_", language, "_MODULE_MAP_FORMAT");
|
||||
cmStrCat("CMAKE_", language, "_MODULE_MAP_FORMAT");
|
||||
std::string const modmapFormat =
|
||||
this->Makefile->GetSafeDefinition(modmapFormatVar);
|
||||
if (needDyndep && !modmapFormat.empty()) {
|
||||
std::string modmapFlags = this->GetMakefile()->GetRequiredDefinition(
|
||||
cmStrCat("CMAKE_EXPERIMENTAL_", language, "_MODULE_MAP_FLAG"));
|
||||
cmStrCat("CMAKE_", language, "_MODULE_MAP_FLAG"));
|
||||
// XXX(modmap): If changing this path construction, change
|
||||
// `cmGlobalNinjaGenerator::WriteDyndep` and
|
||||
// `cmNinjaTargetGenerator::WriteObjectBuildStatement` to expect the
|
||||
|
||||
+6
-1
@@ -469,6 +469,10 @@ class cmMakefile;
|
||||
SELECT( \
|
||||
POLICY, CMP0154, \
|
||||
"Generated files are private by default in targets using file sets.", 3, \
|
||||
28, 0, cmPolicies::WARN) \
|
||||
SELECT( \
|
||||
POLICY, CMP0155, \
|
||||
"C++ sources in targets with at least C++20 are scanned for imports", 3, \
|
||||
28, 0, cmPolicies::WARN)
|
||||
|
||||
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
|
||||
@@ -508,7 +512,8 @@ class cmMakefile;
|
||||
F(CMP0119) \
|
||||
F(CMP0131) \
|
||||
F(CMP0142) \
|
||||
F(CMP0154)
|
||||
F(CMP0154) \
|
||||
F(CMP0155)
|
||||
|
||||
#define CM_FOR_EACH_CUSTOM_COMMAND_POLICY(F) \
|
||||
F(CMP0116) \
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
#include "cmArgumentParser.h"
|
||||
#include "cmArgumentParserTypes.h"
|
||||
#include "cmExperimental.h"
|
||||
#include "cmFileSet.h"
|
||||
#include "cmGeneratorExpression.h"
|
||||
#include "cmList.h"
|
||||
@@ -260,28 +259,18 @@ bool TargetSourcesImpl::HandleOneFileSet(
|
||||
this->SetError("Must specify a TYPE when creating file set");
|
||||
return false;
|
||||
}
|
||||
bool const supportCxx20FileSetTypes = cmExperimental::HasSupportEnabled(
|
||||
*this->Makefile, cmExperimental::Feature::CxxModuleCMakeApi);
|
||||
if (type != "HEADERS"_s && type != "CXX_MODULES"_s) {
|
||||
this->SetError(
|
||||
R"(File set TYPE may only be "HEADERS" or "CXX_MODULES")");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (supportCxx20FileSetTypes) {
|
||||
if (type != "HEADERS"_s && type != "CXX_MODULES"_s) {
|
||||
if (cmFileSetVisibilityIsForInterface(visibility) &&
|
||||
!cmFileSetVisibilityIsForSelf(visibility) &&
|
||||
!this->Target->IsImported()) {
|
||||
if (type == "CXX_MODULES"_s) {
|
||||
this->SetError(
|
||||
R"(File set TYPE may only be "HEADERS" or "CXX_MODULES")");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cmFileSetVisibilityIsForInterface(visibility) &&
|
||||
!cmFileSetVisibilityIsForSelf(visibility) &&
|
||||
!this->Target->IsImported()) {
|
||||
if (type == "CXX_MODULES"_s) {
|
||||
this->SetError(
|
||||
R"(File set TYPE "CXX_MODULES" may not have "INTERFACE" visibility)");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (type != "HEADERS"_s) {
|
||||
this->SetError("File set TYPE may only be \"HEADERS\"");
|
||||
R"(File set TYPE "CXX_MODULES" may not have "INTERFACE" visibility)");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,15 +362,6 @@ void cmVisualStudio10TargetGenerator::Generate()
|
||||
this->GeneratorTarget->CheckCxxModuleStatus(config);
|
||||
}
|
||||
|
||||
if (this->GeneratorTarget->HaveCxx20ModuleSources() &&
|
||||
!this->GlobalGenerator->SupportsCxxModuleDyndep()) {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("The target named \"", this->GeneratorTarget->GetName(),
|
||||
"\" contains C++ sources that export modules which is not "
|
||||
"supported by the generator"));
|
||||
}
|
||||
|
||||
this->ProjectType = computeProjectType(this->GeneratorTarget);
|
||||
this->Managed = this->ProjectType == VsProjectType::csproj;
|
||||
const std::string ProjectFileExtension =
|
||||
|
||||
Reference in New Issue
Block a user