Browse Source

CPack/NSIS: Add custom component install directory

Roman Wüger 9 years ago
parent
commit
06dea230ae

+ 5 - 0
Modules/CPackNSIS.cmake

@@ -96,6 +96,11 @@
 #  Contact information for questions and comments about the installation
 #  process.
 #
+# .. variable:: CPACK_NSIS_<compName>_INSTALL_DIRECTORY
+#
+#  Custom install directory for the specified component <compName> instead
+#  of $INSTDIR.
+#
 # .. variable:: CPACK_NSIS_CREATE_ICONS_EXTRA
 #
 #  Additional NSIS commands for creating start menu shortcuts.

+ 35 - 6
Source/CPack/cmCPackNSISGenerator.cxx

@@ -71,14 +71,26 @@ int cmCPackNSISGenerator::PackageFiles()
   std::ostringstream str;
   std::vector<std::string>::const_iterator it;
   for (it = files.begin(); it != files.end(); ++it) {
+    std::string outputDir = "$INSTDIR";
     std::string fileN =
       cmSystemTools::RelativePath(toplevel.c_str(), it->c_str());
     if (!this->Components.empty()) {
+      const std::string::size_type pos = fileN.find('/');
+
+      // Use the custom component install directory if we have one
+      if (pos != std::string::npos) {
+        const std::string componentName = fileN.substr(0, pos);
+        outputDir = CustomComponentInstallDirectory(componentName);
+      } else {
+        outputDir = CustomComponentInstallDirectory(fileN);
+      }
+
       // Strip off the component part of the path.
-      fileN = fileN.substr(fileN.find('/') + 1, std::string::npos);
+      fileN = fileN.substr(pos + 1, std::string::npos);
     }
     std::replace(fileN.begin(), fileN.end(), '/', '\\');
-    str << "  Delete \"$INSTDIR\\" << fileN << "\"" << std::endl;
+
+    str << "  Delete \"" << outputDir << "\\" << fileN << "\"" << std::endl;
   }
   cmCPackLogger(cmCPackLog::LOG_DEBUG, "Uninstall Files: " << str.str()
                                                            << std::endl);
@@ -108,7 +120,12 @@ int cmCPackNSISGenerator::PackageFiles()
       }
     }
     std::replace(fileN.begin(), fileN.end(), '/', '\\');
-    dstr << "  RMDir \"$INSTDIR\\" << fileN << "\"" << std::endl;
+
+    const std::string componentOutputDir =
+      CustomComponentInstallDirectory(componentName);
+
+    dstr << "  RMDir \"" << componentOutputDir << "\\" << fileN << "\""
+         << std::endl;
     if (!componentName.empty()) {
       this->Components[componentName].Directories.push_back(fileN);
     }
@@ -650,7 +667,10 @@ std::string cmCPackNSISGenerator::CreateComponentDescription(
     }
     componentCode += "  SectionIn" + out.str() + "\n";
   }
-  componentCode += "  SetOutPath \"$INSTDIR\"\n";
+
+  const std::string componentOutputDir =
+    CustomComponentInstallDirectory(component->Name);
+  componentCode += "  SetOutPath \"" + componentOutputDir + "\"\n";
 
   // Create the actual installation commands
   if (component->IsDownloaded) {
@@ -796,13 +816,13 @@ std::string cmCPackNSISGenerator::CreateComponentDescription(
        ++pathIt) {
     path = *pathIt;
     std::replace(path.begin(), path.end(), '/', '\\');
-    macrosOut << "  Delete \"$INSTDIR\\" << path << "\"\n";
+    macrosOut << "  Delete \"" << componentOutputDir << "\\" << path << "\"\n";
   }
   for (pathIt = component->Directories.begin();
        pathIt != component->Directories.end(); ++pathIt) {
     path = *pathIt;
     std::replace(path.begin(), path.end(), '/', '\\');
-    macrosOut << "  RMDir \"$INSTDIR\\" << path << "\"\n";
+    macrosOut << "  RMDir \"" << componentOutputDir << "\\" << path << "\"\n";
   }
   macrosOut << "  noremove_" << component->Name << ":\n";
   macrosOut << "!macroend\n";
@@ -914,6 +934,15 @@ std::string cmCPackNSISGenerator::CreateComponentGroupDescription(
   return code;
 }
 
+std::string cmCPackNSISGenerator::CustomComponentInstallDirectory(
+  const std::string& componentName)
+{
+  const char* outputDir =
+    this->GetOption("CPACK_NSIS_" + componentName + "_INSTALL_DIRECTORY");
+  const std::string componentOutputDir = (outputDir ? outputDir : "$INSTDIR");
+  return componentOutputDir;
+}
+
 std::string cmCPackNSISGenerator::TranslateNewlines(std::string str)
 {
   cmSystemTools::ReplaceString(str, "\n", "$\\r$\\n");

+ 5 - 0
Source/CPack/cmCPackNSISGenerator.h

@@ -84,6 +84,11 @@ protected:
   std::string CreateComponentGroupDescription(cmCPackComponentGroup* group,
                                               std::ostream& macrosOut);
 
+  /// Returns the custom install directory if available for the specified
+  /// component, otherwise $INSTDIR is returned.
+  std::string CustomComponentInstallDirectory(
+    const std::string& componentName);
+
   /// Translations any newlines found in the string into \\r\\n, so that the
   /// resulting string can be used within NSIS.
   static std::string TranslateNewlines(std::string str);