Răsfoiți Sursa

BUG: Fix #5868 - add COMPONENT handling to the SCRIPT and CODE signatures of the INSTALL command.

David Cole 18 ani în urmă
părinte
comite
c8e832dcf5

+ 48 - 11
Source/cmInstallCommand.cxx

@@ -99,8 +99,34 @@ bool cmInstallCommand::InitialPass(std::vector<std::string> const& args)
 //----------------------------------------------------------------------------
 bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args)
 {
+  std::string component("Unspecified");
+  int componentCount = 0;
   bool doing_script = false;
   bool doing_code = false;
+
+  // Scan the args once for COMPONENT. Only allow one.
+  //
+  for(size_t i=0; i < args.size(); ++i)
+    {
+    if(args[i] == "COMPONENT" && i+1 < args.size())
+        {
+        ++componentCount;
+        ++i;
+        component = args[i];
+        }
+    }
+
+  if(componentCount>1)
+    {
+    this->SetError("given more than one COMPONENT for the SCRIPT or CODE "
+      "signature of the INSTALL command. "
+      "Use multiple INSTALL commands with one COMPONENT each.");
+    return false;
+    }
+
+  // Scan the args again, this time adding install generators each time we
+  // encounter a SCRIPT or CODE arg:
+  //
   for(size_t i=0; i < args.size(); ++i)
     {
     if(args[i] == "SCRIPT")
@@ -113,6 +139,11 @@ bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args)
       doing_script = false;
       doing_code = true;
       }
+    else if(args[i] == "COMPONENT")
+      {
+      doing_script = false;
+      doing_code = false;
+      }
     else if(doing_script)
       {
       doing_script = false;
@@ -129,16 +160,17 @@ bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args)
         return false;
         }
       this->Makefile->AddInstallGenerator(
-        new cmInstallScriptGenerator(script.c_str()));
+        new cmInstallScriptGenerator(script.c_str(), false, component.c_str()));
       }
     else if(doing_code)
       {
       doing_code = false;
       std::string code = args[i];
       this->Makefile->AddInstallGenerator(
-        new cmInstallScriptGenerator(code.c_str(), true));
+        new cmInstallScriptGenerator(code.c_str(), true, component.c_str()));
       }
     }
+
   if(doing_script)
     {
     this->SetError("given no value for SCRIPT argument.");
@@ -149,6 +181,11 @@ bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args)
     this->SetError("given no value for CODE argument.");
     return false;
     }
+
+  //Tell the global generator about any installation component names specified.
+  this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+                             ->AddInstallComponent(component.c_str());
+
   return true;
 }
 
@@ -169,15 +206,15 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
 
   cmCommandArgumentsHelper argHelper;
   cmCommandArgumentGroup group;
-  cmCAStringVector genericArgVector     (&argHelper, 0);
-  cmCAStringVector archiveArgVector     (&argHelper, "ARCHIVE", &group);
-  cmCAStringVector libraryArgVector     (&argHelper, "LIBRARY", &group);
-  cmCAStringVector runtimeArgVector     (&argHelper, "RUNTIME", &group);
-  cmCAStringVector frameworkArgVector   (&argHelper, "FRAMEWORK", &group);
-  cmCAStringVector bundleArgVector      (&argHelper, "BUNDLE", &group);
-  cmCAStringVector privateHeaderArgVector(&argHelper,"PRIVATE_HEADER", &group);
-  cmCAStringVector publicHeaderArgVector(&argHelper, "PUBLIC_HEADER", &group);
-  cmCAStringVector resourceArgVector   (&argHelper, "RESOURCE", &group);
+  cmCAStringVector genericArgVector      (&argHelper,0);
+  cmCAStringVector archiveArgVector      (&argHelper,"ARCHIVE",&group);
+  cmCAStringVector libraryArgVector      (&argHelper,"LIBRARY",&group);
+  cmCAStringVector runtimeArgVector      (&argHelper,"RUNTIME",&group);
+  cmCAStringVector frameworkArgVector    (&argHelper,"FRAMEWORK",&group);
+  cmCAStringVector bundleArgVector       (&argHelper,"BUNDLE",&group);
+  cmCAStringVector privateHeaderArgVector(&argHelper,"PRIVATE_HEADER",&group);
+  cmCAStringVector publicHeaderArgVector (&argHelper,"PUBLIC_HEADER",&group);
+  cmCAStringVector resourceArgVector     (&argHelper,"RESOURCE",&group);
   genericArgVector.Follows(0);
   group.Follows(&genericArgVector);
 

+ 12 - 4
Source/cmInstallScriptGenerator.cxx

@@ -18,8 +18,9 @@
 
 //----------------------------------------------------------------------------
 cmInstallScriptGenerator
-::cmInstallScriptGenerator(const char* script, bool code):
-  cmInstallGenerator(0, std::vector<std::string>(), 0),
+::cmInstallScriptGenerator(const char* script, bool code,
+                           const char* component) :
+  cmInstallGenerator(0, std::vector<std::string>(), component),
   Script(script), Code(code)
 {
 }
