Export: Factor out file generation steps into helpers

Do not actually generate any content in the driving code paths.
Use helpers for that.
This commit is contained in:
Bill Hoffman 2016-07-12 13:26:55 -04:00 committed by Brad King
parent f506489d1e
commit f81b9475f3
4 changed files with 121 additions and 87 deletions

View File

@ -96,24 +96,8 @@ bool cmExportFileGenerator::GenerateImportFile()
}
std::ostream& os = *foutPtr;
// Protect that file against use with older CMake versions.
/* clang-format off */
os << "# Generated by CMake\n\n";
os << "if(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n"
<< " message(FATAL_ERROR \"CMake >= 2.6.0 required\")\n"
<< "endif()\n";
/* clang-format on */
// Isolate the file policy level.
// We use 2.6 here instead of the current version because newer
// versions of CMake should be able to export files imported by 2.6
// until the import format changes.
/* clang-format off */
os << "cmake_policy(PUSH)\n"
<< "cmake_policy(VERSION 2.6)\n";
/* clang-format on */
// Start with the import file header.
this->GeneratePolicyHeaderCode(os);
this->GenerateImportHeaderCode(os);
// Create all the imported targets.
@ -121,7 +105,7 @@ bool cmExportFileGenerator::GenerateImportFile()
// End with the import file footer.
this->GenerateImportFooterCode(os);
os << "cmake_policy(POP)\n";
this->GeneratePolicyFooterCode(os);
return result;
}
@ -832,6 +816,31 @@ void cmExportFileGenerator::SetImportLinkProperty(
properties[prop] = link_entries;
}
void cmExportFileGenerator::GeneratePolicyHeaderCode(std::ostream& os)
{
// Protect that file against use with older CMake versions.
/* clang-format off */
os << "# Generated by CMake\n\n";
os << "if(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n"
<< " message(FATAL_ERROR \"CMake >= 2.6.0 required\")\n"
<< "endif()\n";
/* clang-format on */
// Isolate the file policy level.
// We use 2.6 here instead of the current version because newer
// versions of CMake should be able to export files imported by 2.6
// until the import format changes.
/* clang-format off */
os << "cmake_policy(PUSH)\n"
<< "cmake_policy(VERSION 2.6)\n";
/* clang-format on */
}
void cmExportFileGenerator::GeneratePolicyFooterCode(std::ostream& os)
{
os << "cmake_policy(POP)\n";
}
void cmExportFileGenerator::GenerateImportHeaderCode(std::ostream& os,
const std::string& config)
{

View File

@ -78,6 +78,8 @@ protected:
std::vector<std::string>& missingTargets);
// Methods to implement export file code generation.
void GeneratePolicyHeaderCode(std::ostream& os);
void GeneratePolicyFooterCode(std::ostream& os);
void GenerateImportHeaderCode(std::ostream& os,
const std::string& config = "");
void GenerateImportFooterCode(std::ostream& os);

View File

@ -75,58 +75,8 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
this->GenerateExpectedTargetsCode(os, expectedTargets);
}
// 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";
if (cmHasLiteralPrefix(absDestS.c_str(), "/lib/") ||
cmHasLiteralPrefix(absDestS.c_str(), "/lib64/") ||
cmHasLiteralPrefix(absDestS.c_str(), "/usr/lib/") ||
cmHasLiteralPrefix(absDestS.c_str(), "/usr/lib64/")) {
// 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";
}
// Compute the relative import prefix for the file
this->GenerateImportPrefix(os);
std::vector<std::string> missingTargets;
@ -204,24 +154,9 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
this->GenerateRequiredCMakeVersion(os, "2.8.12");
}
// 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 */
this->LoadConfigFiles(os);
// Cleanup the import prefix variable.
/* clang-format off */
os << "# Cleanup temporary variables.\n"
<< "set(_IMPORT_PREFIX)\n"
<< "\n";
/* clang-format on */
this->CleanupTemporaryVariables(os);
this->GenerateImportedFileCheckLoop(os);
bool result = true;
@ -242,6 +177,86 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
return result;
}
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";
if (cmHasLiteralPrefix(absDestS.c_str(), "/lib/") ||
cmHasLiteralPrefix(absDestS.c_str(), "/lib64/") ||
cmHasLiteralPrefix(absDestS.c_str(), "/usr/lib/") ||
cmHasLiteralPrefix(absDestS.c_str(), "/usr/lib64/")) {
// 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 */
}
void cmExportInstallFileGenerator::ReplaceInstallPrefix(std::string& input)
{
std::string::size_type pos = 0;

View File

@ -80,6 +80,14 @@ protected:
std::vector<std::string> FindNamespaces(cmGlobalGenerator* gg,
const std::string& name);
/** Generate the relative import prefix. */
void GenerateImportPrefix(std::ostream&);
/** Generate the relative import prefix. */
void LoadConfigFiles(std::ostream&);
void CleanupTemporaryVariables(std::ostream&);
/** Generate a per-configuration file for the targets. */
bool GenerateImportFileConfig(const std::string& config,
std::vector<std::string>& missingTargets);