diff options
author | Brad King <brad.king@kitware.com> | 2018-02-28 15:58:07 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2018-02-28 15:58:10 (GMT) |
commit | ea0ce73a195e1cc0f672f1e7519c42a240592f15 (patch) | |
tree | 568319f21bf3e9ed2583832c0b2e69eb2d29d5b3 /Source | |
parent | d870148537319da2e86237cbd8baf6815975e594 (diff) | |
download | CMake-ea0ce73a195e1cc0f672f1e7519c42a240592f15.zip CMake-ea0ce73a195e1cc0f672f1e7519c42a240592f15.tar.gz CMake-ea0ce73a195e1cc0f672f1e7519c42a240592f15.tar.bz2 |
install,export: Maybe transform OBJECT libraries to INTERFACE libraries
Teach the `install` and `export` commands to support installing and
exporting `OBJECT` libraries without their object files. Transform
them to `INTERFACE` libraries in such cases.
For `install(TARGETS)`, activate this when no destination for the object
files is specified. For `export`, activate this only under Xcode with
multiple architectures when we have no well-defined object file
locations to give to clients.
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmExportBuildAndroidMKGenerator.cxx | 3 | ||||
-rw-r--r-- | Source/cmExportBuildAndroidMKGenerator.h | 6 | ||||
-rw-r--r-- | Source/cmExportBuildFileGenerator.cxx | 22 | ||||
-rw-r--r-- | Source/cmExportBuildFileGenerator.h | 3 | ||||
-rw-r--r-- | Source/cmExportCommand.cxx | 11 | ||||
-rw-r--r-- | Source/cmExportFileGenerator.cxx | 6 | ||||
-rw-r--r-- | Source/cmExportFileGenerator.h | 4 | ||||
-rw-r--r-- | Source/cmExportInstallAndroidMKGenerator.cxx | 3 | ||||
-rw-r--r-- | Source/cmExportInstallAndroidMKGenerator.h | 6 | ||||
-rw-r--r-- | Source/cmExportInstallFileGenerator.cxx | 22 | ||||
-rw-r--r-- | Source/cmExportInstallFileGenerator.h | 4 | ||||
-rw-r--r-- | Source/cmExportTryCompileFileGenerator.cxx | 2 | ||||
-rw-r--r-- | Source/cmInstallCommand.cxx | 31 |
13 files changed, 77 insertions, 46 deletions
diff --git a/Source/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx index 6f31a2d..61eea88 100644 --- a/Source/cmExportBuildAndroidMKGenerator.cxx +++ b/Source/cmExportBuildAndroidMKGenerator.cxx @@ -40,7 +40,8 @@ void cmExportBuildAndroidMKGenerator::GenerateExpectedTargetsCode( } void cmExportBuildAndroidMKGenerator::GenerateImportTargetCode( - std::ostream& os, const cmGeneratorTarget* target) + std::ostream& os, cmGeneratorTarget const* target, + cmStateEnums::TargetType /*targetType*/) { std::string targetName = this->Namespace; targetName += target->GetExportName(); diff --git a/Source/cmExportBuildAndroidMKGenerator.h b/Source/cmExportBuildAndroidMKGenerator.h index c80839b..a9b6107 100644 --- a/Source/cmExportBuildAndroidMKGenerator.h +++ b/Source/cmExportBuildAndroidMKGenerator.h @@ -11,6 +11,7 @@ #include "cmExportBuildFileGenerator.h" #include "cmExportFileGenerator.h" +#include "cmStateTypes.h" class cmGeneratorTarget; @@ -47,8 +48,9 @@ protected: void GenerateImportHeaderCode(std::ostream& os, const std::string& config = "") override; void GenerateImportFooterCode(std::ostream& os) override; - void GenerateImportTargetCode(std::ostream& os, - const cmGeneratorTarget* target) override; + void GenerateImportTargetCode( + std::ostream& os, cmGeneratorTarget const* target, + cmStateEnums::TargetType /*targetType*/) override; void GenerateExpectedTargetsCode( std::ostream& os, const std::string& expectedTargets) override; void GenerateImportPropertyCode( diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index f7aa6e8..a276d01 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -59,7 +59,7 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) this->LG->GetMakefile()->GetBacktrace()); return false; } - if (te->GetType() == cmStateEnums::INTERFACE_LIBRARY) { + if (this->GetExportTargetType(te) == cmStateEnums::INTERFACE_LIBRARY) { this->GenerateRequiredCMakeVersion(os, "3.0.0"); } } @@ -71,7 +71,7 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) // Create all the imported targets. for (cmGeneratorTarget* gte : this->Exports) { - this->GenerateImportTargetCode(os, gte); + this->GenerateImportTargetCode(os, gte, this->GetExportTargetType(gte)); gte->Target->AppendBuildInterfaceIncludes(); @@ -128,12 +128,13 @@ void cmExportBuildFileGenerator::GenerateImportTargetsConfig( // Collect import properties for this target. ImportPropertyMap properties; - if (target->GetType() != cmStateEnums::INTERFACE_LIBRARY) { + if (this->GetExportTargetType(target) != cmStateEnums::INTERFACE_LIBRARY) { this->SetImportLocationProperty(config, suffix, target, properties); } if (!properties.empty()) { // Get the rest of the target details. - if (target->GetType() != cmStateEnums::INTERFACE_LIBRARY) { + if (this->GetExportTargetType(target) != + cmStateEnums::INTERFACE_LIBRARY) { this->SetImportDetailProperties(config, suffix, target, properties, missingTargets); this->SetImportLinkInterface(config, suffix, @@ -153,6 +154,19 @@ void cmExportBuildFileGenerator::GenerateImportTargetsConfig( } } +cmStateEnums::TargetType cmExportBuildFileGenerator::GetExportTargetType( + cmGeneratorTarget const* target) const +{ + cmStateEnums::TargetType targetType = target->GetType(); + // An object library exports as an interface library if we cannot + // tell clients where to find the objects. + if (targetType == cmStateEnums::OBJECT_LIBRARY && + !this->LG->GetGlobalGenerator()->HasKnownObjectFileLocation(nullptr)) { + targetType = cmStateEnums::INTERFACE_LIBRARY; + } + return targetType; +} + void cmExportBuildFileGenerator::SetExportSet(cmExportSet* exportSet) { this->ExportSet = exportSet; diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h index 6457a77..ada2709 100644 --- a/Source/cmExportBuildFileGenerator.h +++ b/Source/cmExportBuildFileGenerator.h @@ -6,6 +6,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmExportFileGenerator.h" +#include "cmStateTypes.h" #include <iosfwd> #include <string> @@ -53,6 +54,8 @@ protected: void GenerateImportTargetsConfig( std::ostream& os, const std::string& config, std::string const& suffix, std::vector<std::string>& missingTargets) override; + cmStateEnums::TargetType GetExportTargetType( + cmGeneratorTarget const* target) const; void HandleMissingTarget(std::string& link_libs, std::vector<std::string>& missingTargets, cmGeneratorTarget* depender, diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx index c8a727d..655ebe8 100644 --- a/Source/cmExportCommand.cxx +++ b/Source/cmExportCommand.cxx @@ -146,17 +146,6 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args, } if (cmTarget* target = gg->FindTarget(currentTarget)) { - if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) { - std::string reason; - if (!this->Makefile->GetGlobalGenerator() - ->HasKnownObjectFileLocation(&reason)) { - std::ostringstream e; - e << "given OBJECT library \"" << currentTarget - << "\" which may not be exported" << reason << "."; - this->SetError(e.str()); - return false; - } - } if (target->GetType() == cmStateEnums::UTILITY) { this->SetError("given custom target \"" + currentTarget + "\" which may not be exported."); diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 434abdc..0f1d745 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -901,8 +901,10 @@ void cmExportFileGenerator::GenerateExpectedTargetsCode( "\n\n"; /* clang-format on */ } + void cmExportFileGenerator::GenerateImportTargetCode( - std::ostream& os, const cmGeneratorTarget* target) + std::ostream& os, cmGeneratorTarget const* target, + cmStateEnums::TargetType targetType) { // Construct the imported target name. std::string targetName = this->Namespace; @@ -911,7 +913,7 @@ void cmExportFileGenerator::GenerateImportTargetCode( // Create the imported target. os << "# Create imported target " << targetName << "\n"; - switch (target->GetType()) { + switch (targetType) { case cmStateEnums::EXECUTABLE: os << "add_executable(" << targetName << " IMPORTED)\n"; break; diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index 985c8f6..e541372 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -6,6 +6,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmGeneratorExpression.h" +#include "cmStateTypes.h" #include "cmVersion.h" #include "cmVersionConfig.h" @@ -76,7 +77,8 @@ protected: virtual void GenerateImportFooterCode(std::ostream& os); void GenerateImportVersionCode(std::ostream& os); virtual void GenerateImportTargetCode(std::ostream& os, - cmGeneratorTarget const* target); + cmGeneratorTarget const* target, + cmStateEnums::TargetType targetType); virtual void GenerateImportPropertyCode(std::ostream& os, const std::string& config, cmGeneratorTarget const* target, diff --git a/Source/cmExportInstallAndroidMKGenerator.cxx b/Source/cmExportInstallAndroidMKGenerator.cxx index fe565e6..9bc8089 100644 --- a/Source/cmExportInstallAndroidMKGenerator.cxx +++ b/Source/cmExportInstallAndroidMKGenerator.cxx @@ -55,7 +55,8 @@ void cmExportInstallAndroidMKGenerator::GenerateImportFooterCode(std::ostream&) } void cmExportInstallAndroidMKGenerator::GenerateImportTargetCode( - std::ostream& os, const cmGeneratorTarget* target) + std::ostream& os, cmGeneratorTarget const* target, + cmStateEnums::TargetType /*targetType*/) { std::string targetName = this->Namespace; targetName += target->GetExportName(); diff --git a/Source/cmExportInstallAndroidMKGenerator.h b/Source/cmExportInstallAndroidMKGenerator.h index 91554ee..8883ffa 100644 --- a/Source/cmExportInstallAndroidMKGenerator.h +++ b/Source/cmExportInstallAndroidMKGenerator.h @@ -12,6 +12,7 @@ #include "cmExportFileGenerator.h" #include "cmExportInstallFileGenerator.h" +#include "cmStateTypes.h" class cmGeneratorTarget; class cmInstallExportGenerator; @@ -41,8 +42,9 @@ protected: void GenerateImportHeaderCode(std::ostream& os, const std::string& config = "") override; void GenerateImportFooterCode(std::ostream& os) override; - void GenerateImportTargetCode(std::ostream& os, - const cmGeneratorTarget* target) override; + void GenerateImportTargetCode( + std::ostream& os, cmGeneratorTarget const* target, + cmStateEnums::TargetType /*targetType*/) override; void GenerateExpectedTargetsCode( std::ostream& os, const std::string& expectedTargets) override; void GenerateImportPropertyCode( diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 954b561..93ba2ce 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -75,11 +75,12 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) // Create all the imported targets. for (cmTargetExport* te : allTargets) { cmGeneratorTarget* gt = te->Target; + cmStateEnums::TargetType targetType = this->GetExportTargetType(te); requiresConfigFiles = - requiresConfigFiles || gt->GetType() != cmStateEnums::INTERFACE_LIBRARY; + requiresConfigFiles || targetType != cmStateEnums::INTERFACE_LIBRARY; - this->GenerateImportTargetCode(os, gt); + this->GenerateImportTargetCode(os, gt, targetType); ImportPropertyMap properties; @@ -114,7 +115,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) require2_8_12 = true; } } - if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY) { + if (targetType == cmStateEnums::INTERFACE_LIBRARY) { require3_0_0 = true; } if (gt->GetProperty("INTERFACE_SOURCES")) { @@ -308,7 +309,7 @@ void cmExportInstallFileGenerator::GenerateImportTargetsConfig( // Add each target in the set to the export. for (cmTargetExport* te : *this->IEGen->GetExportSet()->GetTargetExports()) { // Collect import properties for this target. - if (te->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) { + if (this->GetExportTargetType(te) == cmStateEnums::INTERFACE_LIBRARY) { continue; } @@ -426,6 +427,19 @@ void cmExportInstallFileGenerator::SetImportLocationProperty( } } +cmStateEnums::TargetType cmExportInstallFileGenerator::GetExportTargetType( + cmTargetExport const* targetExport) const +{ + cmStateEnums::TargetType targetType = targetExport->Target->GetType(); + // An OBJECT library installed with no OBJECTS DESTINATION + // is transformed to an INTERFACE library. + if (targetType == cmStateEnums::OBJECT_LIBRARY && + targetExport->ObjectsGenerator == nullptr) { + targetType = cmStateEnums::INTERFACE_LIBRARY; + } + return targetType; +} + void cmExportInstallFileGenerator::HandleMissingTarget( std::string& link_libs, std::vector<std::string>& missingTargets, cmGeneratorTarget* depender, cmGeneratorTarget* dependee) diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h index cda8433..ea607fb 100644 --- a/Source/cmExportInstallFileGenerator.h +++ b/Source/cmExportInstallFileGenerator.h @@ -6,6 +6,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmExportFileGenerator.h" +#include "cmStateTypes.h" #include <iosfwd> #include <map> @@ -17,6 +18,7 @@ class cmGeneratorTarget; class cmGlobalGenerator; class cmInstallExportGenerator; class cmInstallTargetGenerator; +class cmTargetExport; /** \class cmExportInstallFileGenerator * \brief Generate a file exporting targets from an install tree. @@ -57,6 +59,8 @@ protected: void GenerateImportTargetsConfig( std::ostream& os, const std::string& config, std::string const& suffix, std::vector<std::string>& missingTargets) override; + cmStateEnums::TargetType GetExportTargetType( + cmTargetExport const* targetExport) const; void HandleMissingTarget(std::string& link_libs, std::vector<std::string>& missingTargets, cmGeneratorTarget* depender, diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx index 1fb9cf8..798f2e6 100644 --- a/Source/cmExportTryCompileFileGenerator.cxx +++ b/Source/cmExportTryCompileFileGenerator.cxx @@ -32,7 +32,7 @@ bool cmExportTryCompileFileGenerator::GenerateMainFile(std::ostream& os) this->Exports.pop_back(); if (emitted.insert(te).second) { emittedDeps.insert(te); - this->GenerateImportTargetCode(os, te); + this->GenerateImportTargetCode(os, te, te->GetType()); ImportPropertyMap properties; diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index 394f976..008a5e0 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -360,17 +360,6 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) this->SetError(e.str()); return false; } - if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) { - std::string reason; - if (!this->Makefile->GetGlobalGenerator()->HasKnownObjectFileLocation( - &reason)) { - std::ostringstream e; - e << "TARGETS given OBJECT library \"" << tgt - << "\" which may not be installed" << reason << "."; - this->SetError(e.str()); - return false; - } - } // Store the target in the list to be installed. targets.push_back(target); } else { @@ -534,15 +523,23 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) case cmStateEnums::OBJECT_LIBRARY: { // Objects use OBJECT properties. if (!objectArgs.GetDestination().empty()) { + // Verify that we know where the objects are to install them. + std::string reason; + if (!this->Makefile->GetGlobalGenerator() + ->HasKnownObjectFileLocation(&reason)) { + std::ostringstream e; + e << "TARGETS given OBJECT library \"" << target.GetName() + << "\" whose objects may not be installed" << reason << "."; + this->SetError(e.str()); + return false; + } + objectGenerator = CreateInstallTargetGenerator(target, objectArgs, false); } else { - std::ostringstream e; - e << "TARGETS given no OBJECTS DESTINATION for object library " - "target \"" - << target.GetName() << "\"."; - this->SetError(e.str()); - return false; + // Installing an OBJECT library without a destination transforms + // it to an INTERFACE library. It installs no files but can be + // exported. } } break; case cmStateEnums::EXECUTABLE: { |