mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-01 19:30:13 -06:00
install(EXPORT): Install file sets
This commit is contained in:
@@ -11,12 +11,15 @@
|
||||
#include <cmext/algorithm>
|
||||
|
||||
#include "cmExportSet.h"
|
||||
#include "cmFileSet.h"
|
||||
#include "cmGeneratorExpression.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
#include "cmListFileCache.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmMessageType.h"
|
||||
#include "cmOutputConverter.h"
|
||||
#include "cmPolicies.h"
|
||||
#include "cmStateTypes.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
@@ -135,6 +138,8 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
|
||||
this->PopulateCompatibleInterfaceProperties(gte, properties);
|
||||
|
||||
this->GenerateInterfaceProperties(gte, os, properties);
|
||||
|
||||
this->GenerateTargetFileSets(gte, os);
|
||||
}
|
||||
|
||||
// Generate import file content for each configuration.
|
||||
@@ -356,3 +361,17 @@ std::string cmExportBuildFileGenerator::InstallNameDir(
|
||||
|
||||
return install_name_dir;
|
||||
}
|
||||
|
||||
std::string cmExportBuildFileGenerator::GetFileSetDirectories(
|
||||
cmGeneratorTarget* /*gte*/, cmFileSet* fileSet, cmTargetExport* /*te*/)
|
||||
{
|
||||
return cmOutputConverter::EscapeForCMake(
|
||||
cmJoin(fileSet->GetDirectoryEntries(), ";"));
|
||||
}
|
||||
|
||||
std::string cmExportBuildFileGenerator::GetFileSetFiles(
|
||||
cmGeneratorTarget* /*gte*/, cmFileSet* fileSet, cmTargetExport* /*te*/)
|
||||
{
|
||||
return cmOutputConverter::EscapeForCMake(
|
||||
cmJoin(fileSet->GetFileEntries(), ";"));
|
||||
}
|
||||
|
||||
@@ -15,9 +15,11 @@
|
||||
#include "cmStateTypes.h"
|
||||
|
||||
class cmExportSet;
|
||||
class cmFileSet;
|
||||
class cmGeneratorTarget;
|
||||
class cmGlobalGenerator;
|
||||
class cmLocalGenerator;
|
||||
class cmTargetExport;
|
||||
|
||||
/** \class cmExportBuildFileGenerator
|
||||
* \brief Generate a file exporting targets from a build tree.
|
||||
@@ -76,6 +78,11 @@ protected:
|
||||
std::string InstallNameDir(cmGeneratorTarget const* target,
|
||||
const std::string& config) override;
|
||||
|
||||
std::string GetFileSetDirectories(cmGeneratorTarget* gte, cmFileSet* fileSet,
|
||||
cmTargetExport* te) override;
|
||||
std::string GetFileSetFiles(cmGeneratorTarget* gte, cmFileSet* fileSet,
|
||||
cmTargetExport* te) override;
|
||||
|
||||
std::pair<std::vector<std::string>, std::string> FindBuildExportInfo(
|
||||
cmGlobalGenerator* gg, const std::string& name);
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "cmsys/FStream.hxx"
|
||||
|
||||
#include "cmComputeLinkInformation.h"
|
||||
#include "cmFileSet.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
@@ -1256,3 +1257,39 @@ bool cmExportFileGenerator::PopulateExportProperties(
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void cmExportFileGenerator::GenerateTargetFileSets(cmGeneratorTarget* gte,
|
||||
std::ostream& os,
|
||||
cmTargetExport* te)
|
||||
{
|
||||
auto interfaceFileSets = gte->Target->GetAllInterfaceFileSets();
|
||||
if (!interfaceFileSets.empty()) {
|
||||
std::string targetName = cmStrCat(this->Namespace, gte->GetExportName());
|
||||
os << "if(NOT CMAKE_VERSION VERSION_LESS \"" << DEVEL_CMAKE_VERSION(3, 23)
|
||||
<< "\")\n"
|
||||
" target_sources("
|
||||
<< targetName << "\n";
|
||||
|
||||
for (auto const& name : interfaceFileSets) {
|
||||
auto* fileSet = gte->Target->GetFileSet(name);
|
||||
if (!fileSet) {
|
||||
gte->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("File set \"", name,
|
||||
"\" is listed in interface file sets of ", gte->GetName(),
|
||||
" but has not been created"));
|
||||
return;
|
||||
}
|
||||
|
||||
os << " INTERFACE"
|
||||
<< "\n FILE_SET " << cmOutputConverter::EscapeForCMake(name)
|
||||
<< "\n TYPE "
|
||||
<< cmOutputConverter::EscapeForCMake(fileSet->GetType())
|
||||
<< "\n BASE_DIRS "
|
||||
<< this->GetFileSetDirectories(gte, fileSet, te) << "\n FILES "
|
||||
<< this->GetFileSetFiles(gte, fileSet, te) << "\n";
|
||||
}
|
||||
|
||||
os << " )\nendif()\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
#include "cmVersion.h"
|
||||
#include "cmVersionConfig.h"
|
||||
|
||||
class cmFileSet;
|
||||
class cmGeneratorTarget;
|
||||
class cmTargetExport;
|
||||
|
||||
#define STRINGIFY_HELPER(X) #X
|
||||
#define STRINGIFY(X) STRINGIFY_HELPER(X)
|
||||
@@ -184,6 +186,16 @@ protected:
|
||||
ImportPropertyMap& properties,
|
||||
std::string& errorMessage);
|
||||
|
||||
void GenerateTargetFileSets(cmGeneratorTarget* gte, std::ostream& os,
|
||||
cmTargetExport* te = nullptr);
|
||||
|
||||
virtual std::string GetFileSetDirectories(cmGeneratorTarget* gte,
|
||||
cmFileSet* fileSet,
|
||||
cmTargetExport* te) = 0;
|
||||
virtual std::string GetFileSetFiles(cmGeneratorTarget* gte,
|
||||
cmFileSet* fileSet,
|
||||
cmTargetExport* te) = 0;
|
||||
|
||||
// The namespace in which the exports are placed in the generated file.
|
||||
std::string Namespace;
|
||||
|
||||
|
||||
@@ -2,19 +2,23 @@
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmExportInstallFileGenerator.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
#include "cmExportSet.h"
|
||||
#include "cmFileSet.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmGeneratorExpression.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
#include "cmInstallExportGenerator.h"
|
||||
#include "cmInstallFileSetGenerator.h"
|
||||
#include "cmInstallTargetGenerator.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmOutputConverter.h"
|
||||
#include "cmPolicies.h"
|
||||
#include "cmStateTypes.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
@@ -147,6 +151,8 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
||||
this->PopulateCompatibleInterfaceProperties(gt, properties);
|
||||
|
||||
this->GenerateInterfaceProperties(gt, os, properties);
|
||||
|
||||
this->GenerateTargetFileSets(gt, os, te);
|
||||
}
|
||||
|
||||
if (require3_1_0) {
|
||||
@@ -534,3 +540,102 @@ std::string cmExportInstallFileGenerator::InstallNameDir(
|
||||
|
||||
return install_name_dir;
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool EntryIsContextSensitive(
|
||||
const std::unique_ptr<cmCompiledGeneratorExpression>& cge)
|
||||
{
|
||||
return cge->GetHadContextSensitiveCondition();
|
||||
}
|
||||
}
|
||||
|
||||
std::string cmExportInstallFileGenerator::GetFileSetDirectories(
|
||||
cmGeneratorTarget* gte, cmFileSet* fileSet, cmTargetExport* te)
|
||||
{
|
||||
std::vector<std::string> resultVector;
|
||||
|
||||
auto configs =
|
||||
gte->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
|
||||
|
||||
cmGeneratorExpression ge;
|
||||
auto cge = ge.Parse(te->FileSetGenerators.at(fileSet)->GetDestination());
|
||||
|
||||
for (auto const& config : configs) {
|
||||
auto dest = cmStrCat("${_IMPORT_PREFIX}/",
|
||||
cmOutputConverter::EscapeForCMake(
|
||||
cge->Evaluate(gte->LocalGenerator, config, gte),
|
||||
cmOutputConverter::WrapQuotes::NoWrap));
|
||||
|
||||
if (cge->GetHadContextSensitiveCondition() && configs.size() != 1) {
|
||||
resultVector.push_back(
|
||||
cmStrCat("\"$<$<CONFIG:", config, ">:", dest, ">\""));
|
||||
} else {
|
||||
resultVector.push_back(cmStrCat('"', dest, '"'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return cmJoin(resultVector, " ");
|
||||
}
|
||||
|
||||
std::string cmExportInstallFileGenerator::GetFileSetFiles(
|
||||
cmGeneratorTarget* gte, cmFileSet* fileSet, cmTargetExport* te)
|
||||
{
|
||||
std::vector<std::string> resultVector;
|
||||
|
||||
auto configs =
|
||||
gte->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
|
||||
|
||||
auto fileEntries = fileSet->CompileFileEntries();
|
||||
auto directoryEntries = fileSet->CompileDirectoryEntries();
|
||||
|
||||
cmGeneratorExpression destGe;
|
||||
auto destCge =
|
||||
destGe.Parse(te->FileSetGenerators.at(fileSet)->GetDestination());
|
||||
|
||||
for (auto const& config : configs) {
|
||||
auto directories = fileSet->EvaluateDirectoryEntries(
|
||||
directoryEntries, gte->LocalGenerator, config, gte);
|
||||
|
||||
std::map<std::string, std::vector<std::string>> files;
|
||||
for (auto const& entry : fileEntries) {
|
||||
fileSet->EvaluateFileEntry(directories, files, entry,
|
||||
gte->LocalGenerator, config, gte);
|
||||
}
|
||||
auto dest = cmStrCat("${_IMPORT_PREFIX}/",
|
||||
cmOutputConverter::EscapeForCMake(
|
||||
destCge->Evaluate(gte->LocalGenerator, config, gte),
|
||||
cmOutputConverter::WrapQuotes::NoWrap),
|
||||
'/');
|
||||
|
||||
bool const contextSensitive = destCge->GetHadContextSensitiveCondition() ||
|
||||
std::any_of(directoryEntries.begin(), directoryEntries.end(),
|
||||
EntryIsContextSensitive) ||
|
||||
std::any_of(fileEntries.begin(), fileEntries.end(),
|
||||
EntryIsContextSensitive);
|
||||
|
||||
for (auto const& it : files) {
|
||||
auto prefix = it.first.empty() ? "" : cmStrCat(it.first, '/');
|
||||
for (auto const& filename : it.second) {
|
||||
auto relFile =
|
||||
cmStrCat(prefix, cmSystemTools::GetFilenameName(filename));
|
||||
auto escapedFile =
|
||||
cmStrCat(dest,
|
||||
cmOutputConverter::EscapeForCMake(
|
||||
relFile, cmOutputConverter::WrapQuotes::NoWrap));
|
||||
if (contextSensitive && configs.size() != 1) {
|
||||
resultVector.push_back(
|
||||
cmStrCat("\"$<$<CONFIG:", config, ">:", escapedFile, ">\""));
|
||||
} else {
|
||||
resultVector.push_back(cmStrCat('"', escapedFile, '"'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(contextSensitive && configs.size() != 1)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return cmJoin(resultVector, " ");
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "cmExportFileGenerator.h"
|
||||
#include "cmStateTypes.h"
|
||||
|
||||
class cmFileSet;
|
||||
class cmGeneratorTarget;
|
||||
class cmGlobalGenerator;
|
||||
class cmInstallExportGenerator;
|
||||
@@ -97,6 +98,11 @@ protected:
|
||||
std::string InstallNameDir(cmGeneratorTarget const* target,
|
||||
const std::string& config) override;
|
||||
|
||||
std::string GetFileSetDirectories(cmGeneratorTarget* gte, cmFileSet* fileSet,
|
||||
cmTargetExport* te) override;
|
||||
std::string GetFileSetFiles(cmGeneratorTarget* gte, cmFileSet* fileSet,
|
||||
cmTargetExport* te) override;
|
||||
|
||||
cmInstallExportGenerator* IEGen;
|
||||
|
||||
// The import file generated for each configuration.
|
||||
|
||||
@@ -7,17 +7,22 @@
|
||||
|
||||
#include <cm/memory>
|
||||
|
||||
#include "cmFileSet.h"
|
||||
#include "cmGeneratorExpression.h"
|
||||
#include "cmGeneratorExpressionDAGChecker.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
#include "cmListFileCache.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmOutputConverter.h"
|
||||
#include "cmStateTypes.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmTarget.h"
|
||||
#include "cmValue.h"
|
||||
|
||||
class cmTargetExport;
|
||||
|
||||
cmExportTryCompileFileGenerator::cmExportTryCompileFileGenerator(
|
||||
cmGlobalGenerator* gg, const std::vector<std::string>& targets,
|
||||
cmMakefile* mf, std::set<std::string> const& langs)
|
||||
@@ -137,3 +142,17 @@ std::string cmExportTryCompileFileGenerator::InstallNameDir(
|
||||
|
||||
return install_name_dir;
|
||||
}
|
||||
|
||||
std::string cmExportTryCompileFileGenerator::GetFileSetDirectories(
|
||||
cmGeneratorTarget* /*gte*/, cmFileSet* fileSet, cmTargetExport* /*te*/)
|
||||
{
|
||||
return cmOutputConverter::EscapeForCMake(
|
||||
cmJoin(fileSet->GetDirectoryEntries(), ";"));
|
||||
}
|
||||
|
||||
std::string cmExportTryCompileFileGenerator::GetFileSetFiles(
|
||||
cmGeneratorTarget* /*gte*/, cmFileSet* fileSet, cmTargetExport* /*te*/)
|
||||
{
|
||||
return cmOutputConverter::EscapeForCMake(
|
||||
cmJoin(fileSet->GetFileEntries(), ";"));
|
||||
}
|
||||
|
||||
@@ -11,9 +11,11 @@
|
||||
|
||||
#include "cmExportFileGenerator.h"
|
||||
|
||||
class cmFileSet;
|
||||
class cmGeneratorTarget;
|
||||
class cmGlobalGenerator;
|
||||
class cmMakefile;
|
||||
class cmTargetExport;
|
||||
|
||||
class cmExportTryCompileFileGenerator : public cmExportFileGenerator
|
||||
{
|
||||
@@ -48,6 +50,13 @@ protected:
|
||||
std::string InstallNameDir(cmGeneratorTarget const* target,
|
||||
const std::string& config) override;
|
||||
|
||||
std::string GetFileSetDirectories(cmGeneratorTarget* target,
|
||||
cmFileSet* fileSet,
|
||||
cmTargetExport* te) override;
|
||||
|
||||
std::string GetFileSetFiles(cmGeneratorTarget* target, cmFileSet* fileSet,
|
||||
cmTargetExport* te) override;
|
||||
|
||||
private:
|
||||
std::string FindTargets(const std::string& prop,
|
||||
const cmGeneratorTarget* tgt,
|
||||
|
||||
@@ -729,9 +729,24 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
||||
// Track whether this is a namelink-only rule.
|
||||
bool namelinkOnly = false;
|
||||
|
||||
auto addTargetExport = [&]() {
|
||||
auto addTargetExport = [&]() -> bool {
|
||||
// Add this install rule to an export if one was specified.
|
||||
if (!exports.empty()) {
|
||||
auto interfaceFileSets = target.GetAllInterfaceFileSets();
|
||||
if (std::any_of(
|
||||
interfaceFileSets.begin(), interfaceFileSets.end(),
|
||||
[=](const std::string& name) -> bool {
|
||||
return !std::any_of(
|
||||
fileSetArgs.begin(), fileSetArgs.end(),
|
||||
[=](const cmInstallCommandFileSetArguments& fileSetArg)
|
||||
-> bool { return fileSetArg.GetFileSet() == name; });
|
||||
})) {
|
||||
status.SetError(cmStrCat(
|
||||
"TARGETS target ", target.GetName(),
|
||||
" is exported but not all of its file sets are installed"));
|
||||
return false;
|
||||
}
|
||||
|
||||
auto te = cm::make_unique<cmTargetExport>();
|
||||
te->TargetName = target.GetName();
|
||||
te->ArchiveGenerator = archiveGenerator.get();
|
||||
@@ -741,6 +756,9 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
||||
te->LibraryGenerator = libraryGenerator.get();
|
||||
te->RuntimeGenerator = runtimeGenerator.get();
|
||||
te->ObjectsGenerator = objectGenerator.get();
|
||||
for (auto const& gen : fileSetGenerators) {
|
||||
te->FileSetGenerators[gen->GetFileSet()] = gen.get();
|
||||
}
|
||||
target.AddInstallIncludeDirectories(
|
||||
cmMakeRange(includesArgs.GetIncludeDirs()));
|
||||
te->NamelinkOnly = namelinkOnly;
|
||||
@@ -748,6 +766,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
||||
->GetExportSets()[exports]
|
||||
.AddTargetExport(std::move(te));
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
switch (target.GetType()) {
|
||||
@@ -759,7 +778,9 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
||||
// When in namelink only mode skip all libraries on Windows.
|
||||
if (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly) {
|
||||
namelinkOnly = true;
|
||||
addTargetExport();
|
||||
if (!addTargetExport()) {
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -795,7 +816,9 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
||||
// When in namelink only mode skip frameworks.
|
||||
if (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly) {
|
||||
namelinkOnly = true;
|
||||
addTargetExport();
|
||||
if (!addTargetExport()) {
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -844,7 +867,9 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
||||
// When in namelink only mode skip frameworks.
|
||||
if (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly) {
|
||||
namelinkOnly = true;
|
||||
addTargetExport();
|
||||
if (!addTargetExport()) {
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1080,7 +1105,9 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
||||
}
|
||||
|
||||
// Add this install rule to an export if one was specified.
|
||||
addTargetExport();
|
||||
if (!addTargetExport()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Keep track of whether we're installing anything in each category
|
||||
installsArchive = installsArchive || archiveGenerator;
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
class cmFileSet;
|
||||
class cmGeneratorTarget;
|
||||
class cmInstallFileSetGenerator;
|
||||
class cmInstallFilesGenerator;
|
||||
class cmInstallTargetGenerator;
|
||||
|
||||
@@ -29,6 +31,7 @@ public:
|
||||
cmInstallTargetGenerator* FrameworkGenerator;
|
||||
cmInstallTargetGenerator* BundleGenerator;
|
||||
cmInstallFilesGenerator* HeaderGenerator;
|
||||
std::map<cmFileSet*, cmInstallFileSetGenerator*> FileSetGenerators;
|
||||
///@}
|
||||
|
||||
bool NamelinkOnly = false;
|
||||
|
||||
Reference in New Issue
Block a user