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.
This commit is contained in:
Ben Boeckel
2022-04-18 12:26:49 -04:00
parent 29118091dc
commit fe44cbe9e7
7 changed files with 70 additions and 9 deletions

View File

@@ -25,7 +25,8 @@ Exporting Targets
.. code-block:: cmake
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
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
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
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 <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
import targets from the current project's build tree. This is the same

View File

@@ -790,9 +790,10 @@ Installing Exports
.. code-block:: cmake
install(EXPORT <export-name> DESTINATION <dir>
[NAMESPACE <namespace>] [[FILE <name>.cmake]|
[NAMESPACE <namespace>] [FILE <name>.cmake]
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...]]
[CONFIGURATIONS [Debug|Release|...]
[CXX_MODULES_DIRECTORY <directory>]
[EXPORT_LINK_INTERFACE_LIBRARIES]
[COMPONENT <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

View File

@@ -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<cmGeneratorTarget*> Exports;
cmLocalGenerator* LG;
// The directory for C++ module information.
std::string CxxModulesDirectory;
};

View File

@@ -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<std::string> 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<std::string> 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<std::string> 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);

View File

@@ -1995,7 +1995,7 @@ bool HandleExportAndroidMKMode(std::vector<std::string> const& args,
cm::make_unique<cmInstallExportGenerator>(
&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<std::string> 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<std::string> unknownArgs;
ica.Parse(args, &unknownArgs);
@@ -2109,8 +2116,8 @@ bool HandleExportMode(std::vector<std::string> const& args,
cm::make_unique<cmInstallExportGenerator>(
&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;
}

View File

@@ -23,7 +23,8 @@ cmInstallExportGenerator::cmInstallExportGenerator(
cmExportSet* exportSet, std::string const& destination,
std::string file_permissions, std::vector<std::string> 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) {

View File

@@ -28,7 +28,8 @@ public:
const std::vector<std::string>& 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;