From f81b9475f3724eef5d9e81b9190e30f5df09c808 Mon Sep 17 00:00:00 2001 From: Bill Hoffman Date: Tue, 12 Jul 2016 13:26:55 -0400 Subject: [PATCH] Export: Factor out file generation steps into helpers Do not actually generate any content in the driving code paths. Use helpers for that. --- Source/cmExportFileGenerator.cxx | 45 ++++--- Source/cmExportFileGenerator.h | 2 + Source/cmExportInstallFileGenerator.cxx | 153 +++++++++++++----------- Source/cmExportInstallFileGenerator.h | 8 ++ 4 files changed, 121 insertions(+), 87 deletions(-) diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 23c77d955..c4c7d7d92 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -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) { diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index 354994a14..5234597a3 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -78,6 +78,8 @@ protected: std::vector& 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); diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index bcadaa023..f47038f08 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -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 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; diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h index c693dc174..fe34efde3 100644 --- a/Source/cmExportInstallFileGenerator.h +++ b/Source/cmExportInstallFileGenerator.h @@ -80,6 +80,14 @@ protected: std::vector 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& missingTargets);