@@ -33,12 +34,19 @@ cmInstallScriptGenerator
 //----------------------------------------------------------------------------
 void cmInstallScriptGenerator::GenerateScript(std::ostream& os)
 {
+  Indent indent;
+  std::string component_test =
+    this->CreateComponentTest(this->Component.c_str());
+  os << indent << "IF(" << component_test << ")\n";
+
   if(this->Code)
     {
-    os << this->Script << "\n";
+    os << indent.Next() << this->Script << "\n";
     }
   else
     {
-    os << "INCLUDE(\"" << this->Script << "\")\n";
+    os << indent.Next() << "INCLUDE(\"" << this->Script << "\")\n";
     }
+
+  os << indent << "ENDIF(" << component_test << ")\n\n";
 }

+ 2 - 1
Source/cmInstallScriptGenerator.h

@@ -25,7 +25,8 @@
 class cmInstallScriptGenerator: public cmInstallGenerator
 {
 public:
-  cmInstallScriptGenerator(const char* script, bool code = false);
+  cmInstallScriptGenerator(const char* script, bool code,
+    const char* component);
   virtual ~cmInstallScriptGenerator();
 
 protected:

+ 2 - 2
Source/cmLocalGenerator.cxx

@@ -2419,7 +2419,7 @@ cmLocalGenerator
     // Include the user-specified pre-install script for this target.
     if(const char* preinstall = l->second.GetProperty("PRE_INSTALL_SCRIPT"))
       {
-      cmInstallScriptGenerator g(preinstall);
+      cmInstallScriptGenerator g(preinstall, false, 0);
       g.Generate(os, config, configurationTypes);
       }
 
@@ -2472,7 +2472,7 @@ cmLocalGenerator
     // Include the user-specified post-install script for this target.
     if(const char* postinstall = l->second.GetProperty("POST_INSTALL_SCRIPT"))
       {
-      cmInstallScriptGenerator g(postinstall);
+      cmInstallScriptGenerator g(postinstall, false, 0);
       g.Generate(os, config, configurationTypes);
       }
     }

+ 9 - 2
Tests/SimpleInstall/CMakeLists.txt

@@ -251,14 +251,21 @@ ELSE(STAGE2)
   # Test empty directory installation.
   INSTALL(DIRECTORY DESTINATION MyTest/share/empty)
 
-  # Test user-specified install scripts.
+  # Test user-specified install scripts, with and without COMPONENT.
   INSTALL(
     SCRIPT InstallScript1.cmake
     CODE "SET(INSTALL_CODE_DID_RUN 1)"
     SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/InstallScript2.cmake
     )
+  INSTALL(
+    SCRIPT InstallScript3.cmake
+    CODE "SET(INSTALL_CODE_WITH_COMPONENT_DID_RUN 1)"
+    SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/InstallScript4.cmake
+    COMPONENT Development
+    )
   SET_DIRECTORY_PROPERTIES(PROPERTIES
-    ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_INSTALL_PREFIX}/InstallScriptOut.cmake)
+    ADDITIONAL_MAKE_CLEAN_FILES
+    "${CMAKE_INSTALL_PREFIX}/InstallScriptOut.cmake;${CMAKE_INSTALL_PREFIX}/InstallScript4Out.cmake")
 
   SET_TARGET_PROPERTIES(SimpleInstall PROPERTIES OUTPUT_NAME SimpleInstExe)
   # Disable VERSION test until it is implemented in the XCode generator.

+ 12 - 0
Tests/SimpleInstall/InstallScript3.cmake

@@ -0,0 +1,12 @@
+MESSAGE("This is install script 3.")
+SET(INSTALL_SCRIPT_3_DID_RUN 1)
+IF(INSTALL_CODE_WITH_COMPONENT_DID_RUN)
+  MESSAGE(FATAL_ERROR "Install script 3 did not run before install code with component.")
+ENDIF(INSTALL_CODE_WITH_COMPONENT_DID_RUN)
+
+IF(CMAKE_INSTALL_COMPONENT)
+IF(NOT "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Development")
+  MESSAGE("CMAKE_INSTALL_COMPONENT=\"${CMAKE_INSTALL_COMPONENT}\"")
+  MESSAGE(FATAL_ERROR "Install script 3 should only run for \"Development\" INSTALL COMPONENT.")
+ENDIF(NOT "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Development")
+ENDIF(CMAKE_INSTALL_COMPONENT)

+ 22 - 0
Tests/SimpleInstall/InstallScript4.cmake

