Bläddra i källkod

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 `<FILE_NAME>-*.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.
Ben Boeckel 3 år sedan
förälder
incheckning
fe44cbe9e7

+ 14 - 2
Help/command/export.rst

@@ -25,7 +25,8 @@ Exporting Targets
 .. code-block:: cmake
 .. code-block:: cmake
 
 
   export(TARGETS <target>... [NAMESPACE <namespace>]
   export(TARGETS <target>... [NAMESPACE <namespace>]
-         [APPEND] FILE <filename> [EXPORT_LINK_INTERFACE_LIBRARIES])
+         [APPEND] FILE <filename> [EXPORT_LINK_INTERFACE_LIBRARIES]
+         [CXX_MODULES_DIRECTORY <directory>])
 
 
 Creates a file ``<filename>`` that may be included by outside projects to
 Creates a file ``<filename>`` that may be included by outside projects to
 import targets named by ``<target>...`` from the current project's build tree.
 import targets named by ``<target>...`` 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
   in the export, even when policy :policy:`CMP0022` is NEW.  This is useful
   to support consumers using CMake versions older than 2.8.12.
   to support consumers using CMake versions older than 2.8.12.
 
 
+``CXX_MODULES_DIRECTORY <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
 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
 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
 included, the behavior is unspecified.  See the `export(EXPORT)`_ signature
@@ -95,7 +106,8 @@ Exporting Targets matching install(EXPORT)
 
 
 .. code-block:: cmake
 .. code-block:: cmake
 
 
-  export(EXPORT <export-name> [NAMESPACE <namespace>] [FILE <filename>])
+  export(EXPORT <export-name> [NAMESPACE <namespace>] [FILE <filename>]
+         [CXX_MODULES_DIRECTORY <directory>])
 
 
 Creates a file ``<filename>`` that may be included by outside projects to
 Creates a file ``<filename>`` that may be included by outside projects to
 import targets from the current project's build tree.  This is the same
 import targets from the current project's build tree.  This is the same

+ 15 - 2
Help/command/install.rst

@@ -790,9 +790,10 @@ Installing Exports
 .. code-block:: cmake
 .. code-block:: cmake
 
 
   install(EXPORT <export-name> DESTINATION <dir>
   install(EXPORT <export-name> DESTINATION <dir>
-          [NAMESPACE <namespace>] [[FILE <name>.cmake]|
+          [NAMESPACE <namespace>] [FILE <name>.cmake]
           [PERMISSIONS permissions...]
           [PERMISSIONS permissions...]
-          [CONFIGURATIONS [Debug|Release|...]]
+          [CONFIGURATIONS [Debug|Release|...]
+          [CXX_MODULES_DIRECTORY <directory>]
           [EXPORT_LINK_INTERFACE_LIBRARIES]
           [EXPORT_LINK_INTERFACE_LIBRARIES]
           [COMPONENT <component>]
           [COMPONENT <component>]
           [EXCLUDE_FROM_ALL])
           [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
   to an ndk build system complete with transitive dependencies, include flags
   and defines required to use the libraries.
   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
 The ``EXPORT`` form is useful to help outside projects use targets built
 and installed by the current project.  For example, the code
 and installed by the current project.  For example, the code
 
 

+ 12 - 0
Source/cmExportBuildFileGenerator.h

@@ -47,6 +47,16 @@ public:
   }
   }
   void SetExportSet(cmExportSet*);
   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.  */
   /** Set whether to append generated code to the output file.  */
   void SetAppendMode(bool append) { this->AppendMode = append; }
   void SetAppendMode(bool append) { this->AppendMode = append; }
 
 
@@ -88,4 +98,6 @@ protected:
   cmExportSet* ExportSet;
   cmExportSet* ExportSet;
   std::vector<cmGeneratorTarget*> Exports;
   std::vector<cmGeneratorTarget*> Exports;
   cmLocalGenerator* LG;
   cmLocalGenerator* LG;
+  // The directory for C++ module information.
+  std::string CxxModulesDirectory;
 };
 };

+ 9 - 0
Source/cmExportCommand.cxx

@@ -14,6 +14,7 @@
 
 
 #include "cmArgumentParser.h"
 #include "cmArgumentParser.h"
 #include "cmExecutionStatus.h"
 #include "cmExecutionStatus.h"
+#include "cmExperimental.h"
 #include "cmExportBuildAndroidMKGenerator.h"
 #include "cmExportBuildAndroidMKGenerator.h"
 #include "cmExportBuildFileGenerator.h"
 #include "cmExportBuildFileGenerator.h"
 #include "cmExportSet.h"
 #include "cmExportSet.h"
@@ -61,6 +62,7 @@ bool cmExportCommand(std::vector<std::string> const& args,
     std::string Namespace;
     std::string Namespace;
     std::string Filename;
     std::string Filename;
     std::string AndroidMKFile;
     std::string AndroidMKFile;
+    std::string CxxModulesDirectory;
     bool Append = false;
     bool Append = false;
     bool ExportOld = false;
     bool ExportOld = false;
   };
   };
@@ -69,6 +71,12 @@ bool cmExportCommand(std::vector<std::string> const& args,
                   .Bind("NAMESPACE"_s, &Arguments::Namespace)
                   .Bind("NAMESPACE"_s, &Arguments::Namespace)
                   .Bind("FILE"_s, &Arguments::Filename);
                   .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") {
   if (args[0] == "EXPORT") {
     parser.Bind("EXPORT"_s, &Arguments::ExportSetName);
     parser.Bind("EXPORT"_s, &Arguments::ExportSetName);
   } else {
   } else {
@@ -211,6 +219,7 @@ bool cmExportCommand(std::vector<std::string> const& args,
   }
   }
   ebfg->SetExportFile(fname.c_str());
   ebfg->SetExportFile(fname.c_str());
   ebfg->SetNamespace(arguments.Namespace);
   ebfg->SetNamespace(arguments.Namespace);
+  ebfg->SetCxxModuleDirectory(arguments.CxxModulesDirectory);
   ebfg->SetAppendMode(arguments.Append);
   ebfg->SetAppendMode(arguments.Append);
   if (exportSet != nullptr) {
   if (exportSet != nullptr) {
     ebfg->SetExportSet(exportSet);
     ebfg->SetExportSet(exportSet);

+ 10 - 3
Source/cmInstallCommand.cxx

@@ -1995,7 +1995,7 @@ bool HandleExportAndroidMKMode(std::vector<std::string> const& args,
     cm::make_unique<cmInstallExportGenerator>(
     cm::make_unique<cmInstallExportGenerator>(
       &exportSet, ica.GetDestination(), ica.GetPermissions(),
       &exportSet, ica.GetDestination(), ica.GetPermissions(),
       ica.GetConfigurations(), ica.GetComponent(), message,
       ica.GetConfigurations(), ica.GetComponent(), message,
-      ica.GetExcludeFromAll(), fname, name_space, exportOld, true,
+      ica.GetExcludeFromAll(), fname, name_space, "", exportOld, true,
       helper.Makefile->GetBacktrace()));
       helper.Makefile->GetBacktrace()));
 
 
   return true;
   return true;
@@ -2018,12 +2018,19 @@ bool HandleExportMode(std::vector<std::string> const& args,
   std::string name_space;
   std::string name_space;
   bool exportOld = false;
   bool exportOld = false;
   std::string filename;
   std::string filename;
+  std::string cxx_modules_directory;
 
 
   ica.Bind("EXPORT"_s, exp);
   ica.Bind("EXPORT"_s, exp);
   ica.Bind("NAMESPACE"_s, name_space);
   ica.Bind("NAMESPACE"_s, name_space);
   ica.Bind("EXPORT_LINK_INTERFACE_LIBRARIES"_s, exportOld);
   ica.Bind("EXPORT_LINK_INTERFACE_LIBRARIES"_s, exportOld);
   ica.Bind("FILE"_s, filename);
   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<std::string> unknownArgs;
   std::vector<std::string> unknownArgs;
   ica.Parse(args, &unknownArgs);
   ica.Parse(args, &unknownArgs);
 
 
@@ -2109,8 +2116,8 @@ bool HandleExportMode(std::vector<std::string> const& args,
     cm::make_unique<cmInstallExportGenerator>(
     cm::make_unique<cmInstallExportGenerator>(
       &exportSet, ica.GetDestination(), ica.GetPermissions(),
       &exportSet, ica.GetDestination(), ica.GetPermissions(),
       ica.GetConfigurations(), ica.GetComponent(), message,
       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;
   return true;
 }
 }

+ 3 - 1
Source/cmInstallExportGenerator.cxx

@@ -23,7 +23,8 @@ cmInstallExportGenerator::cmInstallExportGenerator(
   cmExportSet* exportSet, std::string const& destination,
   cmExportSet* exportSet, std::string const& destination,
   std::string file_permissions, std::vector<std::string> const& configurations,
   std::string file_permissions, std::vector<std::string> const& configurations,
   std::string const& component, MessageLevel message, bool exclude_from_all,
   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)
   cmListFileBacktrace backtrace)
   : cmInstallGenerator(destination, configurations, component, message,
   : cmInstallGenerator(destination, configurations, component, message,
                        exclude_from_all, false, std::move(backtrace))
                        exclude_from_all, false, std::move(backtrace))
@@ -31,6 +32,7 @@ cmInstallExportGenerator::cmInstallExportGenerator(
   , FilePermissions(std::move(file_permissions))
   , FilePermissions(std::move(file_permissions))
   , FileName(std::move(filename))
   , FileName(std::move(filename))
   , Namespace(std::move(name_space))
   , Namespace(std::move(name_space))
+  , CxxModulesDirectory(std::move(cxx_modules_directory))
   , ExportOld(exportOld)
   , ExportOld(exportOld)
 {
 {
   if (android) {
   if (android) {

+ 7 - 1
Source/cmInstallExportGenerator.h

@@ -28,7 +28,8 @@ public:
                            const std::vector<std::string>& configurations,
                            const std::vector<std::string>& configurations,
                            std::string const& component, MessageLevel message,
                            std::string const& component, MessageLevel message,
                            bool exclude_from_all, std::string filename,
                            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);
                            bool android, cmListFileBacktrace backtrace);
   cmInstallExportGenerator(const cmInstallExportGenerator&) = delete;
   cmInstallExportGenerator(const cmInstallExportGenerator&) = delete;
   ~cmInstallExportGenerator() override;
   ~cmInstallExportGenerator() override;
@@ -50,6 +51,10 @@ public:
   std::string GetDestinationFile() const;
   std::string GetDestinationFile() const;
   std::string GetFileName() const { return this->FileName; }
   std::string GetFileName() const { return this->FileName; }
   std::string GetTempDir() const;
   std::string GetTempDir() const;
+  std::string GetCxxModuleDirectory() const
+  {
+    return this->CxxModulesDirectory;
+  }
 
 
 protected:
 protected:
   void GenerateScript(std::ostream& os) override;
   void GenerateScript(std::ostream& os) override;
@@ -64,6 +69,7 @@ protected:
   std::string const FilePermissions;
   std::string const FilePermissions;
   std::string const FileName;
   std::string const FileName;
   std::string const Namespace;
   std::string const Namespace;
+  std::string const CxxModulesDirectory;
   bool const ExportOld;
   bool const ExportOld;
   cmLocalGenerator* LocalGenerator = nullptr;
   cmLocalGenerator* LocalGenerator = nullptr;