From c8e832dcf5d1477192e19bf521f684c953d7751d Mon Sep 17 00:00:00 2001 From: David Cole Date: Mon, 15 Oct 2007 07:08:15 -0400 Subject: [PATCH] BUG: Fix #5868 - add COMPONENT handling to the SCRIPT and CODE signatures of the INSTALL command. --- Source/cmInstallCommand.cxx | 59 ++++++++++++++++++---- Source/cmInstallScriptGenerator.cxx | 16 ++++-- Source/cmInstallScriptGenerator.h | 3 +- Source/cmLocalGenerator.cxx | 4 +- Tests/SimpleInstall/CMakeLists.txt | 11 +++- Tests/SimpleInstall/InstallScript3.cmake | 12 +++++ Tests/SimpleInstall/InstallScript4.cmake | 22 ++++++++ Tests/SimpleInstallS2/CMakeLists.txt | 11 +++- Tests/SimpleInstallS2/InstallScript3.cmake | 12 +++++ Tests/SimpleInstallS2/InstallScript4.cmake | 22 ++++++++ 10 files changed, 150 insertions(+), 22 deletions(-) create mode 100644 Tests/SimpleInstall/InstallScript3.cmake create mode 100644 Tests/SimpleInstall/InstallScript4.cmake create mode 100644 Tests/SimpleInstallS2/InstallScript3.cmake create mode 100644 Tests/SimpleInstallS2/InstallScript4.cmake diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index 6696629fc..6a645da1d 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -99,8 +99,34 @@ bool cmInstallCommand::InitialPass(std::vector const& args) //---------------------------------------------------------------------------- bool cmInstallCommand::HandleScriptMode(std::vector 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 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 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 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 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); diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx index ca4cbbb02..b7e63de4d 100644 --- a/Source/cmInstallScriptGenerator.cxx +++ b/Source/cmInstallScriptGenerator.cxx @@ -18,8 +18,9 @@ //---------------------------------------------------------------------------- cmInstallScriptGenerator -::cmInstallScriptGenerator(const char* script, bool code): - cmInstallGenerator(0, std::vector(), 0), +::cmInstallScriptGenerator(const char* script, bool code, + const char* component) : + cmInstallGenerator(0, std::vector(), 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"; } diff --git a/Source/cmInstallScriptGenerator.h b/Source/cmInstallScriptGenerator.h index 2e9461a58..bbe2677e3 100644 --- a/Source/cmInstallScriptGenerator.h +++ b/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: diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 3c20cf89b..acaaad50b 100644 --- a/Source/cmLocalGenerator.cxx +++ b/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); } } diff --git a/Tests/SimpleInstall/CMakeLists.txt b/Tests/SimpleInstall/CMakeLists.txt index 0d3b8078b..e1de4bd07 100644 --- a/Tests/SimpleInstall/CMakeLists.txt +++ b/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. diff --git a/Tests/SimpleInstall/InstallScript3.cmake b/Tests/SimpleInstall/InstallScript3.cmake new file mode 100644 index 000000000..b1aecd4c2 --- /dev/null +++ b/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) diff --git a/Tests/SimpleInstall/InstallScript4.cmake b/Tests/SimpleInstall/InstallScript4.cmake new file mode 100644 index 000000000..0ffea4bc8 --- /dev/null +++ b/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" + ) diff --git a/Tests/SimpleInstallS2/CMakeLists.txt b/Tests/SimpleInstallS2/CMakeLists.txt index 0d3b8078b..e1de4bd07 100644 --- a/Tests/SimpleInstallS2/CMakeLists.txt +++ b/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. diff --git a/Tests/SimpleInstallS2/InstallScript3.cmake b/Tests/SimpleInstallS2/InstallScript3.cmake new file mode 100644 index 000000000..b1aecd4c2 --- /dev/null +++ b/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) diff --git a/Tests/SimpleInstallS2/InstallScript4.cmake b/Tests/SimpleInstallS2/InstallScript4.cmake new file mode 100644 index 000000000..0ffea4bc8 --- /dev/null +++ b/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" + )