@@ -0,0 +1,22 @@
+MESSAGE("This is install script 4.")
+IF(INSTALL_SCRIPT_3_DID_RUN)
+  MESSAGE("Install script ordering works.")
+ELSE(INSTALL_SCRIPT_3_DID_RUN)
+  MESSAGE(FATAL_ERROR "Install script 3 did not run before install script 4.")
+ENDIF(INSTALL_SCRIPT_3_DID_RUN)
+IF(INSTALL_CODE_WITH_COMPONENT_DID_RUN)
+  MESSAGE("Install code ordering works.")
+ELSE(INSTALL_CODE_WITH_COMPONENT_DID_RUN)
+  MESSAGE(FATAL_ERROR "Install script 4 did not run after install with component code.")
+ENDIF(INSTALL_CODE_WITH_COMPONENT_DID_RUN)
+
+IF(CMAKE_INSTALL_COMPONENT)
+IF(NOT "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Development")
+  MESSAGE("CMAKE_INSTALL_COMPONENT=\"${CMAKE_INSTALL_COMPONENT}\"")
+  MESSAGE(FATAL_ERROR "Install script 4 should only run for \"Development\" INSTALL COMPONENT.")
+ENDIF(NOT "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Development")
+ENDIF(CMAKE_INSTALL_COMPONENT)
+
+FILE(WRITE "${CMAKE_INSTALL_PREFIX}/MyTest/InstallScript4Out.cmake"
+  "SET(CMAKE_INSTALL_SCRIPT_4_DID_RUN 1)\n"
+  )

+ 9 - 2
Tests/SimpleInstallS2/CMakeLists.txt

@@ -251,14 +251,21 @@ ELSE(STAGE2)
   # Test empty directory installation.
   INSTALL(DIRECTORY DESTINATION MyTest/share/empty)
 
-  # Test user-specified install scripts.
+  # Test user-specified install scripts, with and without COMPONENT.
   INSTALL(
     SCRIPT InstallScript1.cmake
     CODE "SET(INSTALL_CODE_DID_RUN 1)"
     SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/InstallScript2.cmake
     )
+  INSTALL(
+    SCRIPT InstallScript3.cmake
+    CODE "SET(INSTALL_CODE_WITH_COMPONENT_DID_RUN 1)"
+    SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/InstallScript4.cmake
+    COMPONENT Development
+    )
   SET_DIRECTORY_PROPERTIES(PROPERTIES
-    ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_INSTALL_PREFIX}/InstallScriptOut.cmake)
+    ADDITIONAL_MAKE_CLEAN_FILES
+    "${CMAKE_INSTALL_PREFIX}/InstallScriptOut.cmake;${CMAKE_INSTALL_PREFIX}/InstallScript4Out.cmake")
 
   SET_TARGET_PROPERTIES(SimpleInstall PROPERTIES OUTPUT_NAME SimpleInstExe)
   # Disable VERSION test until it is implemented in the XCode generator.

+ 12 - 0
Tests/SimpleInstallS2/InstallScript3.cmake

@@ -0,0 +1,12 @@
+MESSAGE("This is install script 3.")
+SET(INSTALL_SCRIPT_3_DID_RUN 1)
+IF(INSTALL_CODE_WITH_COMPONENT_DID_RUN)
+  MESSAGE(FATAL_ERROR "Install script 3 did not run before install code with component.")
+ENDIF(INSTALL_CODE_WITH_COMPONENT_DID_RUN)
+
+IF(CMAKE_INSTALL_COMPONENT)
+IF(NOT "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Development")
+  MESSAGE("CMAKE_INSTALL_COMPONENT=\"${CMAKE_INSTALL_COMPONENT}\"")
+  MESSAGE(FATAL_ERROR "Install script 3 should only run for \"Development\" INSTALL COMPONENT.")
+ENDIF(NOT "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Development")
+ENDIF(CMAKE_INSTALL_COMPONENT)

+ 22 - 0
Tests/SimpleInstallS2/InstallScript4.cmake

@@ -0,0 +1,22 @@
+MESSAGE("This is install script 4.")
+IF(INSTALL_SCRIPT_3_DID_RUN)
+  MESSAGE("Install script ordering works.")
+ELSE(INSTALL_SCRIPT_3_DID_RUN)
+  MESSAGE(FATAL_ERROR "Install script 3 did not run before install script 4.")
+ENDIF(INSTALL_SCRIPT_3_DID_RUN)
+IF(INSTALL_CODE_WITH_COMPONENT_DID_RUN)
+  MESSAGE("Install code ordering works.")
+ELSE(INSTALL_CODE_WITH_COMPONENT_DID_RUN)
+  MESSAGE(FATAL_ERROR "Install script 4 did not run after install with component code.")
+ENDIF(INSTALL_CODE_WITH_COMPONENT_DID_RUN)
+
+IF(CMAKE_INSTALL_COMPONENT)
+IF(NOT "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Development")
+  MESSAGE("CMAKE_INSTALL_COMPONENT=\"${CMAKE_INSTALL_COMPONENT}\"")
+  MESSAGE(FATAL_ERROR "Install script 4 should only run for \"Development\" INSTALL COMPONENT.")
+ENDIF(NOT "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Development")
+ENDIF(CMAKE_INSTALL_COMPONENT)
+
+FILE(WRITE "${CMAKE_INSTALL_PREFIX}/MyTest/InstallScript4Out.cmake"
+  "SET(CMAKE_INSTALL_SCRIPT_4_DID_RUN 1)\n"
+  )