From fe44cbe9e7849b3c555fbb29c83a54414c0e8629 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Mon, 18 Apr 2022 12:26:49 -0400 Subject: exports: support `CXX_MODULES_DIRECTORY` This directory will be used to store build-discovered information about targets such as the modules provided by the files in the relevant `FILE_SET` types. A directory is used because basing the name on a `-*.cmake` pattern makes it end up being globbed in the configuration-dependent information mechanism. Since old modules and targets may be around, unconditionally including them may refer to targets that do not actually exist. --- Help/command/export.rst | 16 ++++++++++++++-- Help/command/install.rst | 17 +++++++++++++++-- Source/cmExportBuildFileGenerator.h | 12 ++++++++++++ Source/cmExportCommand.cxx | 9 +++++++++ Source/cmInstallCommand.cxx | 13 ++++++++++--- Source/cmInstallExportGenerator.cxx | 4 +++- Source/cmInstallExportGenerator.h | 8 +++++++- 7 files changed, 70 insertions(+), 9 deletions(-) diff --git a/Help/command/export.rst b/Help/command/export.rst index dc69645..6785b05 100644 --- a/Help/command/export.rst +++ b/Help/command/export.rst @@ -25,7 +25,8 @@ Exporting Targets .. code-block:: cmake export(TARGETS ... [NAMESPACE ] - [APPEND] FILE [EXPORT_LINK_INTERFACE_LIBRARIES]) + [APPEND] FILE [EXPORT_LINK_INTERFACE_LIBRARIES] + [CXX_MODULES_DIRECTORY ]) Creates a file ```` that may be included by outside projects to import targets named by ``...`` from the current project's build tree. @@ -52,6 +53,16 @@ The options are: in the export, even when policy :policy:`CMP0022` is NEW. This is useful to support consumers using CMake versions older than 2.8.12. +``CXX_MODULES_DIRECTORY `` + +.. note :: + + Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API`` + + Export C++ module properties to files under the given directory. Each file + will be named according to the target's export name (without any namespace). + These files will automatically be included from the export file. + This signature requires all targets to be listed explicitly. If a library target is included in the export, but a target to which it links is not included, the behavior is unspecified. See the `export(EXPORT)`_ signature @@ -95,7 +106,8 @@ Exporting Targets matching install(EXPORT) .. code-block:: cmake - export(EXPORT [NAMESPACE ] [FILE ]) + export(EXPORT [NAMESPACE ] [FILE ] + [CXX_MODULES_DIRECTORY ]) Creates a file ```` that may be included by outside projects to import targets from the current project's build tree. This is the same diff --git a/Help/command/install.rst b/Help/command/install.rst index d64fe5e..beb2157 100644 --- a/Help/command/install.rst +++ b/Help/command/install.rst @@ -790,9 +790,10 @@ Installing Exports .. code-block:: cmake install(EXPORT DESTINATION - [NAMESPACE ] [[FILE .cmake]| + [NAMESPACE ] [FILE .cmake] [PERMISSIONS permissions...] - [CONFIGURATIONS [Debug|Release|...]] + [CONFIGURATIONS [Debug|Release|...] + [CXX_MODULES_DIRECTORY ] [EXPORT_LINK_INTERFACE_LIBRARIES] [COMPONENT ] [EXCLUDE_FROM_ALL]) @@ -848,6 +849,18 @@ library is always installed if the headers and CMake export file are present. to an ndk build system complete with transitive dependencies, include flags and defines required to use the libraries. +``CXX_MODULES_DIRECTORY`` + +.. note :: + + Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API`` + + Specify a subdirectory to store C++ module information for targets in the + export set. This directory will be populated with files which add the + necessary target property information to the relevant targets. Note that + without this information, none of the C++ modules which are part of the + targets in the export set will support being imported in consuming targets. + The ``EXPORT`` form is useful to help outside projects use targets built and installed by the current project. For example, the code diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h index 5681e8f..5f72046 100644 --- a/Source/cmExportBuildFileGenerator.h +++ b/Source/cmExportBuildFileGenerator.h @@ -47,6 +47,16 @@ public: } void SetExportSet(cmExportSet*); + /** Set the name of the C++ module directory. */ + void SetCxxModuleDirectory(std::string cxx_module_dir) + { + this->CxxModulesDirectory = std::move(cxx_module_dir); + } + const std::string& GetCxxModuleDirectory() const + { + return this->CxxModulesDirectory; + } + /** Set whether to append generated code to the output file. */ void SetAppendMode(bool append) { this->AppendMode = append; } @@ -88,4 +98,6 @@ protected: cmExportSet* ExportSet; std::vector Exports; cmLocalGenerator* LG; + // The directory for C++ module information. + std::string CxxModulesDirectory; }; diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx index 198874e..4071f99 100644 --- a/Source/cmExportCommand.cxx +++ b/Source/cmExportCommand.cxx @@ -14,6 +14,7 @@ #include "cmArgumentParser.h" #include "cmExecutionStatus.h" +#include "cmExperimental.h" #include "cmExportBuildAndroidMKGenerator.h" #include "cmExportBuildFileGenerator.h" #include "cmExportSet.h" @@ -61,6 +62,7 @@ bool cmExportCommand(std::vector const& args, std::string Namespace; std::string Filename; std::string AndroidMKFile; + std::string CxxModulesDirectory; bool Append = false; bool ExportOld = false; }; @@ -69,6 +71,12 @@ bool cmExportCommand(std::vector const& args, .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); + } + if (args[0] == "EXPORT") { parser.Bind("EXPORT"_s, &Arguments::ExportSetName); } else { @@ -211,6 +219,7 @@ bool cmExportCommand(std::vector const& args, } ebfg->SetExportFile(fname.c_str()); ebfg->SetNamespace(arguments.Namespace); + ebfg->SetCxxModuleDirectory(arguments.CxxModulesDirectory); ebfg->SetAppendMode(arguments.Append); if (exportSet != nullptr) { ebfg->SetExportSet(exportSet); diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index 4d77303..35ddf34 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -1995,7 +1995,7 @@ bool HandleExportAndroidMKMode(std::vector const& args, cm::make_unique( &exportSet, ica.GetDestination(), ica.GetPermissions(), ica.GetConfigurations(), ica.GetComponent(), message, - ica.GetExcludeFromAll(), fname, name_space, exportOld, true, + ica.GetExcludeFromAll(), fname, name_space, "", exportOld, true, helper.Makefile->GetBacktrace())); return true; @@ -2018,12 +2018,19 @@ bool HandleExportMode(std::vector const& args, std::string name_space; bool exportOld = false; std::string filename; + std::string cxx_modules_directory; ica.Bind("EXPORT"_s, exp); 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); + } + std::vector unknownArgs; ica.Parse(args, &unknownArgs); @@ -2109,8 +2116,8 @@ bool HandleExportMode(std::vector const& args, cm::make_unique( &exportSet, ica.GetDestination(), ica.GetPermissions(), ica.GetConfigurations(), ica.GetComponent(), message, - ica.GetExcludeFromAll(), fname, name_space, exportOld, false, - helper.Makefile->GetBacktrace())); + ica.GetExcludeFromAll(), fname, name_space, cxx_modules_directory, + exportOld, false, helper.Makefile->GetBacktrace())); return true; } diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index b80437d..433e0c5 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -23,7 +23,8 @@ cmInstallExportGenerator::cmInstallExportGenerator( cmExportSet* exportSet, std::string const& destination, std::string file_permissions, std::vector const& configurations, std::string const& component, MessageLevel message, bool exclude_from_all, - std::string filename, std::string name_space, bool exportOld, bool android, + std::string filename, std::string name_space, + std::string cxx_modules_directory, bool exportOld, bool android, cmListFileBacktrace backtrace) : cmInstallGenerator(destination, configurations, component, message, exclude_from_all, false, std::move(backtrace)) @@ -31,6 +32,7 @@ cmInstallExportGenerator::cmInstallExportGenerator( , FilePermissions(std::move(file_permissions)) , FileName(std::move(filename)) , Namespace(std::move(name_space)) + , CxxModulesDirectory(std::move(cxx_modules_directory)) , ExportOld(exportOld) { if (android) { diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h index 02fe1fa..346ca67 100644 --- a/Source/cmInstallExportGenerator.h +++ b/Source/cmInstallExportGenerator.h @@ -28,7 +28,8 @@ public: const std::vector& configurations, std::string const& component, MessageLevel message, bool exclude_from_all, std::string filename, - std::string name_space, bool exportOld, + std::string name_space, + std::string cxx_modules_directory, bool exportOld, bool android, cmListFileBacktrace backtrace); cmInstallExportGenerator(const cmInstallExportGenerator&) = delete; ~cmInstallExportGenerator() override; @@ -50,6 +51,10 @@ public: std::string GetDestinationFile() const; std::string GetFileName() const { return this->FileName; } std::string GetTempDir() const; + std::string GetCxxModuleDirectory() const + { + return this->CxxModulesDirectory; + } protected: void GenerateScript(std::ostream& os) override; @@ -64,6 +69,7 @@ protected: std::string const FilePermissions; std::string const FileName; std::string const Namespace; + std::string const CxxModulesDirectory; bool const ExportOld; cmLocalGenerator* LocalGenerator = nullptr; -- cgit v0.12