2016-09-27 19:01:08 +00:00
|
|
|
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
|
|
|
file Copyright.txt or https://cmake.org/licensing for details. */
|
2008-01-28 13:38:36 +00:00
|
|
|
#include "cmExportInstallFileGenerator.h"
|
|
|
|
|
2019-09-30 14:46:28 +00:00
|
|
|
#include <memory>
|
|
|
|
#include <sstream>
|
|
|
|
#include <utility>
|
|
|
|
|
2012-09-28 19:47:37 +00:00
|
|
|
#include "cmExportSet.h"
|
2008-01-28 13:38:36 +00:00
|
|
|
#include "cmGeneratedFileStream.h"
|
2016-09-01 18:59:28 +00:00
|
|
|
#include "cmGeneratorExpression.h"
|
|
|
|
#include "cmGeneratorTarget.h"
|
2012-09-28 19:47:37 +00:00
|
|
|
#include "cmGlobalGenerator.h"
|
2008-01-28 13:38:36 +00:00
|
|
|
#include "cmInstallExportGenerator.h"
|
|
|
|
#include "cmInstallTargetGenerator.h"
|
2016-04-29 14:53:13 +00:00
|
|
|
#include "cmLocalGenerator.h"
|
2016-09-01 18:59:28 +00:00
|
|
|
#include "cmMakefile.h"
|
|
|
|
#include "cmPolicies.h"
|
2016-10-18 19:28:48 +00:00
|
|
|
#include "cmStateTypes.h"
|
2019-07-29 10:16:40 +00:00
|
|
|
#include "cmStringAlgorithms.h"
|
2016-09-01 18:59:28 +00:00
|
|
|
#include "cmSystemTools.h"
|
|
|
|
#include "cmTarget.h"
|
2012-02-26 20:05:17 +00:00
|
|
|
#include "cmTargetExport.h"
|
2008-01-28 13:38:36 +00:00
|
|
|
|
2016-05-16 14:34:04 +00:00
|
|
|
cmExportInstallFileGenerator::cmExportInstallFileGenerator(
|
|
|
|
cmInstallExportGenerator* iegen)
|
|
|
|
: IEGen(iegen)
|
2008-01-28 13:38:36 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2009-01-07 19:16:28 +00:00
|
|
|
std::string cmExportInstallFileGenerator::GetConfigImportFileGlob()
|
|
|
|
{
|
2019-08-22 14:34:40 +00:00
|
|
|
std::string glob = cmStrCat(this->FileBase, "-*", this->FileExt);
|
2009-01-07 19:16:28 +00:00
|
|
|
return glob;
|
|
|
|
}
|
|
|
|
|
2008-01-28 13:38:36 +00:00
|
|
|
bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
|
|
|
{
|
2013-01-05 11:13:49 +00:00
|
|
|
std::vector<cmTargetExport*> allTargets;
|
2012-11-30 08:26:09 +00:00
|
|
|
{
|
2016-05-16 14:34:04 +00:00
|
|
|
std::string expectedTargets;
|
|
|
|
std::string sep;
|
2019-09-08 09:14:55 +00:00
|
|
|
for (std::unique_ptr<cmTargetExport> const& te :
|
|
|
|
this->IEGen->GetExportSet()->GetTargetExports()) {
|
2017-09-11 10:40:26 +00:00
|
|
|
expectedTargets += sep + this->Namespace + te->Target->GetExportName();
|
2016-05-16 14:34:04 +00:00
|
|
|
sep = " ";
|
|
|
|
if (this->ExportedTargets.insert(te->Target).second) {
|
2019-09-08 09:14:55 +00:00
|
|
|
allTargets.push_back(te.get());
|
2016-05-16 14:34:04 +00:00
|
|
|
} else {
|
|
|
|
std::ostringstream e;
|
|
|
|
e << "install(EXPORT \"" << this->IEGen->GetExportSet()->GetName()
|
|
|
|
<< "\" ...) "
|
|
|
|
<< "includes target \"" << te->Target->GetName()
|
|
|
|
<< "\" more than once in the export set.";
|
2019-01-23 15:12:17 +00:00
|
|
|
cmSystemTools::Error(e.str());
|
2016-05-16 14:34:04 +00:00
|
|
|
return false;
|
2008-02-06 19:20:36 +00:00
|
|
|
}
|
2008-01-28 13:38:36 +00:00
|
|
|
}
|
|
|
|
|
2016-05-16 14:34:04 +00:00
|
|
|
this->GenerateExpectedTargetsCode(os, expectedTargets);
|
2012-12-30 21:06:12 +00:00
|
|
|
}
|
|
|
|
|
2016-07-12 17:26:55 +00:00
|
|
|
// Compute the relative import prefix for the file
|
|
|
|
this->GenerateImportPrefix(os);
|
2013-01-27 08:42:54 +00:00
|
|
|
|
2012-09-23 11:45:17 +00:00
|
|
|
std::vector<std::string> missingTargets;
|
|
|
|
|
2013-06-04 14:47:57 +00:00
|
|
|
bool require2_8_12 = false;
|
2013-12-10 17:59:21 +00:00
|
|
|
bool require3_0_0 = false;
|
2014-11-28 17:58:38 +00:00
|
|
|
bool require3_1_0 = false;
|
2013-12-26 07:19:33 +00:00
|
|
|
bool requiresConfigFiles = false;
|
2012-12-30 21:06:12 +00:00
|
|
|
// Create all the imported targets.
|
2017-09-11 10:40:26 +00:00
|
|
|
for (cmTargetExport* te : allTargets) {
|
|
|
|
cmGeneratorTarget* gt = te->Target;
|
2018-02-28 15:58:07 +00:00
|
|
|
cmStateEnums::TargetType targetType = this->GetExportTargetType(te);
|
2013-12-26 07:19:33 +00:00
|
|
|
|
2016-05-16 14:34:04 +00:00
|
|
|
requiresConfigFiles =
|
2018-02-28 15:58:07 +00:00
|
|
|
requiresConfigFiles || targetType != cmStateEnums::INTERFACE_LIBRARY;
|
2013-12-26 07:19:33 +00:00
|
|
|
|
2018-02-28 15:58:07 +00:00
|
|
|
this->GenerateImportTargetCode(os, gt, targetType);
|
2012-09-23 11:45:17 +00:00
|
|
|
|
|
|
|
ImportPropertyMap properties;
|
|
|
|
|
2016-05-16 14:34:04 +00:00
|
|
|
this->PopulateIncludeDirectoriesInterface(
|
2017-09-11 10:40:26 +00:00
|
|
|
te, cmGeneratorExpression::InstallInterface, properties, missingTargets);
|
|
|
|
this->PopulateSourcesInterface(te, cmGeneratorExpression::InstallInterface,
|
2016-05-16 14:34:04 +00:00
|
|
|
properties, missingTargets);
|
|
|
|
this->PopulateInterfaceProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", gt,
|
|
|
|
cmGeneratorExpression::InstallInterface,
|
|
|
|
properties, missingTargets);
|
|
|
|
this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", gt,
|
|
|
|
cmGeneratorExpression::InstallInterface,
|
|
|
|
properties, missingTargets);
|
|
|
|
this->PopulateInterfaceProperty("INTERFACE_COMPILE_OPTIONS", gt,
|
|
|
|
cmGeneratorExpression::InstallInterface,
|
|
|
|
properties, missingTargets);
|
2019-09-23 17:51:07 +00:00
|
|
|
this->PopulateInterfaceProperty("INTERFACE_PRECOMPILE_HEADERS", gt,
|
|
|
|
cmGeneratorExpression::InstallInterface,
|
|
|
|
properties, missingTargets);
|
2016-05-16 14:34:04 +00:00
|
|
|
this->PopulateInterfaceProperty("INTERFACE_AUTOUIC_OPTIONS", gt,
|
|
|
|
cmGeneratorExpression::InstallInterface,
|
|
|
|
properties, missingTargets);
|
|
|
|
this->PopulateInterfaceProperty("INTERFACE_COMPILE_FEATURES", gt,
|
|
|
|
cmGeneratorExpression::InstallInterface,
|
|
|
|
properties, missingTargets);
|
2018-04-24 15:01:01 +00:00
|
|
|
this->PopulateInterfaceProperty("INTERFACE_LINK_OPTIONS", gt,
|
|
|
|
cmGeneratorExpression::InstallInterface,
|
|
|
|
properties, missingTargets);
|
2018-09-14 15:48:20 +00:00
|
|
|
this->PopulateLinkDirectoriesInterface(
|
|
|
|
te, cmGeneratorExpression::InstallInterface, properties, missingTargets);
|
2018-06-26 14:21:05 +00:00
|
|
|
this->PopulateLinkDependsInterface(
|
|
|
|
te, cmGeneratorExpression::InstallInterface, properties, missingTargets);
|
2013-06-04 14:47:57 +00:00
|
|
|
|
2018-03-08 17:46:49 +00:00
|
|
|
std::string errorMessage;
|
|
|
|
if (!this->PopulateExportProperties(gt, properties, errorMessage)) {
|
2019-01-23 15:12:17 +00:00
|
|
|
cmSystemTools::Error(errorMessage);
|
2018-03-08 17:46:49 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-06-04 14:47:57 +00:00
|
|
|
const bool newCMP0022Behavior =
|
2016-05-16 14:34:04 +00:00
|
|
|
gt->GetPolicyStatusCMP0022() != cmPolicies::WARN &&
|
|
|
|
gt->GetPolicyStatusCMP0022() != cmPolicies::OLD;
|
|
|
|
if (newCMP0022Behavior) {
|
|
|
|
if (this->PopulateInterfaceLinkLibrariesProperty(
|
|
|
|
gt, cmGeneratorExpression::InstallInterface, properties,
|
|
|
|
missingTargets) &&
|
|
|
|
!this->ExportOld) {
|
2013-06-04 14:47:57 +00:00
|
|
|
require2_8_12 = true;
|
|
|
|
}
|
2016-05-16 14:34:04 +00:00
|
|
|
}
|
2018-02-28 15:58:07 +00:00
|
|
|
if (targetType == cmStateEnums::INTERFACE_LIBRARY) {
|
2013-12-10 17:59:21 +00:00
|
|
|
require3_0_0 = true;
|
2016-05-16 14:34:04 +00:00
|
|
|
}
|
|
|
|
if (gt->GetProperty("INTERFACE_SOURCES")) {
|
2014-11-28 17:58:38 +00:00
|
|
|
// We can only generate INTERFACE_SOURCES in CMake 3.3, but CMake 3.1
|
|
|
|
// can consume them.
|
|
|
|
require3_1_0 = true;
|
2016-05-16 14:34:04 +00:00
|
|
|
}
|
2014-11-28 17:58:38 +00:00
|
|
|
|
2016-05-16 14:34:04 +00:00
|
|
|
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", gt,
|
|
|
|
properties);
|
2015-08-04 17:19:42 +00:00
|
|
|
|
2015-10-17 11:31:33 +00:00
|
|
|
this->PopulateCompatibleInterfaceProperties(gt, properties);
|
2012-09-23 11:45:17 +00:00
|
|
|
|
2015-10-17 12:33:51 +00:00
|
|
|
this->GenerateInterfaceProperties(gt, os, properties);
|
2016-05-16 14:34:04 +00:00
|
|
|
}
|
2012-12-30 21:06:12 +00:00
|
|
|
|
2016-05-16 14:34:04 +00:00
|
|
|
if (require3_1_0) {
|
2014-11-28 17:58:38 +00:00
|
|
|
this->GenerateRequiredCMakeVersion(os, "3.1.0");
|
2016-05-16 14:34:04 +00:00
|
|
|
} else if (require3_0_0) {
|
2014-02-19 14:15:33 +00:00
|
|
|
this->GenerateRequiredCMakeVersion(os, "3.0.0");
|
2016-05-16 14:34:04 +00:00
|
|
|
} else if (require2_8_12) {
|
2013-08-15 14:53:16 +00:00
|
|
|
this->GenerateRequiredCMakeVersion(os, "2.8.12");
|
2016-05-16 14:34:04 +00:00
|
|
|
}
|
2012-09-23 11:45:17 +00:00
|
|
|
|
2016-07-12 17:26:55 +00:00
|
|
|
this->LoadConfigFiles(os);
|
2008-01-28 13:38:36 +00:00
|
|
|
|
2016-07-12 17:26:55 +00:00
|
|
|
this->CleanupTemporaryVariables(os);
|
2013-01-13 08:48:45 +00:00
|
|
|
this->GenerateImportedFileCheckLoop(os);
|
|
|
|
|
2008-01-28 13:38:36 +00:00
|
|
|
bool result = true;
|
2013-12-26 07:19:33 +00:00
|
|
|
// Generate an import file for each configuration.
|
|
|
|
// Don't do this if we only export INTERFACE_LIBRARY targets.
|
2016-05-16 14:34:04 +00:00
|
|
|
if (requiresConfigFiles) {
|
2017-09-11 10:40:26 +00:00
|
|
|
for (std::string const& c : this->Configurations) {
|
|
|
|
if (!this->GenerateImportFileConfig(c, missingTargets)) {
|
2013-12-26 07:19:33 +00:00
|
|
|
result = false;
|
2008-01-28 13:38:36 +00:00
|
|
|
}
|
|
|
|
}
|
2016-05-16 14:34:04 +00:00
|
|
|
}
|
2013-01-13 08:44:52 +00:00
|
|
|
|
|
|
|
this->GenerateMissingTargetsCheckCode(os, missingTargets);
|
|
|
|
|
2008-01-28 13:38:36 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2016-07-12 17:26:55 +00:00
|
|
|
void cmExportInstallFileGenerator::GenerateImportPrefix(std::ostream& os)
|
|
|
|
{
|
|
|
|
// Set an _IMPORT_PREFIX variable for import location properties
|
|
|
|
// to reference if they are relative to the install prefix.
|
|
|
|
std::string installPrefix =
|
|
|
|
this->IEGen->GetLocalGenerator()->GetMakefile()->GetSafeDefinition(
|
|
|
|
"CMAKE_INSTALL_PREFIX");
|
|
|
|
std::string const& expDest = this->IEGen->GetDestination();
|
|
|
|
if (cmSystemTools::FileIsFullPath(expDest)) {
|
|
|
|
// The export file is being installed to an absolute path so the
|
|
|
|
// package is not relocatable. Use the configured install prefix.
|
|
|
|
/* clang-format off */
|
|
|
|
os <<
|
|
|
|
"# The installation prefix configured by this project.\n"
|
|
|
|
"set(_IMPORT_PREFIX \"" << installPrefix << "\")\n"
|
|
|
|
"\n";
|
|
|
|
/* clang-format on */
|
|
|
|
} else {
|
|
|
|
// Add code to compute the installation prefix relative to the
|
|
|
|
// import file location.
|
|
|
|
std::string absDest = installPrefix + "/" + expDest;
|
|
|
|
std::string absDestS = absDest + "/";
|
|
|
|
os << "# Compute the installation prefix relative to this file.\n"
|
|
|
|
<< "get_filename_component(_IMPORT_PREFIX"
|
|
|
|
<< " \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
|
2018-01-31 15:20:02 +00:00
|
|
|
if (cmHasLiteralPrefix(absDestS, "/lib/") ||
|
|
|
|
cmHasLiteralPrefix(absDestS, "/lib64/") ||
|
|
|
|
cmHasLiteralPrefix(absDestS, "/libx32/") ||
|
|
|
|
cmHasLiteralPrefix(absDestS, "/usr/lib/") ||
|
|
|
|
cmHasLiteralPrefix(absDestS, "/usr/lib64/") ||
|
|
|
|
cmHasLiteralPrefix(absDestS, "/usr/libx32/")) {
|
2016-07-12 17:26:55 +00:00
|
|
|
// Handle "/usr move" symlinks created by some Linux distros.
|
|
|
|
/* clang-format off */
|
|
|
|
os <<
|
|
|
|
"# Use original install prefix when loaded through a\n"
|
|
|
|
"# cross-prefix symbolic link such as /lib -> /usr/lib.\n"
|
|
|
|
"get_filename_component(_realCurr \"${_IMPORT_PREFIX}\" REALPATH)\n"
|
|
|
|
"get_filename_component(_realOrig \"" << absDest << "\" REALPATH)\n"
|
|
|
|
"if(_realCurr STREQUAL _realOrig)\n"
|
|
|
|
" set(_IMPORT_PREFIX \"" << absDest << "\")\n"
|
|
|
|
"endif()\n"
|
|
|
|
"unset(_realOrig)\n"
|
|
|
|
"unset(_realCurr)\n";
|
|
|
|
/* clang-format on */
|
|
|
|
}
|
|
|
|
std::string dest = expDest;
|
|
|
|
while (!dest.empty()) {
|
|
|
|
os << "get_filename_component(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" "
|
|
|
|
"PATH)\n";
|
|
|
|
dest = cmSystemTools::GetFilenamePath(dest);
|
|
|
|
}
|
|
|
|
os << "if(_IMPORT_PREFIX STREQUAL \"/\")\n"
|
|
|
|
<< " set(_IMPORT_PREFIX \"\")\n"
|
|
|
|
<< "endif()\n"
|
|
|
|
<< "\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void cmExportInstallFileGenerator::CleanupTemporaryVariables(std::ostream& os)
|
|
|
|
{
|
|
|
|
/* clang-format off */
|
|
|
|
os << "# Cleanup temporary variables.\n"
|
|
|
|
<< "set(_IMPORT_PREFIX)\n"
|
|
|
|
<< "\n";
|
|
|
|
/* clang-format on */
|
|
|
|
}
|
|
|
|
|
|
|
|
void cmExportInstallFileGenerator::LoadConfigFiles(std::ostream& os)
|
|
|
|
{
|
|
|
|
// Now load per-configuration properties for them.
|
|
|
|
/* clang-format off */
|
|
|
|
os << "# Load information for each installed configuration.\n"
|
|
|
|
<< "get_filename_component(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"
|
|
|
|
<< "file(GLOB CONFIG_FILES \"${_DIR}/"
|
|
|
|
<< this->GetConfigImportFileGlob() << "\")\n"
|
|
|
|
<< "foreach(f ${CONFIG_FILES})\n"
|
|
|
|
<< " include(${f})\n"
|
|
|
|
<< "endforeach()\n"
|
|
|
|
<< "\n";
|
|
|
|
/* clang-format on */
|
|
|
|
}
|
|
|
|
|
2016-05-16 14:34:04 +00:00
|
|
|
void cmExportInstallFileGenerator::ReplaceInstallPrefix(std::string& input)
|
2013-01-27 08:43:44 +00:00
|
|
|
{
|
2019-11-01 20:50:42 +00:00
|
|
|
cmGeneratorExpression::ReplaceInstallPrefix(input, "${_IMPORT_PREFIX}");
|
2013-01-27 08:43:44 +00:00
|
|
|
}
|
|
|
|
|
2016-05-16 14:34:04 +00:00
|
|
|
bool cmExportInstallFileGenerator::GenerateImportFileConfig(
|
|
|
|
const std::string& config, std::vector<std::string>& missingTargets)
|
2008-01-28 13:38:36 +00:00
|
|
|
{
|
|
|
|
// Skip configurations not enabled for this export.
|
2016-05-16 14:34:04 +00:00
|
|
|
if (!this->IEGen->InstallsForConfig(config)) {
|
2008-01-28 13:38:36 +00:00
|
|
|
return true;
|
2016-05-16 14:34:04 +00:00
|
|
|
}
|
2008-01-28 13:38:36 +00:00
|
|
|
|
|
|
|
// Construct the name of the file to generate.
|
2019-08-22 14:34:40 +00:00
|
|
|
std::string fileName = cmStrCat(this->FileDir, '/', this->FileBase, '-');
|
2016-05-16 14:34:04 +00:00
|
|
|
if (!config.empty()) {
|
2008-01-28 13:38:36 +00:00
|
|
|
fileName += cmSystemTools::LowerCase(config);
|
2016-05-16 14:34:04 +00:00
|
|
|
} else {
|
2008-01-28 13:38:36 +00:00
|
|
|
fileName += "noconfig";
|
2016-05-16 14:34:04 +00:00
|
|
|
}
|
2008-01-28 13:38:36 +00:00
|
|
|
fileName += this->FileExt;
|
|
|
|
|
|
|
|
// Open the output file to generate it.
|
2018-08-07 13:01:25 +00:00
|
|
|
cmGeneratedFileStream exportFileStream(fileName, true);
|
2016-05-16 14:34:04 +00:00
|
|
|
if (!exportFileStream) {
|
2008-01-28 13:38:36 +00:00
|
|
|
std::string se = cmSystemTools::GetLastSystemError();
|
2015-01-05 19:31:31 +00:00
|
|
|
std::ostringstream e;
|
2016-05-16 14:34:04 +00:00
|
|
|
e << "cannot write to file \"" << fileName << "\": " << se;
|
2019-01-23 15:12:17 +00:00
|
|
|
cmSystemTools::Error(e.str());
|
2008-01-28 13:38:36 +00:00
|
|
|
return false;
|
2016-05-16 14:34:04 +00:00
|
|
|
}
|
2008-01-28 13:38:36 +00:00
|
|
|
std::ostream& os = exportFileStream;
|
|
|
|
|
|
|
|
// Start with the import file header.
|
|
|
|
this->GenerateImportHeaderCode(os, config);
|
|
|
|
|
|
|
|
// Generate the per-config target information.
|
2013-01-13 08:44:52 +00:00
|
|
|
this->GenerateImportConfig(os, config, missingTargets);
|
2008-01-28 13:38:36 +00:00
|
|
|
|
|
|
|
// End with the import file footer.
|
|
|
|
this->GenerateImportFooterCode(os);
|
|
|
|
|
|
|
|
// Record this per-config import file.
|
|
|
|
this->ConfigImportFiles[config] = fileName;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-05-16 14:34:04 +00:00
|
|
|
void cmExportInstallFileGenerator::GenerateImportTargetsConfig(
|
|
|
|
std::ostream& os, const std::string& config, std::string const& suffix,
|
|
|
|
std::vector<std::string>& missingTargets)
|
2008-01-28 13:38:36 +00:00
|
|
|
{
|
|
|
|
// Add each target in the set to the export.
|
2019-09-08 09:14:55 +00:00
|
|
|
for (std::unique_ptr<cmTargetExport> const& te :
|
|
|
|
this->IEGen->GetExportSet()->GetTargetExports()) {
|
2008-01-28 13:38:36 +00:00
|
|
|
// Collect import properties for this target.
|
2019-09-08 09:14:55 +00:00
|
|
|
if (this->GetExportTargetType(te.get()) ==
|
|
|
|
cmStateEnums::INTERFACE_LIBRARY) {
|
2012-11-20 10:06:29 +00:00
|
|
|
continue;
|
2016-05-16 14:34:04 +00:00
|
|
|
}
|
2013-12-19 13:24:46 +00:00
|
|
|
|
|
|
|
ImportPropertyMap properties;
|
|
|
|
std::set<std::string> importedLocations;
|
|
|
|
|
2011-11-12 17:12:07 +00:00
|
|
|
this->SetImportLocationProperty(config, suffix, te->ArchiveGenerator,
|
|
|
|
properties, importedLocations);
|
|
|
|
this->SetImportLocationProperty(config, suffix, te->LibraryGenerator,
|
|
|
|
properties, importedLocations);
|
2016-05-16 14:34:04 +00:00
|
|
|
this->SetImportLocationProperty(config, suffix, te->RuntimeGenerator,
|
|
|
|
properties, importedLocations);
|
2017-03-23 13:32:08 +00:00
|
|
|
this->SetImportLocationProperty(config, suffix, te->ObjectsGenerator,
|
|
|
|
properties, importedLocations);
|
2011-11-12 17:12:07 +00:00
|
|
|
this->SetImportLocationProperty(config, suffix, te->FrameworkGenerator,
|
|
|
|
properties, importedLocations);
|
|
|
|
this->SetImportLocationProperty(config, suffix, te->BundleGenerator,
|
|
|
|
properties, importedLocations);
|
2008-01-28 13:38:36 +00:00
|
|
|
|
|
|
|
// If any file location was set for the target add it to the
|
|
|
|
// import file.
|
2016-05-16 14:34:04 +00:00
|
|
|
if (!properties.empty()) {
|
2008-01-28 13:38:36 +00:00
|
|
|
// Get the rest of the target details.
|
2016-05-16 14:34:04 +00:00
|
|
|
cmGeneratorTarget* gtgt = te->Target;
|
|
|
|
this->SetImportDetailProperties(config, suffix, gtgt, properties,
|
|
|
|
missingTargets);
|
2008-01-28 13:38:36 +00:00
|
|
|
|
2013-01-04 14:58:16 +00:00
|
|
|
this->SetImportLinkInterface(config, suffix,
|
|
|
|
cmGeneratorExpression::InstallInterface,
|
2012-10-06 15:51:07 +00:00
|
|
|
gtgt, properties, missingTargets);
|
2013-01-04 14:58:16 +00:00
|
|
|
|
2018-06-04 05:48:39 +00:00
|
|
|
// TODO: PUBLIC_HEADER_LOCATION
|
2008-01-28 20:22:07 +00:00
|
|
|
// This should wait until the build feature propagation stuff
|
|
|
|
// is done. Then this can be a propagated include directory.
|
2008-01-28 13:38:36 +00:00
|
|
|
// this->GenerateImportProperty(config, te->HeaderGenerator,
|
|
|
|
// properties);
|
|
|
|
|
|
|
|
// Generate code in the export file.
|
2015-10-17 13:10:32 +00:00
|
|
|
this->GenerateImportPropertyCode(os, config, gtgt, properties);
|
|
|
|
this->GenerateImportedFileChecksCode(os, gtgt, properties,
|
2011-11-12 17:12:07 +00:00
|
|
|
importedLocations);
|
2008-01-28 13:38:36 +00:00
|
|
|
}
|
2016-05-16 14:34:04 +00:00
|
|
|
}
|
2008-01-28 13:38:36 +00:00
|
|
|
}
|
|
|
|
|
2016-05-16 14:34:04 +00:00
|
|
|
void cmExportInstallFileGenerator::SetImportLocationProperty(
|
|
|
|
const std::string& config, std::string const& suffix,
|
|
|
|
cmInstallTargetGenerator* itgen, ImportPropertyMap& properties,
|
|
|
|
std::set<std::string>& importedLocations)
|
2008-01-28 13:38:36 +00:00
|
|
|
{
|
|
|
|
// Skip rules that do not match this configuration.
|
2016-05-16 14:34:04 +00:00
|
|
|
if (!(itgen && itgen->InstallsForConfig(config))) {
|
2008-01-28 13:38:36 +00:00
|
|
|
return;
|
2016-05-16 14:34:04 +00:00
|
|
|
}
|
2008-01-28 13:38:36 +00:00
|
|
|
|
2008-02-06 19:20:36 +00:00
|
|
|
// Get the target to be installed.
|
2015-10-17 12:54:15 +00:00
|
|
|
cmGeneratorTarget* target = itgen->GetTarget();
|
2008-01-28 13:38:36 +00:00
|
|
|
|
|
|
|
// Construct the installed location of the target.
|
2015-02-11 19:02:45 +00:00
|
|
|
std::string dest = itgen->GetDestination(config);
|
2008-01-28 13:38:36 +00:00
|
|
|
std::string value;
|
2018-01-31 15:20:02 +00:00
|
|
|
if (!cmSystemTools::FileIsFullPath(dest)) {
|
2008-01-28 13:38:36 +00:00
|
|
|
// The target is installed relative to the installation prefix.
|
2014-12-15 14:52:48 +00:00
|
|
|
value = "${_IMPORT_PREFIX}/";
|
2016-05-16 14:34:04 +00:00
|
|
|
}
|
2008-01-28 13:38:36 +00:00
|
|
|
value += dest;
|
|
|
|
value += "/";
|
|
|
|
|
2016-05-16 14:34:04 +00:00
|
|
|
if (itgen->IsImportLibrary()) {
|
2008-02-06 19:20:36 +00:00
|
|
|
// Construct the property name.
|
2019-08-22 14:34:40 +00:00
|
|
|
std::string prop = cmStrCat("IMPORTED_IMPLIB", suffix);
|
2008-02-06 19:20:36 +00:00
|
|
|
|
|
|
|
// Append the installed file name.
|
2018-11-21 19:51:35 +00:00
|
|
|
value += cmInstallTargetGenerator::GetInstallFilename(
|
|
|
|
target, config, cmInstallTargetGenerator::NameImplib);
|
2008-02-06 19:20:36 +00:00
|
|
|
|
|
|
|
// Store the property.
|
|
|
|
properties[prop] = value;
|
2011-11-12 17:12:07 +00:00
|
|
|
importedLocations.insert(prop);
|
2017-03-23 13:32:08 +00:00
|
|
|
} else if (itgen->GetTarget()->GetType() == cmStateEnums::OBJECT_LIBRARY) {
|
|
|
|
// Construct the property name.
|
2019-08-22 14:34:40 +00:00
|
|
|
std::string prop = cmStrCat("IMPORTED_OBJECTS", suffix);
|
2017-03-23 13:32:08 +00:00
|
|
|
|
|
|
|
// Compute all the object files inside this target and setup
|
|
|
|
// IMPORTED_OBJECTS as a list of object files
|
|
|
|
std::vector<std::string> objects;
|
|
|
|
itgen->GetInstallObjectNames(config, objects);
|
2017-09-11 10:40:26 +00:00
|
|
|
for (std::string& obj : objects) {
|
2019-08-03 11:20:31 +00:00
|
|
|
obj = cmStrCat(value, obj);
|
2017-03-23 13:32:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Store the property.
|
|
|
|
properties[prop] = cmJoin(objects, ";");
|
|
|
|
importedLocations.insert(prop);
|
2016-05-16 14:34:04 +00:00
|
|
|
} else {
|
2008-02-06 19:20:36 +00:00
|
|
|
// Construct the property name.
|
2019-08-22 14:34:40 +00:00
|
|
|
std::string prop = cmStrCat("IMPORTED_LOCATION", suffix);
|
2008-01-28 13:38:36 +00:00
|
|
|
|
2008-02-06 19:20:36 +00:00
|
|
|
// Append the installed file name.
|
2016-05-16 14:34:04 +00:00
|
|
|
if (target->IsAppBundleOnApple()) {
|
2018-11-21 19:51:35 +00:00
|
|
|
value += cmInstallTargetGenerator::GetInstallFilename(target, config);
|
2008-02-06 19:20:36 +00:00
|
|
|
value += ".app/Contents/MacOS/";
|
2018-11-21 19:51:35 +00:00
|
|
|
value += cmInstallTargetGenerator::GetInstallFilename(target, config);
|
2016-05-16 14:34:04 +00:00
|
|
|
} else {
|
2018-11-21 19:51:35 +00:00
|
|
|
value += cmInstallTargetGenerator::GetInstallFilename(
|
|
|
|
target, config, cmInstallTargetGenerator::NameReal);
|
2016-05-16 14:34:04 +00:00
|
|
|
}
|
2008-02-06 19:20:36 +00:00
|
|
|
|
|
|
|
// Store the property.
|
|
|
|
properties[prop] = value;
|
2011-11-12 17:12:07 +00:00
|
|
|
importedLocations.insert(prop);
|
2016-05-16 14:34:04 +00:00
|
|
|
}
|
2008-01-28 13:38:36 +00:00
|
|
|
}
|
|
|
|
|
2018-02-28 15:58:07 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2016-05-16 14:34:04 +00:00
|
|
|
void cmExportInstallFileGenerator::HandleMissingTarget(
|
|
|
|
std::string& link_libs, std::vector<std::string>& missingTargets,
|
2015-10-17 13:05:46 +00:00
|
|
|
cmGeneratorTarget* depender, cmGeneratorTarget* dependee)
|
2012-09-28 19:47:37 +00:00
|
|
|
{
|
2013-05-17 08:12:02 +00:00
|
|
|
const std::string name = dependee->GetName();
|
2015-10-17 13:05:46 +00:00
|
|
|
cmGlobalGenerator* gg = dependee->GetLocalGenerator()->GetGlobalGenerator();
|
2019-08-19 18:18:08 +00:00
|
|
|
auto exportInfo = this->FindNamespaces(gg, name);
|
|
|
|
std::vector<std::string> const& exportFiles = exportInfo.first;
|
|
|
|
if (exportFiles.size() == 1) {
|
|
|
|
std::string missingTarget = exportInfo.second;
|
2013-05-17 08:12:02 +00:00
|
|
|
|
2015-10-17 13:08:13 +00:00
|
|
|
missingTarget += dependee->GetExportName();
|
2012-09-28 19:47:37 +00:00
|
|
|
link_libs += missingTarget;
|
2018-01-25 13:59:33 +00:00
|
|
|
missingTargets.push_back(std::move(missingTarget));
|
2016-05-16 14:34:04 +00:00
|
|
|
} else {
|
2013-10-10 09:14:11 +00:00
|
|
|
// All exported targets should be known here and should be unique.
|
|
|
|
// This is probably user-error.
|
2019-08-19 18:18:08 +00:00
|
|
|
this->ComplainAboutMissingTarget(depender, dependee, exportFiles);
|
2016-05-16 14:34:04 +00:00
|
|
|
}
|
2012-09-28 19:47:37 +00:00
|
|
|
}
|
|
|
|
|
2019-08-19 18:18:08 +00:00
|
|
|
std::pair<std::vector<std::string>, std::string>
|
|
|
|
cmExportInstallFileGenerator::FindNamespaces(cmGlobalGenerator* gg,
|
|
|
|
const std::string& name)
|
2012-09-28 19:47:37 +00:00
|
|
|
{
|
2019-08-19 18:18:08 +00:00
|
|
|
std::vector<std::string> exportFiles;
|
|
|
|
std::string ns;
|
2012-09-28 19:47:37 +00:00
|
|
|
const cmExportSetMap& exportSets = gg->GetExportSets();
|
|
|
|
|
2017-09-11 10:40:26 +00:00
|
|
|
for (auto const& expIt : exportSets) {
|
2019-09-06 10:16:02 +00:00
|
|
|
const cmExportSet& exportSet = expIt.second;
|
2012-09-28 19:47:37 +00:00
|
|
|
|
|
|
|
bool containsTarget = false;
|
2019-09-08 09:14:55 +00:00
|
|
|
for (auto const& target : exportSet.GetTargetExports()) {
|
2017-09-11 10:40:26 +00:00
|
|
|
if (name == target->TargetName) {
|
2012-09-28 19:47:37 +00:00
|
|
|
containsTarget = true;
|
|
|
|
break;
|
|
|
|
}
|
2016-05-16 14:34:04 +00:00
|
|
|
}
|
2012-09-28 19:47:37 +00:00
|
|
|
|
2016-05-16 14:34:04 +00:00
|
|
|
if (containsTarget) {
|
2012-09-28 19:47:37 +00:00
|
|
|
std::vector<cmInstallExportGenerator const*> const* installs =
|
2019-09-06 10:16:02 +00:00
|
|
|
exportSet.GetInstallations();
|
2017-09-11 10:40:26 +00:00
|
|
|
for (cmInstallExportGenerator const* install : *installs) {
|
2019-08-19 18:18:08 +00:00
|
|
|
exportFiles.push_back(install->GetDestinationFile());
|
|
|
|
ns = install->GetNamespace();
|
2012-09-28 19:47:37 +00:00
|
|
|
}
|
|
|
|
}
|
2016-05-16 14:34:04 +00:00
|
|
|
}
|
2012-09-28 19:47:37 +00:00
|
|
|
|
2019-09-06 20:27:39 +00:00
|
|
|
return { exportFiles, ns };
|
2012-09-28 19:47:37 +00:00
|
|
|
}
|
|
|
|
|
2016-05-16 14:34:04 +00:00
|
|
|
void cmExportInstallFileGenerator::ComplainAboutMissingTarget(
|
2019-08-19 18:18:08 +00:00
|
|
|
cmGeneratorTarget* depender, cmGeneratorTarget* dependee,
|
|
|
|
std::vector<std::string> const& exportFiles)
|
2008-01-28 13:38:36 +00:00
|
|
|
{
|
2015-01-05 19:31:31 +00:00
|
|
|
std::ostringstream e;
|
2016-05-16 14:34:04 +00:00
|
|
|
e << "install(EXPORT \"" << this->IEGen->GetExportSet()->GetName()
|
2012-03-01 10:52:32 +00:00
|
|
|
<< "\" ...) "
|
2008-02-01 13:56:00 +00:00
|
|
|
<< "includes target \"" << depender->GetName()
|
2012-09-15 19:55:24 +00:00
|
|
|
<< "\" which requires target \"" << dependee->GetName() << "\" ";
|
2019-08-19 18:18:08 +00:00
|
|
|
if (exportFiles.empty()) {
|
|
|
|
e << "that is not in any export set.";
|
2016-05-16 14:34:04 +00:00
|
|
|
} else {
|
2019-08-19 18:18:08 +00:00
|
|
|
e << "that is not in this export set, but in multiple other export sets: "
|
|
|
|
<< cmJoin(exportFiles, ", ") << ".\n";
|
|
|
|
e << "An exported target cannot depend upon another target which is "
|
|
|
|
"exported multiple times. Consider consolidating the exports of the "
|
|
|
|
"\""
|
|
|
|
<< dependee->GetName() << "\" target to a single export.";
|
2016-05-16 14:34:04 +00:00
|
|
|
}
|
2019-01-23 15:12:17 +00:00
|
|
|
cmSystemTools::Error(e.str());
|
2008-01-28 13:38:36 +00:00
|
|
|
}
|
2013-05-20 22:57:58 +00:00
|
|
|
|
2016-05-16 14:34:04 +00:00
|
|
|
std::string cmExportInstallFileGenerator::InstallNameDir(
|
2019-11-01 21:37:59 +00:00
|
|
|
cmGeneratorTarget* target, const std::string& config)
|
2013-05-20 22:57:58 +00:00
|
|
|
{
|
|
|
|
std::string install_name_dir;
|
|
|
|
|
2015-08-04 17:19:47 +00:00
|
|
|
cmMakefile* mf = target->Target->GetMakefile();
|
2016-05-16 14:34:04 +00:00
|
|
|
if (mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) {
|
2019-11-01 21:37:59 +00:00
|
|
|
install_name_dir =
|
|
|
|
target->GetInstallNameDirForInstallTree(config, "${_IMPORT_PREFIX}");
|
2016-05-16 14:34:04 +00:00
|
|
|
}
|
2013-05-20 22:57:58 +00:00
|
|
|
|
|
|
|
return install_name_dir;
|
|
|
|
}
|