diff --git a/Source/CPack/cmCPackBundleGenerator.cxx b/Source/CPack/cmCPackBundleGenerator.cxx index 06a050992..af78e7822 100644 --- a/Source/CPack/cmCPackBundleGenerator.cxx +++ b/Source/CPack/cmCPackBundleGenerator.cxx @@ -165,5 +165,10 @@ int cmCPackBundleGenerator::PackageFiles() cmSystemTools::SetPermissions(command_target.str().c_str(), 0777); } - return this->CreateDMG(); + return this->CreateDMG(toplevel, packageFileNames[0]); +} + +bool cmCPackBundleGenerator::SupportsComponentInstallation() const +{ + return false; } diff --git a/Source/CPack/cmCPackBundleGenerator.h b/Source/CPack/cmCPackBundleGenerator.h index 82814b0a5..ed0187dd4 100644 --- a/Source/CPack/cmCPackBundleGenerator.h +++ b/Source/CPack/cmCPackBundleGenerator.h @@ -32,6 +32,7 @@ protected: virtual int InitializeInternal(); virtual const char* GetPackagingInstallPrefix(); int PackageFiles(); + bool SupportsComponentInstallation() const; std::string InstallPrefix; }; diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx index e9ce76c13..83b6b64d4 100644 --- a/Source/CPack/cmCPackDragNDropGenerator.cxx +++ b/Source/CPack/cmCPackDragNDropGenerator.cxx @@ -51,6 +51,8 @@ static const char* SLASTREnglish = //---------------------------------------------------------------------- cmCPackDragNDropGenerator::cmCPackDragNDropGenerator() { + // default to one package file for components + this->componentPackageMethod = ONE_PACKAGE; } //---------------------------------------------------------------------- @@ -106,8 +108,57 @@ const char* cmCPackDragNDropGenerator::GetOutputExtension() //---------------------------------------------------------------------- int cmCPackDragNDropGenerator::PackageFiles() { + // gather which directories to make dmg files for + // multiple directories occur if packaging components or groups separately - return this->CreateDMG(); + // monolith + if(this->Components.empty()) + { + return this->CreateDMG(toplevel, packageFileNames[0]); + } + + // component install + std::vector package_files; + + std::map::iterator compIt; + for (compIt=this->Components.begin(); + compIt!=this->Components.end(); ++compIt ) + { + std::string name = GetComponentInstallDirNameSuffix(compIt->first); + package_files.push_back(name); + } + std::sort(package_files.begin(), package_files.end()); + package_files.erase(std::unique(package_files.begin(), + package_files.end()), + package_files.end()); + + + // loop to create dmg files + packageFileNames.clear(); + for(size_t i=0; iGetOption("CPACK_PACKAGE_FILE_NAME"); + } + else + { + full_package_name += package_files[i]; + } + full_package_name += std::string(GetOutputExtension()); + packageFileNames.push_back(full_package_name); + + std::string src_dir = toplevel; + src_dir += "/"; + src_dir += package_files[i]; + + if(0 == this->CreateDMG(src_dir, full_package_name)) + { + return 0; + } + } + return 1; } //---------------------------------------------------------------------- @@ -159,10 +210,11 @@ bool cmCPackDragNDropGenerator::RunCommand(cmOStringStream& command, } //---------------------------------------------------------------------- -int cmCPackDragNDropGenerator::CreateDMG() +int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, + const std::string& output_file) { // Get optional arguments ... - const std::string cpack_package_icon = this->GetOption("CPACK_PACKAGE_ICON") + const std::string cpack_package_icon = this->GetOption("CPACK_PACKAGE_ICON") ? this->GetOption("CPACK_PACKAGE_ICON") : ""; const std::string cpack_dmg_volume_name = @@ -197,7 +249,7 @@ int cmCPackDragNDropGenerator::CreateDMG() // The staging directory contains everything that will end-up inside the // final disk image ... cmOStringStream staging; - staging << toplevel; + staging << src_dir; // Add a symlink to /Applications so users can drag-and-drop the bundle // into it @@ -472,7 +524,7 @@ int cmCPackDragNDropGenerator::CreateDMG() final_image_command << cpack_dmg_format; final_image_command << " -imagekey"; final_image_command << " zlib-level=9"; - final_image_command << " -o \"" << packageFileNames[0] << "\""; + final_image_command << " -o \"" << output_file << "\""; if(!this->RunCommand(final_image_command)) { @@ -485,3 +537,47 @@ int cmCPackDragNDropGenerator::CreateDMG() return 1; } + +bool cmCPackDragNDropGenerator::SupportsComponentInstallation() const +{ + return true; +} + +std::string +cmCPackDragNDropGenerator::GetComponentInstallDirNameSuffix( + const std::string& componentName) +{ + // we want to group components together that go in the same dmg package + std::string package_file_name = this->GetOption("CPACK_PACKAGE_FILE_NAME"); + + // we have 3 mutually exclusive modes to work in + // 1. all components in one package + // 2. each group goes in its own package with left over + // components in their own package + // 3. ignore groups - if grouping is defined, it is ignored + // and each component goes in its own package + + if(this->componentPackageMethod == ONE_PACKAGE) + { + return "ALL_IN_ONE"; + } + + if(this->componentPackageMethod == ONE_PACKAGE_PER_GROUP) + { + // We have to find the name of the COMPONENT GROUP + // the current COMPONENT belongs to. + std::string groupVar = "CPACK_COMPONENT_" + + cmSystemTools::UpperCase(componentName) + "_GROUP"; + const char* _groupName = GetOption(groupVar.c_str()); + if (_groupName) + { + std::string groupName = _groupName; + + groupName = GetComponentPackageFileName(package_file_name, + groupName, true); + return groupName; + } + } + + return GetComponentPackageFileName(package_file_name, componentName, false); +} diff --git a/Source/CPack/cmCPackDragNDropGenerator.h b/Source/CPack/cmCPackDragNDropGenerator.h index dcef7fb28..808c61886 100644 --- a/Source/CPack/cmCPackDragNDropGenerator.h +++ b/Source/CPack/cmCPackDragNDropGenerator.h @@ -30,11 +30,16 @@ protected: virtual int InitializeInternal(); virtual const char* GetOutputExtension(); int PackageFiles(); + bool SupportsComponentInstallation() const; + bool CopyFile(cmOStringStream& source, cmOStringStream& target); bool RunCommand(cmOStringStream& command, std::string* output = 0); - int CreateDMG(); + std::string + GetComponentInstallDirNameSuffix(const std::string& componentName); + + int CreateDMG(const std::string& src_dir, const std::string& output_file); std::string InstallPrefix; }; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index ea6a416b7..157814e05 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -566,6 +566,9 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ set(CPackRun_CPackCommand "-DCPackCommand=${CMAKE_CPACK_COMMAND}") # set up list of CPack generators list(APPEND GENLST "ZIP") + if(APPLE) + list(APPEND GENLST "DragNDrop") + endif(APPLE) if (CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT CMAKE_CURRENT_BINARY_DIR MATCHES ".* .*") find_program(RPMBUILD NAMES rpmbuild) endif(CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT CMAKE_CURRENT_BINARY_DIR MATCHES ".* .*") diff --git a/Tests/CPackComponentsForAll/MyLibCPackConfig-OnePackPerGroup.cmake.in b/Tests/CPackComponentsForAll/MyLibCPackConfig-OnePackPerGroup.cmake.in index 7b665b6df..1e1a410ab 100644 --- a/Tests/CPackComponentsForAll/MyLibCPackConfig-OnePackPerGroup.cmake.in +++ b/Tests/CPackComponentsForAll/MyLibCPackConfig-OnePackPerGroup.cmake.in @@ -13,10 +13,14 @@ if(CPACK_GENERATOR MATCHES "DEB") set(CPACK_DEB_COMPONENT_INSTALL "ON") endif(CPACK_GENERATOR MATCHES "DEB") +if(CPACK_GENERATOR MATCHES "DragNDrop") + set(CPACK_COMPONENTS_GROUPING "ONE_PER_GROUP") +endif(CPACK_GENERATOR MATCHES "DragNDrop") + # # Choose grouping way # #set(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE) #set(CPACK_COMPONENTS_GROUPING) #set(CPACK_COMPONENTS_IGNORE_GROUPS) -#set(CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE) \ No newline at end of file +#set(CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE) diff --git a/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake index 77a1979a6..e2d343d9f 100644 --- a/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake +++ b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake @@ -69,6 +69,19 @@ elseif (CPackGen MATCHES "DEB") endif () endif() +if(CPackGen MATCHES "DragNDrop") + set(expected_file_mask "${CPackComponentsForAll_BINARY_DIR}/MyLib-*.dmg") + if (${CPackComponentWay} STREQUAL "default") + set(expected_count 1) + elseif (${CPackComponentWay} STREQUAL "OnePackPerGroup") + set(expected_count 3) + elseif (${CPackComponentWay} STREQUAL "IgnoreGroup") + set(expected_count 4) + elseif (${CPackComponentWay} STREQUAL "AllInOne") + set(expected_count 1) + endif () +endif(CPackGen MATCHES "DragNDrop") + # clean-up previously CPack generated files if(expected_file_mask) file(GLOB expected_file "${expected_file_mask}")