summaryrefslogtreecommitdiffstats
path: root/Source/CPack
diff options
context:
space:
mode:
Diffstat (limited to 'Source/CPack')
-rw-r--r--Source/CPack/IFW/cmCPackIFWGenerator.cxx1
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.cxx1
-rw-r--r--Source/CPack/WiX/cmWIXPatch.cxx32
-rw-r--r--Source/CPack/WiX/cmWIXPatch.h3
-rw-r--r--Source/CPack/WiX/cmWIXPatchParser.cxx52
-rw-r--r--Source/CPack/WiX/cmWIXPatchParser.h29
-rw-r--r--Source/CPack/WiX/cmWIXSourceWriter.cxx19
-rw-r--r--Source/CPack/WiX/cmWIXSourceWriter.h2
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.cxx1
-rw-r--r--Source/CPack/cmCPackCygwinBinaryGenerator.cxx1
-rw-r--r--Source/CPack/cmCPackCygwinSourceGenerator.cxx1
-rw-r--r--Source/CPack/cmCPackDebGenerator.cxx7
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.cxx481
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.h12
-rw-r--r--Source/CPack/cmCPackGenerator.cxx4
-rw-r--r--Source/CPack/cmCPackNSISGenerator.cxx23
-rw-r--r--Source/CPack/cmCPackOSXX11Generator.cxx1
-rw-r--r--Source/CPack/cmCPackPackageMakerGenerator.cxx1
-rw-r--r--Source/CPack/cmCPackSTGZGenerator.cxx1
-rw-r--r--Source/CPack/cpack.cxx4
20 files changed, 583 insertions, 93 deletions
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
index 43d34ee..4eb23c1 100644
--- a/Source/CPack/IFW/cmCPackIFWGenerator.cxx
+++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
@@ -24,7 +24,6 @@
#include <cmsys/RegularExpression.hxx>
#include <cmGlobalGenerator.h>
-#include <cmLocalGenerator.h>
#include <cmSystemTools.h>
#include <cmMakefile.h>
#include <cmGeneratedFileStream.h>
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index 6f25e50..d5246db 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -482,6 +482,7 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
featureDefinitions.BeginElement("Feature");
featureDefinitions.AddAttribute("Id", "ProductFeature");
featureDefinitions.AddAttribute("Display", "expand");
+ featureDefinitions.AddAttribute("Absent", "disallow");
featureDefinitions.AddAttribute("ConfigurableDirectory", "INSTALL_ROOT");
std::string cpackPackageName;
diff --git a/Source/CPack/WiX/cmWIXPatch.cxx b/Source/CPack/WiX/cmWIXPatch.cxx
index 5a8dc63..471c3a4 100644
--- a/Source/CPack/WiX/cmWIXPatch.cxx
+++ b/Source/CPack/WiX/cmWIXPatch.cxx
@@ -33,13 +33,30 @@ void cmWIXPatch::ApplyFragment(
if(i == Fragments.end()) return;
const cmWIXPatchElement& fragment = i->second;
+
+ this->ApplyElementChildren(fragment, writer);
+
+ Fragments.erase(i);
+}
+
+void cmWIXPatch::ApplyElementChildren(
+ const cmWIXPatchElement& element, cmWIXSourceWriter& writer)
+{
for(cmWIXPatchElement::child_list_t::const_iterator
- j = fragment.children.begin(); j != fragment.children.end(); ++j)
+ j = element.children.begin(); j != element.children.end(); ++j)
+ {
+ cmWIXPatchNode *node = *j;
+
+ switch(node->type())
{
- ApplyElement(**j, writer);
+ case cmWIXPatchNode::ELEMENT:
+ ApplyElement(dynamic_cast<const cmWIXPatchElement&>(*node), writer);
+ break;
+ case cmWIXPatchNode::TEXT:
+ writer.AddTextNode(dynamic_cast<const cmWIXPatchText&>(*node).text);
+ break;
}
-
- Fragments.erase(i);
+ }
}
void cmWIXPatch::ApplyElement(
@@ -53,16 +70,11 @@ void cmWIXPatch::ApplyElement(
writer.AddAttribute(i->first, i->second);
}
- for(cmWIXPatchElement::child_list_t::const_iterator
- i = element.children.begin(); i != element.children.end(); ++i)
- {
- ApplyElement(**i, writer);
- }
+ this->ApplyElementChildren(element, writer);
writer.EndElement(element.name);
}
-
bool cmWIXPatch::CheckForUnappliedFragments()
{
std::string fragmentList;
diff --git a/Source/CPack/WiX/cmWIXPatch.h b/Source/CPack/WiX/cmWIXPatch.h
index 7b7b2f1..d53fcb4 100644
--- a/Source/CPack/WiX/cmWIXPatch.h
+++ b/Source/CPack/WiX/cmWIXPatch.h
@@ -33,6 +33,9 @@ public:
bool CheckForUnappliedFragments();
private:
+ void ApplyElementChildren(const cmWIXPatchElement& element,
+ cmWIXSourceWriter& writer);
+
void ApplyElement(const cmWIXPatchElement& element,
cmWIXSourceWriter& writer);
diff --git a/Source/CPack/WiX/cmWIXPatchParser.cxx b/Source/CPack/WiX/cmWIXPatchParser.cxx
index e066c28..14c5413 100644
--- a/Source/CPack/WiX/cmWIXPatchParser.cxx
+++ b/Source/CPack/WiX/cmWIXPatchParser.cxx
@@ -16,6 +16,21 @@
#include <cm_expat.h>
+cmWIXPatchNode::Type cmWIXPatchText::type()
+{
+ return cmWIXPatchNode::TEXT;
+}
+
+cmWIXPatchNode::Type cmWIXPatchElement::type()
+{
+ return cmWIXPatchNode::ELEMENT;
+}
+
+cmWIXPatchNode::~cmWIXPatchNode()
+{
+
+}
+
cmWIXPatchElement::~cmWIXPatchElement()
{
for(child_list_t::iterator i = children.begin(); i != children.end(); ++i)
@@ -63,20 +78,20 @@ void cmWIXPatchParser::StartElement(const std::string& name, const char **atts)
{
cmWIXPatchElement &parent = *ElementStack.back();
- parent.children.resize(parent.children.size() + 1);
- cmWIXPatchElement*& currentElement = parent.children.back();
- currentElement = new cmWIXPatchElement;
- currentElement->name = name;
+ cmWIXPatchElement *element = new cmWIXPatchElement;
+ parent.children.push_back(element);
+
+ element->name = name;
for(size_t i = 0; atts[i]; i += 2)
{
std::string key = atts[i];
std::string value = atts[i+1];
- currentElement->attributes[key] = value;
+ element->attributes[key] = value;
}
- ElementStack.push_back(currentElement);
+ ElementStack.push_back(element);
}
}
@@ -117,11 +132,34 @@ void cmWIXPatchParser::EndElement(const std::string& name)
}
else
{
- ElementStack.pop_back();
+ ElementStack.pop_back();
}
}
}
+void cmWIXPatchParser::CharacterDataHandler(const char* data, int length)
+{
+ const char* whitespace = "\x20\x09\x0d\x0a";
+
+ if(State == INSIDE_FRAGMENT)
+ {
+ cmWIXPatchElement &parent = *ElementStack.back();
+
+ std::string text(data, length);
+
+ std::string::size_type first = text.find_first_not_of(whitespace);
+ std::string::size_type last = text.find_last_not_of(whitespace);
+
+ if(first != std::string::npos && last != std::string::npos)
+ {
+ cmWIXPatchText *text_node = new cmWIXPatchText;
+ text_node->text = text.substr(first, last - first + 1);
+
+ parent.children.push_back(text_node);
+ }
+ }
+}
+
void cmWIXPatchParser::ReportError(int line, int column, const char* msg)
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
diff --git a/Source/CPack/WiX/cmWIXPatchParser.h b/Source/CPack/WiX/cmWIXPatchParser.h
index acfb4c0..acaeae3 100644
--- a/Source/CPack/WiX/cmWIXPatchParser.h
+++ b/Source/CPack/WiX/cmWIXPatchParser.h
@@ -20,11 +20,33 @@
#include <map>
#include <list>
-struct cmWIXPatchElement
+struct cmWIXPatchNode
{
+ enum Type
+ {
+ TEXT,
+ ELEMENT
+ };
+
+ virtual ~cmWIXPatchNode();
+
+ virtual Type type() = 0;
+};
+
+struct cmWIXPatchText : public cmWIXPatchNode
+{
+ virtual Type type();
+
+ std::string text;
+};
+
+struct cmWIXPatchElement : cmWIXPatchNode
+{
+ virtual Type type();
+
~cmWIXPatchElement();
- typedef std::list<cmWIXPatchElement*> child_list_t;
+ typedef std::list<cmWIXPatchNode*> child_list_t;
typedef std::map<std::string, std::string> attributes_t;
std::string name;
@@ -48,6 +70,9 @@ private:
void StartFragment(const char **attributes);
virtual void EndElement(const std::string& name);
+
+ virtual void CharacterDataHandler(const char* data, int length);
+
virtual void ReportError(int line, int column, const char* msg);
void ReportValidationError(std::string const& message);
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.cxx b/Source/CPack/WiX/cmWIXSourceWriter.cxx
index 8d38e9b..63acb27 100644
--- a/Source/CPack/WiX/cmWIXSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXSourceWriter.cxx
@@ -102,6 +102,25 @@ void cmWIXSourceWriter::EndElement(std::string const& name)
State = DEFAULT;
}
+void cmWIXSourceWriter::AddTextNode(std::string const& text)
+{
+ if(State == BEGIN)
+ {
+ File << ">";
+ }
+
+ if(Elements.empty())
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "can not add text without open WiX element in '" <<
+ SourceFilename << "'" << std::endl);
+ return;
+ }
+
+ File << this->EscapeAttributeValue(text);
+ State = DEFAULT;
+}
+
void cmWIXSourceWriter::AddProcessingInstruction(
std::string const& target, std::string const& content)
{
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.h b/Source/CPack/WiX/cmWIXSourceWriter.h
index 3b9999c..9e303f0 100644
--- a/Source/CPack/WiX/cmWIXSourceWriter.h
+++ b/Source/CPack/WiX/cmWIXSourceWriter.h
@@ -34,6 +34,8 @@ public:
void EndElement(std::string const& name);
+ void AddTextNode(std::string const& text);
+
void AddProcessingInstruction(
std::string const& target, std::string const& content);
diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx
index 70de757..db985db 100644
--- a/Source/CPack/cmCPackArchiveGenerator.cxx
+++ b/Source/CPack/cmCPackArchiveGenerator.cxx
@@ -14,7 +14,6 @@
#include "cmake.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmSystemTools.h"
#include "cmMakefile.h"
#include "cmGeneratedFileStream.h"
diff --git a/Source/CPack/cmCPackCygwinBinaryGenerator.cxx b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx
index 6605f16..1f905c0 100644
--- a/Source/CPack/cmCPackCygwinBinaryGenerator.cxx
+++ b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx
@@ -14,7 +14,6 @@
#include "cmake.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmSystemTools.h"
#include "cmMakefile.h"
#include "cmGeneratedFileStream.h"
diff --git a/Source/CPack/cmCPackCygwinSourceGenerator.cxx b/Source/CPack/cmCPackCygwinSourceGenerator.cxx
index f1e8539..f5cb53c 100644
--- a/Source/CPack/cmCPackCygwinSourceGenerator.cxx
+++ b/Source/CPack/cmCPackCygwinSourceGenerator.cxx
@@ -14,7 +14,6 @@
#include "cmake.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmSystemTools.h"
#include "cmMakefile.h"
#include "cmGeneratedFileStream.h"
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index 04efb71..13c8d8f 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -339,6 +339,9 @@ int cmCPackDebGenerator::createDeb()
this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PROVIDES");
const char* debian_pkg_replaces =
this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_REPLACES");
+ const char* debian_pkg_source =
+ this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SOURCE");
+
{ // the scope is needed for cmGeneratedFileStream
cmGeneratedFileStream out(ctlfilename.c_str());
@@ -347,6 +350,10 @@ int cmCPackDebGenerator::createDeb()
out << "Section: " << debian_pkg_section << "\n";
out << "Priority: " << debian_pkg_priority << "\n";
out << "Architecture: " << debian_pkg_arch << "\n";
+ if(debian_pkg_source && *debian_pkg_source)
+ {
+ out << "Source: " << debian_pkg_source << "\n";
+ }
if(debian_pkg_dep && *debian_pkg_dep)
{
out << "Depends: " << debian_pkg_dep << "\n";
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index 4c400d9..b5df2d0 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -18,6 +18,24 @@
#include <cmsys/RegularExpression.hxx>
#include <cmsys/FStream.hxx>
+#include <iomanip>
+
+#include <CoreFoundation/CFBase.h>
+#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CFLocale.h>
+
+// The carbon framework is deprecated, but the Region codes it supplies are
+// needed for the LPic data structure used for generating multi-lingual SLAs.
+// There does not seem to be a replacement API for these region codes.
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wdeprecated-declarations"
+#endif
+#include <Carbon/Carbon.h>
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#endif
+
static const char* SLAHeader =
"data 'LPic' (5000) {\n"
" $\"0002 0011 0003 0001 0000 0000 0002 0000\"\n"
@@ -103,6 +121,69 @@ int cmCPackDragNDropGenerator::InitializeInternal()
}
this->SetOptionIfNotSet("CPACK_COMMAND_REZ", rez_path.c_str());
+ if(this->IsSet("CPACK_DMG_SLA_DIR"))
+ {
+ slaDirectory = this->GetOption("CPACK_DMG_SLA_DIR");
+ if(!slaDirectory.empty() && this->IsSet("CPACK_RESOURCE_FILE_LICENSE"))
+ {
+ std::string license_file =
+ this->GetOption("CPACK_RESOURCE_FILE_LICENSE");
+ if(!license_file.empty() &&
+ (license_file.find("CPack.GenericLicense.txt") == std::string::npos))
+ {
+ cmCPackLogger(cmCPackLog::LOG_WARNING,
+ "Both CPACK_DMG_SLA_DIR and CPACK_RESOURCE_FILE_LICENSE specified, "
+ "defaulting to CPACK_DMG_SLA_DIR"
+ << std::endl);
+ }
+ }
+ if(!this->IsSet("CPACK_DMG_SLA_LANGUAGES"))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_DMG_SLA_DIR set but no languages defined "
+ "(set CPACK_DMG_SLA_LANGUAGES)"
+ << std::endl);
+ return 0;
+ }
+ if(!cmSystemTools::FileExists(slaDirectory, false))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_DMG_SLA_DIR does not exist"
+ << std::endl);
+ return 0;
+ }
+
+ std::vector<std::string> languages;
+ cmSystemTools::ExpandListArgument(
+ this->GetOption("CPACK_DMG_SLA_LANGUAGES"), languages);
+ if(languages.empty())
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_DMG_SLA_LANGUAGES set but empty"
+ << std::endl);
+ return 0;
+ }
+ for(size_t i = 0; i < languages.size(); ++i)
+ {
+ std::string license = slaDirectory + "/" + languages[i] + ".license.txt";
+ if (!cmSystemTools::FileExists(license))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Missing license file " << languages[i] << ".license.txt"
+ << std::endl);
+ return 0;
+ }
+ std::string menu = slaDirectory + "/" + languages[i] + ".menu.txt";
+ if (!cmSystemTools::FileExists(menu))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Missing menu file " << languages[i] << ".menu.txt"
+ << std::endl);
+ return 0;
+ }
+ }
+ }
+
return this->Superclass::InitializeInternal();
}
@@ -190,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)
{
@@ -246,12 +349,27 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
this->GetOption("CPACK_DMG_DS_STORE")
? this->GetOption("CPACK_DMG_DS_STORE") : "";
+ const std::string cpack_dmg_languages =
+ this->GetOption("CPACK_DMG_SLA_LANGUAGES")
+ ? this->GetOption("CPACK_DMG_SLA_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)
- {
+ {
+ cpack_license_file = "";
+ }
+
+ // use sla_dir if both sla_dir and license_file are set
+ if(!cpack_license_file.empty() &&
+ !slaDirectory.empty())
+ {
cpack_license_file = "";
- }
+ }
// The staging directory contains everything that will end-up inside the
// final disk image ...
@@ -307,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))
@@ -325,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;
}
@@ -365,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");
@@ -387,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;
@@ -416,56 +581,129 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
return 0;
}
+
+ if(had_error)
+ {
+ return 0;
+ }
}
- if(!cpack_license_file.empty())
- {
+ if(!cpack_license_file.empty() || !slaDirectory.empty())
+ {
+ // Use old hardcoded style if sla_dir is not set
+ bool oldStyle = slaDirectory.empty();
std::string sla_r = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
sla_r += "/sla.r";
- cmsys::ifstream ifs;
- ifs.open(cpack_license_file.c_str());
- if(ifs.is_open())
- {
- cmGeneratedFileStream osf(sla_r.c_str());
- osf << "#include <CoreServices/CoreServices.r>\n\n";
- osf << SLAHeader;
- osf << "\n";
- osf << "data 'TEXT' (5002, \"English\") {\n";
- while(ifs.good())
+ std::vector<std::string> languages;
+ if(!oldStyle)
{
- std::string line;
- std::getline(ifs, line);
- // escape quotes
- std::string::size_type pos = line.find('\"');
- while(pos != std::string::npos)
+ cmSystemTools::ExpandListArgument(cpack_dmg_languages, languages);
+ }
+
+ cmGeneratedFileStream ofs(sla_r.c_str());
+ ofs << "#include <CoreServices/CoreServices.r>\n\n";
+ if(oldStyle)
+ {
+ ofs << SLAHeader;
+ ofs << "\n";
+ }
+ else
+ {
+ /*
+ * LPic Layout
+ * (https://github.com/pypt/dmg-add-license/blob/master/main.c)
+ * as far as I can tell (no official documentation seems to exist):
+ * struct LPic {
+ * uint16_t default_language; // points to a resid, defaulting to 0,
+ * // which is the first set language
+ * uint16_t length;
+ * struct {
+ * uint16_t language_code;
+ * uint16_t resid;
+ * uint16_t encoding; // Encoding from TextCommon.h,
+ * // forcing MacRoman (0) for now. Might need to
+ * // allow overwrite per license by user later
+ * } item[1];
+ * }
+ */
+
+ // Create vector first for readability, then iterate to write to ofs
+ std::vector<uint16_t> header_data;
+ header_data.push_back(0);
+ header_data.push_back(languages.size());
+ for(size_t i = 0; i < languages.size(); ++i)
{
- line.replace(pos, 1, "\\\"");
- pos = line.find('\"', pos+2);
+ CFStringRef language_cfstring = CFStringCreateWithCString(
+ NULL, languages[i].c_str(), kCFStringEncodingUTF8);
+ CFStringRef iso_language =
+ CFLocaleCreateCanonicalLanguageIdentifierFromString(
+ NULL, language_cfstring);
+ if (!iso_language)
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ languages[i] << " is not a recognized language"
+ << std::endl);
+ }
+ char *iso_language_cstr = (char *) malloc(65);
+ CFStringGetCString(iso_language, iso_language_cstr, 64,
+ kCFStringEncodingMacRoman);
+ LangCode lang = 0;
+ RegionCode region = 0;
+ OSStatus err = LocaleStringToLangAndRegionCodes(iso_language_cstr,
+ &lang, &region);
+ if (err != noErr)
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "No language/region code available for " << iso_language_cstr
+ << std::endl);
+ free(iso_language_cstr);
+ return 0;
+ }
+ free(iso_language_cstr);
+ header_data.push_back(region);
+ header_data.push_back(i);
+ header_data.push_back(0);
}
- // break up long lines to avoid Rez errors
- std::vector<std::string> lines;
- const size_t max_line_length = 512;
- for(size_t i=0; i<line.size(); i+= max_line_length)
+ ofs << "data 'LPic' (5000) {\n";
+ ofs << std::hex << std::uppercase << std::setfill('0');
+
+ for(size_t i = 0; i < header_data.size(); ++i)
+ {
+ if(i % 8 == 0)
{
- int line_length = max_line_length;
- if(i+max_line_length > line.size())
- line_length = line.size()-i;
- lines.push_back(line.substr(i, line_length));
+ ofs << " $\"";
}
- for(size_t i=0; i<lines.size(); i++)
+ ofs << std::setw(4) << header_data[i];
+
+ if(i % 8 == 7 || i == header_data.size() - 1)
{
- osf << " \"" << lines[i] << "\"\n";
+ ofs << "\"\n";
}
- osf << " \"\\n\"\n";
+ else
+ {
+ ofs << " ";
+ }
+ }
+ ofs << "};\n\n";
+ // Reset ofs options
+ ofs << std::dec << std::nouppercase << std::setfill(' ');
}
- osf << "};\n";
- osf << "\n";
- osf << SLASTREnglish;
- ifs.close();
- osf.close();
- }
+
+ if(oldStyle)
+ {
+ WriteLicense(ofs, 0, "", cpack_license_file);
+ }
+ else
+ {
+ for(size_t i = 0; i < languages.size(); ++i)
+ {
+ WriteLicense(ofs, i + 5000, languages[i]);
+ }
+ }
+
+ ofs.Close();
// convert to UDCO
std::string temp_udco = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
@@ -539,7 +777,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
}
temp_image = temp_udco;
- }
+ }
// Create the final compressed read-only disk image ...
@@ -607,3 +845,126 @@ cmCPackDragNDropGenerator::GetComponentInstallDirNameSuffix(
return GetComponentPackageFileName(package_file_name, componentName, false);
}
+
+void
+cmCPackDragNDropGenerator::WriteLicense(cmGeneratedFileStream& outputStream,
+ int licenseNumber, std::string licenseLanguage, std::string licenseFile)
+{
+ if(!licenseFile.empty())
+ {
+ licenseNumber = 5002;
+ licenseLanguage = "English";
+ }
+
+ // License header
+ outputStream << "data 'TEXT' (" << licenseNumber << ", \""
+ << licenseLanguage << "\") {\n";
+ // License body
+ std::string actual_license = !licenseFile.empty() ? licenseFile :
+ (slaDirectory + "/" + licenseLanguage + ".license.txt");
+ cmsys::ifstream license_ifs;
+ license_ifs.open(actual_license.c_str());
+ if(license_ifs.is_open())
+ {
+ while(license_ifs.good())
+ {
+ std::string line;
+ std::getline(license_ifs, line);
+ if(!line.empty())
+ {
+ EscapeQuotes(line);
+ std::vector<std::string> lines;
+ BreakLongLine(line, lines);
+ for(size_t i = 0; i < lines.size(); ++i)
+ {
+ outputStream << " \"" << lines[i] << "\"\n";
+ }
+ }
+ outputStream << " \"\\n\"\n";
+ }
+ license_ifs.close();
+ }
+
+ // End of License
+ outputStream << "};\n\n";
+ if(!licenseFile.empty())
+ {
+ outputStream << SLASTREnglish;
+ }
+ else
+ {
+ // Menu header
+ outputStream << "resource 'STR#' (" << licenseNumber << ", \""
+ << licenseLanguage << "\") {\n";
+ outputStream << " {\n";
+
+ // Menu body
+ cmsys::ifstream menu_ifs;
+ menu_ifs.open((slaDirectory+"/"+licenseLanguage+".menu.txt").c_str());
+ if(menu_ifs.is_open())
+ {
+ size_t lines_written = 0;
+ while(menu_ifs.good())
+ {
+ // Lines written from original file, not from broken up lines
+ std::string line;
+ std::getline(menu_ifs, line);
+ if(!line.empty())
+ {
+ EscapeQuotes(line);
+ std::vector<std::string> lines;
+ BreakLongLine(line, lines);
+ for(size_t i = 0; i < lines.size(); ++i)
+ {
+ std::string comma;
+ // We need a comma after every complete string,
+ // but not on the very last line
+ if(lines_written != 8 && i == lines.size() - 1)
+ {
+ comma = ",";
+ }
+ else
+ {
+ comma = "";
+ }
+ outputStream << " \"" << lines[i] << "\"" << comma << "\n";
+ }
+ ++lines_written;
+ }
+ }
+ menu_ifs.close();
+ }
+
+ //End of menu
+ outputStream << " }\n";
+ outputStream << "};\n";
+ outputStream << "\n";
+ }
+}
+
+void
+cmCPackDragNDropGenerator::BreakLongLine(const std::string& line,
+ std::vector<std::string>& lines)
+{
+ const size_t max_line_length = 512;
+ for(size_t i = 0; i < line.size(); i += max_line_length)
+ {
+ int line_length = max_line_length;
+ if(i + max_line_length > line.size())
+ {
+ line_length = line.size() - i;
+ }
+ lines.push_back(line.substr(i, line_length));
+ }
+}
+
+void
+cmCPackDragNDropGenerator::EscapeQuotes(std::string& line)
+{
+ std::string::size_type pos = line.find('\"');
+ while(pos != std::string::npos)
+ {
+ line.replace(pos, 1, "\\\"");
+ pos = line.find('\"', pos + 2);
+ }
+}
diff --git a/Source/CPack/cmCPackDragNDropGenerator.h b/Source/CPack/cmCPackDragNDropGenerator.h
index 1c84d49..53d38c4 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.h
+++ b/Source/CPack/cmCPackDragNDropGenerator.h
@@ -15,6 +15,8 @@
#include "cmCPackGenerator.h"
+class cmGeneratedFileStream;
+
/** \class cmCPackDragNDropGenerator
* \brief A generator for OSX drag-n-drop installs
*/
@@ -34,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
@@ -42,6 +45,15 @@ protected:
int CreateDMG(const std::string& src_dir, const std::string& output_file);
std::string InstallPrefix;
+
+private:
+ std::string slaDirectory;
+
+ void WriteLicense(cmGeneratedFileStream& outputStream, int licenseNumber,
+ std::string licenseLanguage, std::string licenseFile = "");
+ void BreakLongLine(const std::string& line,
+ std::vector<std::string>& lines);
+ void EscapeQuotes(std::string& line);
};
#endif
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index def9fc7..22d4bf0 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -16,7 +16,6 @@
#include "cmCPackLog.h"
#include "cmake.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmGeneratedFileStream.h"
#include "cmCPackComponentGroup.h"
#include "cmXMLSafe.h"
@@ -718,13 +717,12 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
cmake cm;
cm.SetHomeDirectory("");
cm.SetHomeOutputDirectory("");
+ cm.GetCurrentSnapshot().SetDefaultDefinitions();
cm.AddCMakePaths();
cm.SetProgressCallback(cmCPackGeneratorProgress, this);
cmGlobalGenerator gg(&cm);
cmsys::auto_ptr<cmMakefile> mf(
new cmMakefile(&gg, cm.GetCurrentSnapshot()));
- cmsys::auto_ptr<cmLocalGenerator> lg(
- gg.CreateLocalGenerator(mf.get()));
std::string realInstallDirectory = tempInstallDirectory;
if ( !installSubDirectory.empty() && installSubDirectory != "/" )
{
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index 6cdda28..5ba639f 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -13,7 +13,6 @@
#include "cmCPackNSISGenerator.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmSystemTools.h"
#include "cmMakefile.h"
#include "cmGeneratedFileStream.h"
@@ -158,6 +157,28 @@ int cmCPackNSISGenerator::PackageFiles()
installerIconCode.c_str());
}
+ if (this->IsSet("CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP"))
+ {
+ std::string installerBitmapCode =
+ "!define MUI_WELCOMEFINISHPAGE_BITMAP \"";
+ installerBitmapCode +=
+ this->GetOption("CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP");
+ installerBitmapCode += "\"\n";
+ this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_WELCOMEFINISH_CODE",
+ installerBitmapCode.c_str());
+ }
+
+ if (this->IsSet("CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP"))
+ {
+ std::string installerBitmapCode =
+ "!define MUI_UNWELCOMEFINISHPAGE_BITMAP \"";
+ installerBitmapCode +=
+ this->GetOption("CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP");
+ installerBitmapCode += "\"\n";
+ this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_UNWELCOMEFINISH_CODE",
+ installerBitmapCode.c_str());
+ }
+
if(this->IsSet("CPACK_NSIS_MUI_FINISHPAGE_RUN"))
{
std::string installerRunCode = "!define MUI_FINISHPAGE_RUN \"$INSTDIR\\";
diff --git a/Source/CPack/cmCPackOSXX11Generator.cxx b/Source/CPack/cmCPackOSXX11Generator.cxx
index d533af8..8940f54 100644
--- a/Source/CPack/cmCPackOSXX11Generator.cxx
+++ b/Source/CPack/cmCPackOSXX11Generator.cxx
@@ -13,7 +13,6 @@
#include "cmake.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmSystemTools.h"
#include "cmMakefile.h"
#include "cmGeneratedFileStream.h"
diff --git a/Source/CPack/cmCPackPackageMakerGenerator.cxx b/Source/CPack/cmCPackPackageMakerGenerator.cxx
index 880663f..8fdc036 100644
--- a/Source/CPack/cmCPackPackageMakerGenerator.cxx
+++ b/Source/CPack/cmCPackPackageMakerGenerator.cxx
@@ -13,7 +13,6 @@
#include "cmake.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmSystemTools.h"
#include "cmMakefile.h"
#include "cmGeneratedFileStream.h"
diff --git a/Source/CPack/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx
index 109dcb7..68b893f 100644
--- a/Source/CPack/cmCPackSTGZGenerator.cxx
+++ b/Source/CPack/cmCPackSTGZGenerator.cxx
@@ -14,7 +14,6 @@
#include "cmake.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmSystemTools.h"
#include "cmMakefile.h"
#include "cmCPackLog.h"
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index cb9cbc4..c08897f 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -18,7 +18,6 @@
#include "cmCPackGenerator.h"
#include "cmake.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmCPackLog.h"
@@ -200,12 +199,11 @@ int main (int argc, char const* const* argv)
cmake cminst;
cminst.SetHomeDirectory("");
cminst.SetHomeOutputDirectory("");
+ cminst.GetCurrentSnapshot().SetDefaultDefinitions();
cminst.GetState()->RemoveUnscriptableCommands();
cmGlobalGenerator cmgg(&cminst);
cmsys::auto_ptr<cmMakefile> globalMF(
new cmMakefile(&cmgg, cminst.GetCurrentSnapshot()));
- cmsys::auto_ptr<cmLocalGenerator> cmlg(
- cmgg.CreateLocalGenerator(globalMF.get()));
#if defined(__CYGWIN__)
globalMF->AddDefinition("CMAKE_LEGACY_CYGWIN_WIN32", "0");
#endif