Browse Source

Merge topic 'install-EXPORT-absolute-prefix'

dd089e08 install: Allow absolute EXPORT destination with relative targets (#15258)
Brad King 11 years ago
parent
commit
1ac8523c3b

+ 9 - 0
Help/release/dev/install-EXPORT-absolute-prefix.rst

@@ -0,0 +1,9 @@
+install-EXPORT-absolute-prefix
+------------------------------
+
+* The :command:`install(EXPORT)` command now works with an absolute
+  ``DESTINATION`` even if targets in the export set are installed
+  with a destination or usage requirements specified relative to the
+  install prefix.  The value of the :variable:`CMAKE_INSTALL_PREFIX`
+  variable is hard-coded into the installed export file as the base
+  for relative references.

+ 20 - 37
Source/cmExportInstallFileGenerator.cxx

@@ -69,13 +69,24 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
   this->GenerateExpectedTargetsCode(os, expectedTargets);
   }
 
-  // Add code to compute the installation prefix relative to the
-  // import file location.
+  // Set an _IMPORT_PREFIX variable for import location properties
+  // to reference if they are relative to the install prefix.
+  std::string installPrefix =
+    this->IEGen->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
   const char* installDest = this->IEGen->GetDestination();
-  if(!cmSystemTools::FileIsFullPath(installDest))
+  if(cmSystemTools::FileIsFullPath(installDest))
     {
-    std::string installPrefix =
-      this->IEGen->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
+    // The export file is being installed to an absolute path so the
+    // package is not relocatable.  Use the configured install prefix.
+    os <<
+      "# The installation prefix configured by this project.\n"
+      "set(_IMPORT_PREFIX \"" << installPrefix << "\")\n"
+      "\n";
+    }
+  else
+    {
+    // Add code to compute the installation prefix relative to the
+    // import file location.
     std::string absDest = installPrefix + "/" + installDest;
     std::string absDestS = absDest + "/";
     os << "# Compute the installation prefix relative to this file.\n"
@@ -106,9 +117,6 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
       dest = cmSystemTools::GetFilenamePath(dest);
       }
     os << "\n";
-
-    // Import location properties may reference this variable.
-    this->ImportPrefix = "${_IMPORT_PREFIX}/";
     }
 
   std::vector<std::string> missingTargets;
@@ -209,12 +217,9 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
      << "\n";
 
   // Cleanup the import prefix variable.
-  if(!this->ImportPrefix.empty())
-    {
-    os << "# Cleanup temporary variables.\n"
-       << "set(_IMPORT_PREFIX)\n"
-       << "\n";
-    }
+  os << "# Cleanup temporary variables.\n"
+     << "set(_IMPORT_PREFIX)\n"
+     << "\n";
   this->GenerateImportedFileCheckLoop(os);
 
   bool result = true;
@@ -394,11 +399,7 @@ cmExportInstallFileGenerator
   if(!cmSystemTools::FileIsFullPath(dest.c_str()))
     {
     // The target is installed relative to the installation prefix.
-    if(this->ImportPrefix.empty())
-      {
-      this->ComplainAboutImportPrefix(itgen);
-      }
-    value = this->ImportPrefix;
+    value = "${_IMPORT_PREFIX}/";
     }
   value += dest;
   value += "/";
@@ -508,24 +509,6 @@ cmExportInstallFileGenerator
   return namespaces;
 }
 
-
-//----------------------------------------------------------------------------
-void
-cmExportInstallFileGenerator
-::ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen)
-{
-  const char* installDest = this->IEGen->GetDestination();
-  cmOStringStream e;
-  e << "install(EXPORT \""
-    << this->IEGen->GetExportSet()->GetName()
-    << "\") given absolute "
-    << "DESTINATION \"" << installDest << "\" but the export "
-    << "references an installation of target \""
-    << itgen->GetTarget()->GetName() << "\" which has relative "
-    << "DESTINATION \"" << itgen->GetDestination() << "\".";
-  cmSystemTools::Error(e.str().c_str());
-}
-
 //----------------------------------------------------------------------------
 void
 cmExportInstallFileGenerator

+ 0 - 4
Source/cmExportInstallFileGenerator.h

@@ -83,14 +83,10 @@ protected:
                                  std::set<std::string>& importedLocations
                                 );
 
-  void ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen);
-
   std::string InstallNameDir(cmTarget* target, const std::string& config);
 
   cmInstallExportGenerator* IEGen;
 
-  std::string ImportPrefix;
-
   // The import file generated for each configuration.
   std::map<std::string, std::string> ConfigImportFiles;
 };

+ 15 - 0
Tests/ExportImport/Export/CMakeLists.txt

@@ -508,3 +508,18 @@ export(TARGETS testExe2 testLib4 testLib5 testLib6 testExe3 testExe2lib
   )
 
 add_subdirectory(Interface)
+
+#-----------------------------------------------------------------------------
+# Install export with absolute destination but relative pieces.
+add_library(testLibAbs1 STATIC testLibAbs1.c)
+target_include_directories(testLibAbs1 INTERFACE
+  "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/abs/1a;include/abs/1b>"
+  )
+install(
+  TARGETS testLibAbs1
+  EXPORT expAbs
+  ARCHIVE DESTINATION lib
+  INCLUDES DESTINATION include/abs
+  )
+install(DIRECTORY include/abs DESTINATION include)
+install(EXPORT expAbs NAMESPACE expAbs_ DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/expAbs)

+ 1 - 0
Tests/ExportImport/Export/include/abs/1a/testLibAbs1a.h

@@ -0,0 +1 @@
+#define testLibAbs1a

+ 1 - 0
Tests/ExportImport/Export/include/abs/1b/testLibAbs1b.h

@@ -0,0 +1 @@
+#define testLibAbs1b

+ 1 - 0
Tests/ExportImport/Export/include/abs/testLibAbs1.h

@@ -0,0 +1 @@
+extern int testLibAbs1(void);

+ 1 - 0
Tests/ExportImport/Export/testLibAbs1.c

@@ -0,0 +1 @@
+int testLibAbs1(void) { return 0; }

+ 10 - 0
Tests/ExportImport/Import/A/CMakeLists.txt

@@ -95,6 +95,16 @@ foreach(c DEBUG RELWITHDEBINFO)
   set_property(TARGET imp_testExe1b PROPERTY COMPILE_DEFINITIONS_${c} EXE_DBG)
 endforeach()
 
+#-----------------------------------------------------------------------------
+include(${CMAKE_INSTALL_PREFIX}/lib/expAbs/expAbs.cmake)
+
+add_executable(imp_testExeAbs1
+  imp_testExeAbs1.c
+  )
+target_link_libraries(imp_testExeAbs1
+  expAbs_testLibAbs1
+  )
+
 #-----------------------------------------------------------------------------
 # Create a custom target to generate a header for the libraries below.
 # Drive the header generation through an indirect chain of imported

+ 15 - 0
Tests/ExportImport/Import/A/imp_testExeAbs1.c

@@ -0,0 +1,15 @@
+#include "testLibAbs1.h"
+#include "testLibAbs1a.h"
+#include "testLibAbs1b.h"
+#ifndef testLibAbs1a
+# error "testLibAbs1a not defined"
+#endif
+#ifndef testLibAbs1b
+# error "testLibAbs1b not defined"
+#endif
+int main()
+{
+  return 0
+    + testLibAbs1()
+    ;
+}