diff options
author | Brad King <brad.king@kitware.com> | 2015-11-13 13:53:40 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2015-11-13 13:53:40 (GMT) |
commit | 9feb24e514f3c0f6b9a9705e17cf1917152df977 (patch) | |
tree | 8e9d592405399bc81d5ef33f25e1fd2c12cbe8a1 | |
parent | bbf1757dfa4804c0d8ac311e6645084982831a50 (diff) | |
parent | 4bca9401269878d2f3b0465377f0fb8bce87c734 (diff) | |
download | CMake-9feb24e514f3c0f6b9a9705e17cf1917152df977.zip CMake-9feb24e514f3c0f6b9a9705e17cf1917152df977.tar.gz CMake-9feb24e514f3c0f6b9a9705e17cf1917152df977.tar.bz2 |
Merge topic 'better_looking_mac_package'
4bca9401 Improve appearance of CMake .dmg package on OS X
c4b9ee18 CPack/DragNDrop: Update documentation to include new variables
167a4655 CPack/DragNDrop: Optionally run an AppleScript when making a package
9c1dfbfd CPack/DragNDrop: Place the background image file in a hidden folder
47302038 CPack/DragNDrop: Use source file extension for background image
-rw-r--r-- | CMakeCPackOptions.cmake.in | 7 | ||||
-rw-r--r-- | Help/release/dev/better-looking-mac-packages.rst | 8 | ||||
-rw-r--r-- | Modules/CPackDMG.cmake | 20 | ||||
-rw-r--r-- | Packaging/CMakeDMGBackground.tif | bin | 0 -> 95690 bytes | |||
-rw-r--r-- | Packaging/CMakeDMGSetup.scpt | 42 | ||||
-rw-r--r-- | Source/CPack/cmCPackDragNDropGenerator.cxx | 120 | ||||
-rw-r--r-- | Source/CPack/cmCPackDragNDropGenerator.h | 1 |
7 files changed, 172 insertions, 26 deletions
diff --git a/CMakeCPackOptions.cmake.in b/CMakeCPackOptions.cmake.in index b6013ef..ae00653 100644 --- a/CMakeCPackOptions.cmake.in +++ b/CMakeCPackOptions.cmake.in @@ -183,6 +183,13 @@ if("${CPACK_GENERATOR}" STREQUAL "PackageMaker") endif() endif() +if("${CPACK_GENERATOR}" STREQUAL "DragNDrop") + set(CPACK_DMG_BACKGROUND_IMAGE + "@CMake_SOURCE_DIR@/Packaging/CMakeDMGBackground.tif") + set(CPACK_DMG_DS_STORE_SETUP_SCRIPT + "@CMake_SOURCE_DIR@/Packaging/CMakeDMGSetup.scpt") +endif() + if("${CPACK_GENERATOR}" STREQUAL "WIX") # Reset CPACK_PACKAGE_VERSION to deal with WiX restriction. # But the file names still use the full CMake_VERSION value: diff --git a/Help/release/dev/better-looking-mac-packages.rst b/Help/release/dev/better-looking-mac-packages.rst new file mode 100644 index 0000000..ef1b8e8 --- /dev/null +++ b/Help/release/dev/better-looking-mac-packages.rst @@ -0,0 +1,8 @@ +better-looking-mac-packages +--------------------------- + +* The :module:`CPackDMG` module learned new variable to specify AppleScript + file run to customize appearance of ``DragNDrop`` installer folder, + including background image setting using supplied PNG or multi-resolution + TIFF file. See the :variable:`CPACK_DMG_DS_STORE_SETUP_SCRIPT` and + :variable:`CPACK_DMG_BACKGROUND_IMAGE` variables. diff --git a/Modules/CPackDMG.cmake b/Modules/CPackDMG.cmake index 37d7352..6b5af7e 100644 --- a/Modules/CPackDMG.cmake +++ b/Modules/CPackDMG.cmake @@ -26,15 +26,25 @@ # Path to a custom DS_Store file. This .DS_Store file e.g. can be used to # specify the Finder window position/geometry and layout (such as hidden # toolbars, placement of the icons etc.). This file has to be generated by -# the Finder (either manually or through OSA-script) using a normal folder +# the Finder (either manually or through AppleScript) using a normal folder # from which the .DS_Store file can then be extracted. # +# .. variable:: CPACK_DMG_DS_STORE_SETUP_SCRIPT +# +# Path to a custom AppleScript file. This AppleScript is used to generate +# a .DS_Store file which specifies the Finder window position/geometry and +# layout (such as hidden toolbars, placement of the icons etc.). +# By specifying a custom AppleScript there is no need to use +# CPACK_DMG_DS_STORE, as the .DS_Store that is generated by the AppleScript +# will be packaged. +# # .. variable:: CPACK_DMG_BACKGROUND_IMAGE # -# Path to a background image file. This file will be used as the background -# for the Finder Window when the disk image is opened. By default no -# background image is set. The background image is applied after applying the -# custom .DS_Store file. +# Path to an image file to be used as the background. This file will be +# copied to .background/background.<ext>, where ext is the original image file +# extension. The background image is installed into the image before +# CPACK_DMG_DS_STORE_SETUP_SCRIPT is executed or CPACK_DMG_DS_STORE is +# installed. By default no background image is set. # # .. variable:: CPACK_DMG_SLA_DIR # diff --git a/Packaging/CMakeDMGBackground.tif b/Packaging/CMakeDMGBackground.tif Binary files differnew file mode 100644 index 0000000..91c4b13 --- /dev/null +++ b/Packaging/CMakeDMGBackground.tif diff --git a/Packaging/CMakeDMGSetup.scpt b/Packaging/CMakeDMGSetup.scpt new file mode 100644 index 0000000..c7ddcfb --- /dev/null +++ b/Packaging/CMakeDMGSetup.scpt @@ -0,0 +1,42 @@ +on run argv + set image_name to item 1 of argv + + tell application "Finder" + tell disk image_name + + -- open the image the first time and save a DS_Store with just + -- background and icon setup + open + set current view of container window to icon view + set theViewOptions to the icon view options of container window + set background picture of theViewOptions to file ".background:background.tif" + set arrangement of theViewOptions to not arranged + set icon size of theViewOptions to 128 + delay 1 + close + + -- next setup the position of the app and Applications symlink + -- plus hide all the window decoration + open + update without registering applications + tell container window + set sidebar width to 0 + set statusbar visible to false + set toolbar visible to false + set the bounds to { 400, 100, 900, 465 } + set position of item "CMake.app" to { 133, 200 } + set position of item "Applications" to { 378, 200 } + end tell + update without registering applications + delay 1 + close + + -- one last open and close so you can see everything looks correct + open + delay 5 + close + + end tell + delay 1 +end tell +end run diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx index 208a64c..7a93fc6 100644 --- a/Source/CPack/cmCPackDragNDropGenerator.cxx +++ b/Source/CPack/cmCPackDragNDropGenerator.cxx @@ -271,6 +271,28 @@ bool cmCPackDragNDropGenerator::CopyFile(std::ostringstream& source, } //---------------------------------------------------------------------- +bool cmCPackDragNDropGenerator::CreateEmptyFile(std::ostringstream& target, + size_t size) +{ + cmsys::ofstream fout(target.str().c_str(), + std::ios::out | std::ios::binary); + if(!fout) + { + return false; + } + else + { + // Seek to desired size - 1 byte + fout.seekp(size - 1, std::ios_base::beg); + char byte = 0; + // Write one byte to ensure file grows + fout.write(&byte, 1); + } + + return true; +} + +//---------------------------------------------------------------------- bool cmCPackDragNDropGenerator::RunCommand(std::ostringstream& command, std::string* output) { @@ -331,6 +353,10 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, this->GetOption("CPACK_DMG_LANGUAGES") ? this->GetOption("CPACK_DMG_LANGUAGES") : ""; + const std::string cpack_dmg_ds_store_setup_script = + this->GetOption("CPACK_DMG_DS_STORE_SETUP_SCRIPT") + ? this->GetOption("CPACK_DMG_DS_STORE_SETUP_SCRIPT") : ""; + // only put license on dmg if is user provided if(!cpack_license_file.empty() && cpack_license_file.find("CPack.GenericLicense.txt") != std::string::npos) @@ -399,13 +425,18 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, } // Optionally add a custom background image ... + // Make sure the background file type is the same as the custom image + // and that the file is hidden so it doesn't show up. if(!cpack_dmg_background_image.empty()) { + const std::string extension = + cmSystemTools::GetFilenameLastExtension(cpack_dmg_background_image); std::ostringstream package_background_source; package_background_source << cpack_dmg_background_image; std::ostringstream package_background_destination; - package_background_destination << staging.str() << "/background.png"; + package_background_destination << staging.str() + << "/.background/background" << extension; if(!this->CopyFile(package_background_source, package_background_destination)) @@ -417,18 +448,22 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, return 0; } + } - std::ostringstream temp_background_hiding_command; - temp_background_hiding_command << this->GetOption("CPACK_COMMAND_SETFILE"); - temp_background_hiding_command << " -a V \""; - temp_background_hiding_command << package_background_destination.str(); - temp_background_hiding_command << "\""; + bool remount_image = !cpack_package_icon.empty() || + !cpack_dmg_ds_store_setup_script.empty(); - if(!this->RunCommand(temp_background_hiding_command)) + // Create 1 MB dummy padding file in staging area when we need to remount + // image, so we have enough space for storing changes ... + if(remount_image) + { + std::ostringstream dummy_padding; + dummy_padding << staging.str() << "/.dummy-padding-file"; + if(!this->CreateEmptyFile(dummy_padding, 1048576)) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Error setting attributes on disk volume background image." - << std::endl); + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error creating dummy padding file." + << std::endl); return 0; } @@ -457,10 +492,11 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, return 0; } - // Optionally set the custom icon flag for the image ... - if(!cpack_package_icon.empty()) + if(remount_image) { - std::ostringstream temp_mount; + // Store that we have a failure so that we always unmount the image + // before we exit. + bool had_error = false; std::ostringstream attach_command; attach_command << this->GetOption("CPACK_COMMAND_HDIUTIL"); @@ -479,20 +515,57 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, cmsys::RegularExpression mountpoint_regex(".*(/Volumes/[^\n]+)\n.*"); mountpoint_regex.find(attach_output.c_str()); + std::ostringstream temp_mount; temp_mount << mountpoint_regex.match(1); - std::ostringstream setfile_command; - setfile_command << this->GetOption("CPACK_COMMAND_SETFILE"); - setfile_command << " -a C"; - setfile_command << " \"" << temp_mount.str() << "\""; - - if(!this->RunCommand(setfile_command)) + // Remove dummy padding file so we have enough space on RW image ... + std::ostringstream dummy_padding; + dummy_padding << temp_mount.str() << "/.dummy-padding-file"; + if(!cmSystemTools::RemoveFile(dummy_padding.str())) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "Error assigning custom icon to temporary disk image." + "Error removing dummy padding file." << std::endl); - return 0; + had_error = true; + } + + // Optionally set the custom icon flag for the image ... + if(!had_error && !cpack_package_icon.empty()) + { + std::ostringstream setfile_command; + setfile_command << this->GetOption("CPACK_COMMAND_SETFILE"); + setfile_command << " -a C"; + setfile_command << " \"" << temp_mount.str() << "\""; + + if(!this->RunCommand(setfile_command)) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error assigning custom icon to temporary disk image." + << std::endl); + + had_error = true; + } + } + + // Optionally we can execute a custom apple script to generate + // the .DS_Store for the volume folder ... + if(!had_error && !cpack_dmg_ds_store_setup_script.empty()) + { + std::ostringstream setup_script_command; + setup_script_command << "osascript" + << " \"" << cpack_dmg_ds_store_setup_script << "\"" + << " \"" << cpack_dmg_volume_name << "\""; + std::string error; + if(!this->RunCommand(setup_script_command, &error)) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error executing custom script on disk image." << std::endl + << error + << std::endl); + + had_error = true; + } } std::ostringstream detach_command; @@ -508,6 +581,11 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, return 0; } + + if(had_error) + { + return 0; + } } if(!cpack_license_file.empty() || !slaDirectory.empty()) diff --git a/Source/CPack/cmCPackDragNDropGenerator.h b/Source/CPack/cmCPackDragNDropGenerator.h index 12db469..53d38c4 100644 --- a/Source/CPack/cmCPackDragNDropGenerator.h +++ b/Source/CPack/cmCPackDragNDropGenerator.h @@ -36,6 +36,7 @@ protected: bool CopyFile(std::ostringstream& source, std::ostringstream& target); + bool CreateEmptyFile(std::ostringstream& target, size_t size); bool RunCommand(std::ostringstream& command, std::string* output = 0); std::string |