From 29118091dc323d3b48b58155ac0e30b47ca60fb6 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Fri, 22 Apr 2022 18:00:47 -0400 Subject: install: support `CXX_MODULES_BMI` installation bits --- Help/command/install.rst | 14 +++- Source/CMakeLists.txt | 2 + Source/cmFileAPICodemodel.cxx | 16 +++++ Source/cmInstallCommand.cxx | 65 +++++++++++++++++-- Source/cmInstallCxxModuleBmiGenerator.cxx | 75 ++++++++++++++++++++++ Source/cmInstallCxxModuleBmiGenerator.h | 52 +++++++++++++++ Source/cmTargetExport.h | 2 + Tests/RunCMake/CXXModules/InstallBMI-check.cmake | 24 +++++++ Tests/RunCMake/CXXModules/InstallBMI-stderr.txt | 6 ++ Tests/RunCMake/CXXModules/InstallBMI.cmake | 23 +++++++ .../CXXModules/InstallBMIGenericArgs-check.cmake | 8 +++ .../CXXModules/InstallBMIGenericArgs-stderr.txt | 6 ++ .../CXXModules/InstallBMIGenericArgs.cmake | 9 +++ .../CXXModules/InstallBMIIgnore-check.cmake | 13 ++++ .../CXXModules/InstallBMIIgnore-stderr.txt | 6 ++ Tests/RunCMake/CXXModules/InstallBMIIgnore.cmake | 9 +++ .../CXXModules/InstallBMINoGenericArgs-check.cmake | 8 +++ Tests/RunCMake/CXXModules/RunCMakeTest.cmake | 4 ++ Tests/RunCMake/FileAPI/codemodel-v2-check.py | 10 +++ bootstrap | 1 + 20 files changed, 347 insertions(+), 6 deletions(-) create mode 100644 Source/cmInstallCxxModuleBmiGenerator.cxx create mode 100644 Source/cmInstallCxxModuleBmiGenerator.h create mode 100644 Tests/RunCMake/CXXModules/InstallBMI-check.cmake create mode 100644 Tests/RunCMake/CXXModules/InstallBMI-stderr.txt create mode 100644 Tests/RunCMake/CXXModules/InstallBMI.cmake create mode 100644 Tests/RunCMake/CXXModules/InstallBMIGenericArgs-check.cmake create mode 100644 Tests/RunCMake/CXXModules/InstallBMIGenericArgs-stderr.txt create mode 100644 Tests/RunCMake/CXXModules/InstallBMIGenericArgs.cmake create mode 100644 Tests/RunCMake/CXXModules/InstallBMIIgnore-check.cmake create mode 100644 Tests/RunCMake/CXXModules/InstallBMIIgnore-stderr.txt create mode 100644 Tests/RunCMake/CXXModules/InstallBMIIgnore.cmake create mode 100644 Tests/RunCMake/CXXModules/InstallBMINoGenericArgs-check.cmake diff --git a/Help/command/install.rst b/Help/command/install.rst index 973aa31..d64fe5e 100644 --- a/Help/command/install.rst +++ b/Help/command/install.rst @@ -132,7 +132,7 @@ Installing Targets install(TARGETS targets... [EXPORT ] [RUNTIME_DEPENDENCIES args...|RUNTIME_DEPENDENCY_SET ] [[ARCHIVE|LIBRARY|RUNTIME|OBJECTS|FRAMEWORK|BUNDLE| - PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE|FILE_SET ] + PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE|FILE_SET |CXX_MODULES_BMI] [DESTINATION ] [PERMISSIONS permissions...] [CONFIGURATIONS [Debug|Release|...]] @@ -215,6 +215,18 @@ that may be installed: ``/blah/include/myproj/here.h`` with a base directory ``/blah/include`` would be installed to ``myproj/here.h`` below the destination. +``CXX_MODULES_BMI`` + +.. note :: + + Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API`` + + Any module files from C++ modules from ``PUBLIC`` sources in a file set of + type ``CXX_MODULES`` will be installed to the given ``DESTINATION``. All + modules are placed directly in the destination as no directory structure is + derived from the names of the modules. An empty ``DESTINATION`` may be used + to suppress installing these files (for use in generic code). + For each of these arguments given, the arguments following them only apply to the target or file type specified in the argument. If none is given, the installation properties apply to all target types. If only one is given then diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 6312e93..fe92716 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -607,6 +607,8 @@ set(SRCS cmInstallCommand.h cmInstallCommandArguments.cxx cmInstallCommandArguments.h + cmInstallCxxModuleBmiGenerator.cxx + cmInstallCxxModuleBmiGenerator.h cmInstallFilesCommand.cxx cmInstallFilesCommand.h cmInstallProgramsCommand.cxx diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx index dd0540c..0581802 100644 --- a/Source/cmFileAPICodemodel.cxx +++ b/Source/cmFileAPICodemodel.cxx @@ -27,6 +27,7 @@ #include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" +#include "cmInstallCxxModuleBmiGenerator.h" #include "cmInstallDirectoryGenerator.h" #include "cmInstallExportGenerator.h" #include "cmInstallFileSetGenerator.h" @@ -1092,6 +1093,21 @@ Json::Value DirectoryObject::DumpInstaller(cmInstallGenerator* gen) if (installFileSet->GetOptional()) { installer["isOptional"] = true; } + } else if (auto* cxxModuleBmi = + dynamic_cast(gen)) { + installer["type"] = "cxxModuleBmi"; + installer["destination"] = cxxModuleBmi->GetDestination(this->Config); + + auto const* target = cxxModuleBmi->GetTarget(); + installer["cxxModuleBmiTarget"] = Json::objectValue; + installer["cxxModuleBmiTarget"]["id"] = TargetId(target, this->TopBuild); + installer["cxxModuleBmiTarget"]["index"] = this->TargetIndexMap[target]; + + // FIXME: Parse FilePermissions. + // FIXME: Parse MessageLevel. + if (cxxModuleBmi->GetOptional()) { + installer["isOptional"] = true; + } } // Add fields common to all install generators. diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index c03c205..4d77303 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -20,11 +20,13 @@ #include "cmArgumentParser.h" #include "cmExecutionStatus.h" +#include "cmExperimental.h" #include "cmExportSet.h" #include "cmFileSet.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmInstallCommandArguments.h" +#include "cmInstallCxxModuleBmiGenerator.h" #include "cmInstallDirectoryGenerator.h" #include "cmInstallExportGenerator.h" #include "cmInstallFileSetGenerator.h" @@ -110,6 +112,8 @@ public: const cmInstallCommandArguments* args) const; std::string GetLibraryDestination( const cmInstallCommandArguments* args) const; + std::string GetCxxModulesBmiDestination( + const cmInstallCommandArguments* args) const; std::string GetIncludeDestination( const cmInstallCommandArguments* args) const; std::string GetSysconfDestination( @@ -413,6 +417,7 @@ bool HandleTargetsMode(std::vector const& args, std::vector PublicHeader; std::vector Resource; std::vector> FileSets; + std::vector CxxModulesBmi; }; static auto const argHelper = @@ -427,7 +432,8 @@ bool HandleTargetsMode(std::vector const& args, .Bind("PRIVATE_HEADER"_s, &ArgVectors::PrivateHeader) .Bind("PUBLIC_HEADER"_s, &ArgVectors::PublicHeader) .Bind("RESOURCE"_s, &ArgVectors::Resource) - .Bind("FILE_SET"_s, &ArgVectors::FileSets); + .Bind("FILE_SET"_s, &ArgVectors::FileSets) + .Bind("CXX_MODULES_BMI"_s, &ArgVectors::CxxModulesBmi); std::vector genericArgVector; ArgVectors const argVectors = argHelper.Parse(args, &genericArgVector); @@ -466,6 +472,7 @@ bool HandleTargetsMode(std::vector const& args, cmInstallCommandIncludesArgument includesArgs; std::vector fileSetArgs( argVectors.FileSets.size(), { helper.DefaultComponentName }); + cmInstallCommandArguments cxxModuleBmiArgs(helper.DefaultComponentName); // now parse the args for specific parts of the target (e.g. LIBRARY, // RUNTIME, ARCHIVE etc. @@ -489,6 +496,15 @@ bool HandleTargetsMode(std::vector 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( @@ -509,6 +525,7 @@ bool HandleTargetsMode(std::vector const& args, for (auto& fileSetArg : fileSetArgs) { fileSetArg.SetGenericArguments(&genericArgs); } + cxxModuleBmiArgs.SetGenericArguments(&genericArgs); success = success && archiveArgs.Finalize(); success = success && libraryArgs.Finalize(); @@ -522,6 +539,9 @@ bool HandleTargetsMode(std::vector const& args, for (auto& fileSetArg : fileSetArgs) { success = success && fileSetArg.Finalize(); } + if (supportCxx20FileSetTypes) { + success = success && cxxModuleBmiArgs.Finalize(); + } if (!success) { return false; @@ -535,7 +555,8 @@ bool HandleTargetsMode(std::vector const& args, publicHeaderArgs.GetNamelinkOnly() || resourceArgs.GetNamelinkOnly() || std::any_of(fileSetArgs.begin(), fileSetArgs.end(), [](const cmInstallCommandFileSetArguments& fileSetArg) - -> bool { return fileSetArg.GetNamelinkOnly(); })) { + -> bool { return fileSetArg.GetNamelinkOnly(); }) || + cxxModuleBmiArgs.GetNamelinkOnly()) { status.SetError( "TARGETS given NAMELINK_ONLY option not in LIBRARY group. " "The NAMELINK_ONLY option may be specified only following LIBRARY."); @@ -547,7 +568,8 @@ bool HandleTargetsMode(std::vector const& args, publicHeaderArgs.GetNamelinkSkip() || resourceArgs.GetNamelinkSkip() || std::any_of(fileSetArgs.begin(), fileSetArgs.end(), [](const cmInstallCommandFileSetArguments& fileSetArg) - -> bool { return fileSetArg.GetNamelinkSkip(); })) { + -> bool { return fileSetArg.GetNamelinkSkip(); }) || + cxxModuleBmiArgs.GetNamelinkSkip()) { status.SetError( "TARGETS given NAMELINK_SKIP option not in LIBRARY group. " "The NAMELINK_SKIP option may be specified only following LIBRARY."); @@ -563,7 +585,8 @@ bool HandleTargetsMode(std::vector const& args, resourceArgs.HasNamelinkComponent() || std::any_of(fileSetArgs.begin(), fileSetArgs.end(), [](const cmInstallCommandFileSetArguments& fileSetArg) - -> bool { return fileSetArg.HasNamelinkComponent(); })) { + -> bool { return fileSetArg.HasNamelinkComponent(); }) || + cxxModuleBmiArgs.HasNamelinkComponent()) { status.SetError( "TARGETS given NAMELINK_COMPONENT option not in LIBRARY group. " "The NAMELINK_COMPONENT option may be specified only following " @@ -582,7 +605,8 @@ bool HandleTargetsMode(std::vector const& args, !publicHeaderArgs.GetType().empty() || !resourceArgs.GetType().empty() || std::any_of(fileSetArgs.begin(), fileSetArgs.end(), [](const cmInstallCommandFileSetArguments& fileSetArg) - -> bool { return !fileSetArg.GetType().empty(); })) { + -> bool { return !fileSetArg.GetType().empty(); }) || + !cxxModuleBmiArgs.GetType().empty()) { status.SetError( "TARGETS given TYPE option. The TYPE option may only be specified in " " install(FILES) and install(DIRECTORIES)."); @@ -705,6 +729,7 @@ bool HandleTargetsMode(std::vector const& args, bool installsPublicHeader = false; bool installsResource = false; std::vector installsFileSet(fileSetArgs.size(), false); + bool installsCxxModuleBmi = false; // Generate install script code to install the given targets. for (cmTarget* ti : targets) { @@ -721,6 +746,7 @@ bool HandleTargetsMode(std::vector const& args, std::unique_ptr publicHeaderGenerator; std::unique_ptr resourceGenerator; std::vector> fileSetGenerators; + std::unique_ptr cxxModuleBmiGenerator; // Avoid selecting default destinations for PUBLIC_HEADER and // PRIVATE_HEADER if any artifacts are specified. @@ -759,6 +785,7 @@ bool HandleTargetsMode(std::vector const& args, for (auto const& gen : fileSetGenerators) { te->FileSetGenerators[gen->GetFileSet()] = gen.get(); } + te->CxxModuleBmiGenerator = cxxModuleBmiGenerator.get(); target.AddInstallIncludeDirectories( *te, cmMakeRange(includesArgs.GetIncludeDirs())); te->NamelinkOnly = namelinkOnly; @@ -1104,6 +1131,19 @@ bool HandleTargetsMode(std::vector const& args, } } + if (supportCxx20FileSetTypes && + !cxxModuleBmiArgs.GetDestination().empty()) { + cxxModuleBmiGenerator = cm::make_unique( + target.GetName(), + helper.GetCxxModulesBmiDestination(&cxxModuleBmiArgs), + cxxModuleBmiArgs.GetPermissions(), + cxxModuleBmiArgs.GetConfigurations(), cxxModuleBmiArgs.GetComponent(), + cmInstallGenerator::SelectMessageLevel(target.GetMakefile()), + cxxModuleBmiArgs.GetExcludeFromAll(), cxxModuleBmiArgs.GetOptional(), + helper.Makefile->GetBacktrace()); + target.SetHaveInstallRule(true); + } + // Add this install rule to an export if one was specified. if (!addTargetExport()) { return false; @@ -1120,6 +1160,7 @@ bool HandleTargetsMode(std::vector const& args, installsPrivateHeader = installsPrivateHeader || privateHeaderGenerator; installsPublicHeader = installsPublicHeader || publicHeaderGenerator; installsResource = installsResource || resourceGenerator; + installsCxxModuleBmi = installsCxxModuleBmi || cxxModuleBmiGenerator; helper.Makefile->AddInstallGenerator(std::move(archiveGenerator)); helper.Makefile->AddInstallGenerator(std::move(libraryGenerator)); @@ -1134,6 +1175,7 @@ bool HandleTargetsMode(std::vector const& args, for (auto& gen : fileSetGenerators) { helper.Makefile->AddInstallGenerator(std::move(gen)); } + helper.Makefile->AddInstallGenerator(std::move(cxxModuleBmiGenerator)); } if (runtimeDependenciesArgVector && !runtimeDependencySet->Empty()) { @@ -1191,6 +1233,10 @@ bool HandleTargetsMode(std::vector const& args, fileSetArgs[i].GetComponent()); } } + if (installsCxxModuleBmi) { + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( + cxxModuleBmiArgs.GetComponent()); + } return true; } @@ -2279,6 +2325,15 @@ std::string Helper::GetLibraryDestination( return this->GetDestination(args, "CMAKE_INSTALL_LIBDIR", "lib"); } +std::string Helper::GetCxxModulesBmiDestination( + const cmInstallCommandArguments* args) const +{ + if (args) { + return args->GetDestination(); + } + return {}; +} + std::string Helper::GetIncludeDestination( const cmInstallCommandArguments* args) const { diff --git a/Source/cmInstallCxxModuleBmiGenerator.cxx b/Source/cmInstallCxxModuleBmiGenerator.cxx new file mode 100644 index 0000000..1ef1eaa --- /dev/null +++ b/Source/cmInstallCxxModuleBmiGenerator.cxx @@ -0,0 +1,75 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmInstallCxxModuleBmiGenerator.h" + +#include +#include + +#include "cmGeneratorExpression.h" +#include "cmGeneratorTarget.h" +#include "cmGlobalGenerator.h" +#include "cmListFileCache.h" +#include "cmLocalGenerator.h" +#include "cmOutputConverter.h" +#include "cmStringAlgorithms.h" + +cmInstallCxxModuleBmiGenerator::cmInstallCxxModuleBmiGenerator( + std::string target, std::string const& dest, std::string file_permissions, + std::vector const& configurations, std::string const& component, + MessageLevel message, bool exclude_from_all, bool optional, + cmListFileBacktrace backtrace) + : cmInstallGenerator(dest, configurations, component, message, + exclude_from_all, false, std::move(backtrace)) + , TargetName(std::move(target)) + , FilePermissions(std::move(file_permissions)) + , Optional(optional) +{ + this->ActionsPerConfig = true; +} + +cmInstallCxxModuleBmiGenerator::~cmInstallCxxModuleBmiGenerator() = default; + +bool cmInstallCxxModuleBmiGenerator::Compute(cmLocalGenerator* lg) +{ + this->LocalGenerator = lg; + + this->Target = lg->FindLocalNonAliasGeneratorTarget(this->TargetName); + if (!this->Target) { + // If no local target has been found, find it in the global scope. + this->Target = + lg->GetGlobalGenerator()->FindGeneratorTarget(this->TargetName); + } + + return true; +} + +std::string cmInstallCxxModuleBmiGenerator::GetScriptLocation( + std::string const& config) const +{ + char const* config_name = config.c_str(); + if (config.empty()) { + config_name = "noconfig"; + } + return cmStrCat(this->Target->GetSupportDirectory(), + "/install-cxx-module-bmi-", config_name, ".cmake"); +} + +std::string cmInstallCxxModuleBmiGenerator::GetDestination( + std::string const& config) const +{ + return cmGeneratorExpression::Evaluate(this->Destination, + this->LocalGenerator, config); +} + +void cmInstallCxxModuleBmiGenerator::GenerateScriptForConfig( + std::ostream& os, const std::string& config, Indent indent) +{ + auto const& loc = this->GetScriptLocation(config); + if (loc.empty()) { + return; + } + os << indent << "include(\"" + << cmOutputConverter::EscapeForCMake( + loc, cmOutputConverter::WrapQuotes::NoWrap) + << "\" OPTIONAL)\n"; +} diff --git a/Source/cmInstallCxxModuleBmiGenerator.h b/Source/cmInstallCxxModuleBmiGenerator.h new file mode 100644 index 0000000..21edb2e --- /dev/null +++ b/Source/cmInstallCxxModuleBmiGenerator.h @@ -0,0 +1,52 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include "cmConfigure.h" // IWYU pragma: keep + +#include +#include +#include + +#include "cmInstallGenerator.h" +#include "cmScriptGenerator.h" + +class cmGeneratorTarget; +class cmListFileBacktrace; +class cmLocalGenerator; + +/** \class cmInstallCxxModuleBmiGenerator + * \brief Generate C++ module BMI installation rules. + */ +class cmInstallCxxModuleBmiGenerator : public cmInstallGenerator +{ +public: + cmInstallCxxModuleBmiGenerator( + std::string target, std::string const& dest, std::string file_permissions, + std::vector const& configurations, + std::string const& component, MessageLevel message, bool exclude_from_all, + bool optional, cmListFileBacktrace backtrace); + ~cmInstallCxxModuleBmiGenerator() override; + + bool Compute(cmLocalGenerator* lg) override; + + std::string const& GetFilePermissions() const + { + return this->FilePermissions; + } + std::string GetDestination(std::string const& config) const; + std::string GetScriptLocation(std::string const& config) const; + cmGeneratorTarget const* GetTarget() const { return this->Target; } + bool GetOptional() const { return this->Optional; } + MessageLevel GetMessageLevel() const { return this->Message; } + +protected: + void GenerateScriptForConfig(std::ostream& os, const std::string& config, + Indent indent) override; + + std::string const TargetName; + cmGeneratorTarget const* Target = nullptr; + cmLocalGenerator* LocalGenerator = nullptr; + std::string const FilePermissions; + bool const Optional; +}; diff --git a/Source/cmTargetExport.h b/Source/cmTargetExport.h index 885ac74..1cef888 100644 --- a/Source/cmTargetExport.h +++ b/Source/cmTargetExport.h @@ -8,6 +8,7 @@ class cmFileSet; class cmGeneratorTarget; +class cmInstallCxxModuleBmiGenerator; class cmInstallFileSetGenerator; class cmInstallFilesGenerator; class cmInstallTargetGenerator; @@ -32,6 +33,7 @@ public: cmInstallTargetGenerator* BundleGenerator; cmInstallFilesGenerator* HeaderGenerator; std::map FileSetGenerators; + cmInstallCxxModuleBmiGenerator* CxxModuleBmiGenerator; ///@} bool NamelinkOnly = false; diff --git a/Tests/RunCMake/CXXModules/InstallBMI-check.cmake b/Tests/RunCMake/CXXModules/InstallBMI-check.cmake new file mode 100644 index 0000000..f891c80 --- /dev/null +++ b/Tests/RunCMake/CXXModules/InstallBMI-check.cmake @@ -0,0 +1,24 @@ +file(READ "${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake" install_script) + +if (NOT install_script MATCHES [[\(CMAKE_INSTALL_COMPONENT STREQUAL "bmi" OR NOT CMAKE_INSTALL_COMPONENT\)]]) + list(APPEND RunCMake_TEST_FAILED + "Could not find BMI install script component for `bmi`") +endif () + +if (NOT install_script MATCHES [[include\("[^)]*/CMakeFiles/install-bmi\.dir/install-cxx-module-bmi-[^.]*\.cmake" OPTIONAL\)]]) + list(APPEND RunCMake_TEST_FAILED + "Could not find BMI install script inclusion") +endif () + +if (NOT install_script MATCHES [[\(CMAKE_INSTALL_COMPONENT STREQUAL "bmi-optional"\)]]) + list(APPEND RunCMake_TEST_FAILED + "Could not find BMI install script component for `bmi-optional`") +endif () + +if (NOT install_script MATCHES [[\(CMAKE_INSTALL_COMPONENT STREQUAL "bmi-only-debug" OR NOT CMAKE_INSTALL_COMPONENT\) + if\(CMAKE_INSTALL_CONFIG_NAME MATCHES "\^\(\[Dd\]\[Ee\]\[Bb\]\[Uu\]\[Gg\]\)\$"\)]]) + list(APPEND RunCMake_TEST_FAILED + "Could not find BMI install script component for `bmi-only-debug`") +endif () + +string(REPLACE ";" "; " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}") diff --git a/Tests/RunCMake/CXXModules/InstallBMI-stderr.txt b/Tests/RunCMake/CXXModules/InstallBMI-stderr.txt new file mode 100644 index 0000000..fc3c7db --- /dev/null +++ b/Tests/RunCMake/CXXModules/InstallBMI-stderr.txt @@ -0,0 +1,6 @@ +CMake Warning \(dev\) at InstallBMI.cmake:8 \(install\): + CMake's C\+\+ module support is experimental. It is meant only for + experimentation and feedback to CMake developers. +Call Stack \(most recent call first\): + CMakeLists.txt:6 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CXXModules/InstallBMI.cmake b/Tests/RunCMake/CXXModules/InstallBMI.cmake new file mode 100644 index 0000000..f0947b4 --- /dev/null +++ b/Tests/RunCMake/CXXModules/InstallBMI.cmake @@ -0,0 +1,23 @@ +enable_language(CXX) + +add_library(install-bmi) +target_sources(install-bmi + PRIVATE + sources/cxx-anchor.cxx) + +install(TARGETS install-bmi + CXX_MODULES_BMI + DESTINATION "lib/bmi" + COMPONENT "bmi") + +install(TARGETS install-bmi + CXX_MODULES_BMI + DESTINATION "lib/bmi" + EXCLUDE_FROM_ALL + COMPONENT "bmi-optional") + +install(TARGETS install-bmi + CXX_MODULES_BMI + DESTINATION "lib/bmi" + CONFIGURATIONS Debug + COMPONENT "bmi-only-debug") diff --git a/Tests/RunCMake/CXXModules/InstallBMIGenericArgs-check.cmake b/Tests/RunCMake/CXXModules/InstallBMIGenericArgs-check.cmake new file mode 100644 index 0000000..32a37ad --- /dev/null +++ b/Tests/RunCMake/CXXModules/InstallBMIGenericArgs-check.cmake @@ -0,0 +1,8 @@ +file(READ "${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake" install_script) + +if (NOT install_script MATCHES [[include\("[^)]*/CMakeFiles/install-bmi-generic-args\.dir/install-cxx-module-bmi-[^.]*\.cmake" OPTIONAL\)]]) + list(APPEND RunCMake_TEST_FAILED + "Could not find BMI install script inclusion") +endif () + +string(REPLACE ";" "; " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}") diff --git a/Tests/RunCMake/CXXModules/InstallBMIGenericArgs-stderr.txt b/Tests/RunCMake/CXXModules/InstallBMIGenericArgs-stderr.txt new file mode 100644 index 0000000..44c961f --- /dev/null +++ b/Tests/RunCMake/CXXModules/InstallBMIGenericArgs-stderr.txt @@ -0,0 +1,6 @@ +CMake Warning \(dev\) at InstallBMIGenericArgs.cmake:8 \(install\): + CMake's C\+\+ module support is experimental. It is meant only for + experimentation and feedback to CMake developers. +Call Stack \(most recent call first\): + CMakeLists.txt:6 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CXXModules/InstallBMIGenericArgs.cmake b/Tests/RunCMake/CXXModules/InstallBMIGenericArgs.cmake new file mode 100644 index 0000000..8f17143 --- /dev/null +++ b/Tests/RunCMake/CXXModules/InstallBMIGenericArgs.cmake @@ -0,0 +1,9 @@ +enable_language(CXX) + +add_library(install-bmi-generic-args) +target_sources(install-bmi-generic-args + PRIVATE + sources/cxx-anchor.cxx) + +install(TARGETS install-bmi-generic-args + DESTINATION "bin") diff --git a/Tests/RunCMake/CXXModules/InstallBMIIgnore-check.cmake b/Tests/RunCMake/CXXModules/InstallBMIIgnore-check.cmake new file mode 100644 index 0000000..7d13ef0 --- /dev/null +++ b/Tests/RunCMake/CXXModules/InstallBMIIgnore-check.cmake @@ -0,0 +1,13 @@ +file(READ "${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake" install_script) + +if (install_script MATCHES [[\(CMAKE_INSTALL_COMPONENT STREQUAL "bmi" OR NOT CMAKE_INSTALL_COMPONENT\)]]) + list(APPEND RunCMake_TEST_FAILED + "Found BMI install script component for `bmi`") +endif () + +if (install_script MATCHES [[include\("[^)]*/CMakeFiles/install-bmi-ignore\.dir/install-cxx-module-bmi-[^.]*\.cmake" OPTIONAL\)]]) + list(APPEND RunCMake_TEST_FAILED + "Found BMI install script inclusion") +endif () + +string(REPLACE ";" "; " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}") diff --git a/Tests/RunCMake/CXXModules/InstallBMIIgnore-stderr.txt b/Tests/RunCMake/CXXModules/InstallBMIIgnore-stderr.txt new file mode 100644 index 0000000..d9d2c2d --- /dev/null +++ b/Tests/RunCMake/CXXModules/InstallBMIIgnore-stderr.txt @@ -0,0 +1,6 @@ +CMake Warning \(dev\) at InstallBMIIgnore.cmake:5 \(install\): + CMake's C\+\+ module support is experimental. It is meant only for + experimentation and feedback to CMake developers. +Call Stack \(most recent call first\): + CMakeLists.txt:6 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CXXModules/InstallBMIIgnore.cmake b/Tests/RunCMake/CXXModules/InstallBMIIgnore.cmake new file mode 100644 index 0000000..f339511 --- /dev/null +++ b/Tests/RunCMake/CXXModules/InstallBMIIgnore.cmake @@ -0,0 +1,9 @@ +enable_language(CXX) + +add_library(install-bmi-ignore INTERFACE) + +install(TARGETS install-bmi-ignore + CXX_MODULES_BMI + # An empty destination ignores BMI installation. + DESTINATION "" + COMPONENT "bmi") diff --git a/Tests/RunCMake/CXXModules/InstallBMINoGenericArgs-check.cmake b/Tests/RunCMake/CXXModules/InstallBMINoGenericArgs-check.cmake new file mode 100644 index 0000000..412e260 --- /dev/null +++ b/Tests/RunCMake/CXXModules/InstallBMINoGenericArgs-check.cmake @@ -0,0 +1,8 @@ +file(READ "${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake" install_script) + +if (install_script MATCHES [[include\("[^)]*/CMakeFiles/install-bmi-generic-args\.dir/install-cxx-module-bmi-[^.]*\.cmake" OPTIONAL\)]]) + list(APPEND RunCMake_TEST_FAILED + "Found BMI install script inclusion") +endif () + +string(REPLACE ";" "; " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}") diff --git a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake index d459972..7c93100 100644 --- a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake +++ b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake @@ -67,6 +67,10 @@ foreach (fileset_type IN LISTS fileset_types) run_cmake("NotCXXSource${fileset_type}") endforeach () +run_cmake(InstallBMI) +run_cmake(InstallBMIGenericArgs) +run_cmake(InstallBMIIgnore) + # Actual compilation tests. if (NOT CMake_TEST_MODULE_COMPILATION) return () diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py index d5f596e..01a004c 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py +++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py @@ -213,6 +213,16 @@ def check_directory(c): assert is_int(at["index"]) assert c["targets"][at["index"]]["name"] == et["index"] + if e.get("cxxModuleBmiTarget", None) is not None: + expected_keys.append("cxxModuleBmiTarget") + et = e["cxxModuleBmiTarget"] + at = a["cxxModuleBmiTarget"] + assert is_dict(at) + assert sorted(at.keys()) == ["id", "index"] + assert matches(at["id"], et["id"]) + assert is_int(at["index"]) + assert c["targets"][at["index"]]["name"] == et["index"] + if e["backtrace"] is not None: expected_keys.append("backtrace") check_backtrace(d, a["backtrace"], e["backtrace"]) diff --git a/bootstrap b/bootstrap index f7e1544..01ff84f 100755 --- a/bootstrap +++ b/bootstrap @@ -393,6 +393,7 @@ CMAKE_CXX_SOURCES="\ cmIncludeRegularExpressionCommand \ cmInstallCommand \ cmInstallCommandArguments \ + cmInstallCxxModuleBmiGenerator \ cmInstallDirectoryGenerator \ cmInstallExportGenerator \ cmInstallFileSetGenerator \ -- cgit v0.12