Merge topic 'cxxmodules-no-longer-experimental'

437280b127 cxxmodules: scan C++ sources for imports by default
3cddd11649 Ninja: message about not compiled sources explicitly
068fde1c34 cmGeneratorTarget: use `this->` for method calls
197a6bf171 cxxmodules: rework control logic for scanning regular C++ sources
5eb7bd641a Tests/RunCMake/CXXModules: remove rules file requirement
ff18acc301 CXXModules: remove `EXPERIMENTAL` from C++ module variable names
0c07f39006 cmExperimental: remove the flag for C++ modules
68caec9137 Help: 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:
Brad King
2023-10-02 15:55:20 +00:00
committed by Kitware Robot
175 changed files with 564 additions and 868 deletions
+11 -13
View File
@@ -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,
-11
View File
@@ -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",
-1
View File
@@ -15,7 +15,6 @@ class cmExperimental
public:
enum class Feature
{
CxxModuleCMakeApi,
WindowsKernelModeDriver,
Sentinel,
+5 -10
View File
@@ -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
View File
@@ -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
+2 -2
View File
@@ -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) {
-8
View File
@@ -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) {
+4 -21
View File
@@ -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);
-8
View File
@@ -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
+34 -10
View File
@@ -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
View File
@@ -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 -21
View File
@@ -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 =