diff options
Diffstat (limited to 'Source/CPack')
-rw-r--r-- | Source/CPack/WiX/cmCPackWIXGenerator.cxx | 437 | ||||
-rw-r--r-- | Source/CPack/WiX/cmCPackWIXGenerator.h | 45 | ||||
-rw-r--r-- | Source/CPack/WiX/cmWIXSourceWriter.cxx | 29 | ||||
-rw-r--r-- | Source/CPack/WiX/cmWIXSourceWriter.h | 4 | ||||
-rw-r--r-- | Source/CPack/cmCPackDocumentMacros.cxx | 16 | ||||
-rw-r--r-- | Source/CPack/cmCPackDocumentMacros.h | 21 | ||||
-rw-r--r-- | Source/CPack/cmCPackDocumentVariables.cxx | 122 | ||||
-rw-r--r-- | Source/CPack/cmCPackDocumentVariables.h | 21 | ||||
-rw-r--r-- | Source/CPack/cmCPackDragNDropGenerator.cxx | 7 | ||||
-rw-r--r-- | Source/CPack/cmCPackGenerator.cxx | 11 | ||||
-rw-r--r-- | Source/CPack/cmCPackGenerator.h | 9 | ||||
-rw-r--r-- | Source/CPack/cpack.cxx | 158 |
12 files changed, 410 insertions, 470 deletions
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx index cc9dec7..448d8d1 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx +++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx @@ -1,6 +1,6 @@ /*============================================================================ CMake - Cross Platform Makefile Generator - Copyright 2000-2012 Kitware, Inc., Insight Software Consortium + Copyright 2000-2013 Kitware, Inc., Insight Software Consortium Distributed under the OSI-approved BSD License (the "License"); see accompanying file Copyright.txt for details. @@ -14,6 +14,7 @@ #include <cmSystemTools.h> #include <cmGeneratedFileStream.h> +#include <cmCryptoHash.h> #include <CPack/cmCPackLog.h> #include <CPack/cmCPackComponentGroup.h> @@ -169,6 +170,16 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration() } } + if(GetOption("CPACK_PACKAGE_VENDOR") == 0) + { + std::string defaultVendor = "Humanity"; + SetOption("CPACK_PACKAGE_VENDOR", defaultVendor.c_str()); + + cmCPackLogger(cmCPackLog::LOG_VERBOSE, + "CPACK_PACKAGE_VENDOR implicitly set to " << defaultVendor << " . " + << std::endl); + } + return true; } @@ -189,6 +200,8 @@ bool cmCPackWIXGenerator::PackageFilesImpl() return false; } + AppendUserSuppliedExtraSources(); + std::stringstream objectFiles; for(size_t i = 0; i < wixSources.size(); ++i) { @@ -205,9 +218,35 @@ bool cmCPackWIXGenerator::PackageFilesImpl() objectFiles << " " << QuotePath(objectFilename); } + AppendUserSuppliedExtraObjects(objectFiles); + return RunLightCommand(objectFiles.str()); } +void cmCPackWIXGenerator::AppendUserSuppliedExtraSources() +{ + const char *cpackWixExtraSources = GetOption("CPACK_WIX_EXTRA_SOURCES"); + if(!cpackWixExtraSources) return; + + cmSystemTools::ExpandListArgument(cpackWixExtraSources, wixSources); +} + +void cmCPackWIXGenerator::AppendUserSuppliedExtraObjects(std::ostream& stream) +{ + const char *cpackWixExtraObjects = GetOption("CPACK_WIX_EXTRA_OBJECTS"); + if(!cpackWixExtraObjects) return; + + std::vector<std::string> expandedExtraObjects; + + cmSystemTools::ExpandListArgument( + cpackWixExtraObjects, expandedExtraObjects); + + for(size_t i = 0; i < expandedExtraObjects.size(); ++i) + { + stream << " " << QuotePath(expandedExtraObjects[i]); + } +} + bool cmCPackWIXGenerator::CreateWiXVariablesIncludeFile() { std::string cpackTopLevel; @@ -319,9 +358,6 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() directoryDefinitions.AddAttribute("Name", install_root[i]); } - size_t directoryCounter = 0; - size_t fileCounter = 0; - std::string fileDefinitionsFilename = cpackTopLevel + "/files.wxs"; @@ -342,113 +378,49 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() featureDefinitions.AddAttribute("Id", "ProductFeature"); featureDefinitions.AddAttribute("Title", Name); featureDefinitions.AddAttribute("Level", "1"); - featureDefinitions.EndElement(); + featureDefinitions.EndElement("Feature"); featureDefinitions.BeginElement("FeatureRef"); featureDefinitions.AddAttribute("Id", "ProductFeature"); + std::vector<std::string> cpackPackageExecutablesList; const char *cpackPackageExecutables = GetOption("CPACK_PACKAGE_EXECUTABLES"); - std::vector<std::string> cpackPkgExecutables; - std::string regKey; - if ( cpackPackageExecutables ) + if(cpackPackageExecutables) { - cmSystemTools::ExpandListArgument(cpackPackageExecutables, - cpackPkgExecutables); - if ( cpackPkgExecutables.size() % 2 != 0 ) - { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "CPACK_PACKAGE_EXECUTABLES should contain pairs of <executable> and " - "<icon name>." << std::endl); - cpackPkgExecutables.clear(); - } - - const char *cpackVendor = GetOption("CPACK_PACKAGE_VENDOR"); - const char *cpackPkgName = GetOption("CPACK_PACKAGE_NAME"); - if (!cpackVendor || !cpackPkgName) - { - cmCPackLogger(cmCPackLog::LOG_WARNING, "CPACK_PACKAGE_VENDOR and " - "CPACK_PACKAGE_NAME must be defined for shortcut creation" << std::endl); - cpackPkgExecutables.clear(); - } - else - { - regKey = std::string("Software/") + cpackVendor + "/" + cpackPkgName; - } + cmSystemTools::ExpandListArgument(cpackPackageExecutables, + cpackPackageExecutablesList); + if(cpackPackageExecutablesList.size() % 2 != 0 ) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "CPACK_PACKAGE_EXECUTABLES should contain pairs of <executable> and " + "<text label>." << std::endl); + return false; + } } - std::vector<std::string> dirIdExecutables; AddDirectoryAndFileDefinitons( toplevel, "INSTALL_ROOT", directoryDefinitions, fileDefinitions, featureDefinitions, - directoryCounter, fileCounter, cpackPkgExecutables, dirIdExecutables); + cpackPackageExecutablesList); - directoryDefinitions.EndElement(); - directoryDefinitions.EndElement(); - - if (dirIdExecutables.size() > 0 && dirIdExecutables.size() % 3 == 0) + if(!CreateStartMenuShortcuts( + directoryDefinitions, fileDefinitions, featureDefinitions)) { - fileDefinitions.BeginElement("DirectoryRef"); - fileDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER"); - fileDefinitions.BeginElement("Component"); - fileDefinitions.AddAttribute("Id", "SHORTCUT"); - fileDefinitions.AddAttribute("Guid", "*"); + return false; + } - std::vector<std::string>::iterator it; - for ( it = dirIdExecutables.begin() ; - it != dirIdExecutables.end(); - ++it) - { - std::string fileName = *it++; - std::string iconName = *it++; - std::string directoryId = *it; - - fileDefinitions.BeginElement("Shortcut"); - std::string shortcutName = fileName; // the iconName is mor likely to contain blanks early on - std::string::size_type const dotPos = shortcutName.find('.'); - if(std::string::npos == dotPos) - { shortcutName = shortcutName.substr(0, dotPos); } - fileDefinitions.AddAttribute("Id", "SHORTCUT_" + shortcutName); - fileDefinitions.AddAttribute("Name", iconName); - std::string target = "[" + directoryId + "]" + fileName; - fileDefinitions.AddAttribute("Target", target); - fileDefinitions.AddAttribute("WorkingDirectory", directoryId); - fileDefinitions.EndElement(); - } - fileDefinitions.BeginElement("Shortcut"); - fileDefinitions.AddAttribute("Id", "UNINSTALL"); - std::string pkgName = GetOption("CPACK_PACKAGE_NAME"); - fileDefinitions.AddAttribute("Name", "Uninstall " + pkgName); - fileDefinitions.AddAttribute("Description", "Uninstalls " + pkgName); - fileDefinitions.AddAttribute("Target", "[SystemFolder]msiexec.exe"); - fileDefinitions.AddAttribute("Arguments", "/x [ProductCode]"); - fileDefinitions.EndElement(); - fileDefinitions.BeginElement("RemoveFolder"); - fileDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER"); - fileDefinitions.AddAttribute("On", "uninstall"); - fileDefinitions.EndElement(); - fileDefinitions.BeginElement("RegistryValue"); - fileDefinitions.AddAttribute("Root", "HKCU"); - fileDefinitions.AddAttribute("Key", regKey); - fileDefinitions.AddAttribute("Name", "installed"); - fileDefinitions.AddAttribute("Type", "integer"); - fileDefinitions.AddAttribute("Value", "1"); - fileDefinitions.AddAttribute("KeyPath", "yes"); - - featureDefinitions.BeginElement("ComponentRef"); - featureDefinitions.AddAttribute("Id", "SHORTCUT"); - featureDefinitions.EndElement(); - directoryDefinitions.BeginElement("Directory"); - directoryDefinitions.AddAttribute("Id", "ProgramMenuFolder"); - directoryDefinitions.BeginElement("Directory"); - directoryDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER"); - const char *startMenuFolder = GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER"); - directoryDefinitions.AddAttribute("Name", startMenuFolder); - } + featureDefinitions.EndElement("FeatureRef"); + featureDefinitions.EndElement("Fragment"); + fileDefinitions.EndElement("Fragment"); - featureDefinitions.EndElement(); - featureDefinitions.EndElement(); - fileDefinitions.EndElement(); - directoryDefinitions.EndElement(); + for(size_t i = 1; i < install_root.size(); ++i) + { + directoryDefinitions.EndElement("Directory"); + } + + directoryDefinitions.EndElement("Directory"); + directoryDefinitions.EndElement("Directory"); + directoryDefinitions.EndElement("Fragment"); std::string wixTemplate = FindTemplate("WIX.template.in"); if(GetOption("CPACK_WIX_TEMPLATE") != 0) @@ -478,6 +450,106 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() return true; } +bool cmCPackWIXGenerator::CreateStartMenuShortcuts( + cmWIXSourceWriter& directoryDefinitions, + cmWIXSourceWriter& fileDefinitions, + cmWIXSourceWriter& featureDefinitions) +{ + if(shortcutMap.empty()) + { + return true; + } + + std::string cpackVendor; + if(!RequireOption("CPACK_PACKAGE_VENDOR", cpackVendor)) + { + return false; + } + + std::string cpackPackageName; + if(!RequireOption("CPACK_PACKAGE_NAME", cpackPackageName)) + { + return false; + } + + fileDefinitions.BeginElement("DirectoryRef"); + fileDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER"); + fileDefinitions.BeginElement("Component"); + fileDefinitions.AddAttribute("Id", "SHORTCUT"); + fileDefinitions.AddAttribute("Guid", "*"); + + for(shortcut_map_t::const_iterator + i = shortcutMap.begin(); i != shortcutMap.end(); ++i) + { + std::string const& id = i->first; + cmWIXShortcut const& shortcut = i->second; + + std::string shortcutId = std::string("CM_S") + id; + std::string fileId = std::string("CM_F") + id; + + fileDefinitions.BeginElement("Shortcut"); + fileDefinitions.AddAttribute("Id", shortcutId); + fileDefinitions.AddAttribute("Name", shortcut.textLabel); + std::string target = "[#" + fileId + "]"; + fileDefinitions.AddAttribute("Target", target); + fileDefinitions.AddAttribute("WorkingDirectory", + shortcut.workingDirectoryId); + fileDefinitions.EndElement("Shortcut"); + } + + CreateUninstallShortcut(cpackPackageName, fileDefinitions); + + fileDefinitions.BeginElement("RemoveFolder"); + fileDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER"); + fileDefinitions.AddAttribute("On", "uninstall"); + fileDefinitions.EndElement("RemoveFolder"); + + std::string registryKey = + std::string("Software/") + cpackVendor + "/" + cpackPackageName; + + fileDefinitions.BeginElement("RegistryValue"); + fileDefinitions.AddAttribute("Root", "HKCU"); + fileDefinitions.AddAttribute("Key", registryKey); + fileDefinitions.AddAttribute("Name", "installed"); + fileDefinitions.AddAttribute("Type", "integer"); + fileDefinitions.AddAttribute("Value", "1"); + fileDefinitions.AddAttribute("KeyPath", "yes"); + fileDefinitions.EndElement("RegistryValue"); + + fileDefinitions.EndElement("Component"); + fileDefinitions.EndElement("DirectoryRef"); + + featureDefinitions.BeginElement("ComponentRef"); + featureDefinitions.AddAttribute("Id", "SHORTCUT"); + featureDefinitions.EndElement("ComponentRef"); + + directoryDefinitions.BeginElement("Directory"); + directoryDefinitions.AddAttribute("Id", "ProgramMenuFolder"); + + directoryDefinitions.BeginElement("Directory"); + directoryDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER"); + const char *startMenuFolder = GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER"); + directoryDefinitions.AddAttribute("Name", startMenuFolder); + directoryDefinitions.EndElement("Directory"); + + directoryDefinitions.EndElement("Directory"); + + return true; +} + +void cmCPackWIXGenerator::CreateUninstallShortcut( + std::string const& packageName, + cmWIXSourceWriter& fileDefinitions) +{ + fileDefinitions.BeginElement("Shortcut"); + fileDefinitions.AddAttribute("Id", "UNINSTALL"); + fileDefinitions.AddAttribute("Name", "Uninstall " + packageName); + fileDefinitions.AddAttribute("Description", "Uninstalls " + packageName); + fileDefinitions.AddAttribute("Target", "[SystemFolder]msiexec.exe"); + fileDefinitions.AddAttribute("Arguments", "/x [ProductCode]"); + fileDefinitions.EndElement("Shortcut"); +} + bool cmCPackWIXGenerator::CreateLicenseFile() { std::string licenseSourceFilename; @@ -531,10 +603,7 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons( cmWIXSourceWriter& directoryDefinitions, cmWIXSourceWriter& fileDefinitions, cmWIXSourceWriter& featureDefinitions, - size_t& directoryCounter, - size_t& fileCounter, - const std::vector<std::string>& pkgExecutables, - std::vector<std::string>& dirIdExecutables) + const std::vector<std::string>& packageExecutables) { cmsys::Directory dir; dir.Load(topdir.c_str()); @@ -550,11 +619,14 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons( std::string fullPath = topdir + "/" + fileName; + std::string relativePath = cmSystemTools::RelativePath( + toplevel.c_str(), fullPath.c_str()); + + std::string id = PathToId(relativePath); + if(cmSystemTools::FileIsDirectory(fullPath.c_str())) { - std::stringstream tmp; - tmp << "DIR_ID_" << ++directoryCounter; - std::string subDirectoryId = tmp.str(); + std::string subDirectoryId = std::string("CM_D") + id; directoryDefinitions.BeginElement("Directory"); directoryDefinitions.AddAttribute("Id", subDirectoryId); @@ -565,20 +637,14 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons( directoryDefinitions, fileDefinitions, featureDefinitions, - directoryCounter, - fileCounter, - pkgExecutables, - dirIdExecutables); - directoryDefinitions.EndElement(); + packageExecutables); + + directoryDefinitions.EndElement("Directory"); } else { - std::stringstream tmp; - tmp << "_ID_" << ++fileCounter; - std::string idSuffix = tmp.str(); - - std::string componentId = std::string("CMP") + idSuffix; - std::string fileId = std::string("FILE") + idSuffix; + std::string componentId = std::string("CM_C") + id; + std::string fileId = std::string("CM_F") + id; fileDefinitions.BeginElement("DirectoryRef"); fileDefinitions.AddAttribute("Id", directoryId); @@ -592,28 +658,25 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons( fileDefinitions.AddAttribute("Source", fullPath); fileDefinitions.AddAttribute("KeyPath", "yes"); - fileDefinitions.EndElement(); - fileDefinitions.EndElement(); - fileDefinitions.EndElement(); + fileDefinitions.EndElement("File"); + fileDefinitions.EndElement("Component"); + fileDefinitions.EndElement("DirectoryRef"); featureDefinitions.BeginElement("ComponentRef"); featureDefinitions.AddAttribute("Id", componentId); - featureDefinitions.EndElement(); + featureDefinitions.EndElement("ComponentRef"); - std::vector<std::string>::const_iterator it; - for (it = pkgExecutables.begin() ; - it != pkgExecutables.end() ; - ++it) + for(size_t j = 0; j < packageExecutables.size(); ++j) { - std::string execName = *it++; - std::string iconName = *it; + std::string const& executableName = packageExecutables[j++]; + std::string const& textLabel = packageExecutables[j]; - if (cmSystemTools::LowerCase(fileName) == - cmSystemTools::LowerCase(execName) + ".exe") + if(cmSystemTools::LowerCase(fileName) == + cmSystemTools::LowerCase(executableName) + ".exe") { - dirIdExecutables.push_back(fileName); - dirIdExecutables.push_back(iconName); - dirIdExecutables.push_back(directoryId); + cmWIXShortcut &shortcut = shortcutMap[id]; + shortcut.textLabel= textLabel; + shortcut.workingDirectoryId = directoryId; } } } @@ -686,3 +749,119 @@ std::string cmCPackWIXGenerator::GetRightmostExtension( return cmSystemTools::LowerCase(extension); } + +std::string cmCPackWIXGenerator::PathToId(const std::string& path) +{ + id_map_t::const_iterator i = pathToIdMap.find(path); + if(i != pathToIdMap.end()) return i->second; + + std::string id = CreateNewIdForPath(path); + return id; +} + +std::string cmCPackWIXGenerator::CreateNewIdForPath(const std::string& path) +{ + std::vector<std::string> components; + cmSystemTools::SplitPath(path.c_str(), components, false); + + size_t replacementCount = 0; + + std::string identifier; + std::string currentComponent; + + for(size_t i = 1; i < components.size(); ++i) + { + if(i != 1) identifier += '.'; + + currentComponent = NormalizeComponentForId( + components[i], replacementCount); + + identifier += currentComponent; + } + + std::string idPrefix = "P"; + size_t replacementPercent = replacementCount * 100 / identifier.size(); + if(replacementPercent > 33 || identifier.size() > 60) + { + identifier = CreateHashedId(path, currentComponent); + idPrefix = "H"; + } + + std::stringstream result; + result << idPrefix << "_" << identifier; + + size_t ambiguityCount = ++idAmbiguityCounter[identifier]; + + if(ambiguityCount > 999) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error while trying to generate a unique Id for '" << + path << "'" << std::endl); + + return std::string(); + } + else if(ambiguityCount > 1) + { + result << "_" << ambiguityCount; + } + + std::string resultString = result.str(); + + pathToIdMap[path] = resultString; + + return resultString; +} + +std::string cmCPackWIXGenerator::CreateHashedId( + const std::string& path, const std::string& normalizedFilename) +{ + cmsys::auto_ptr<cmCryptoHash> sha1 = cmCryptoHash::New("SHA1"); + std::string hash = sha1->HashString(path.c_str()); + + std::string identifier; + identifier += hash.substr(0, 7) + "_"; + + const size_t maxFileNameLength = 52; + if(normalizedFilename.length() > maxFileNameLength) + { + identifier += normalizedFilename.substr(0, maxFileNameLength - 3); + identifier += "..."; + } + else + { + identifier += normalizedFilename; + } + + return identifier; +} + +std::string cmCPackWIXGenerator::NormalizeComponentForId( + const std::string& component, size_t& replacementCount) +{ + std::string result; + result.resize(component.size()); + + for(size_t i = 0; i < component.size(); ++i) + { + char c = component[i]; + if(IsLegalIdCharacter(c)) + { + result[i] = c; + } + else + { + result[i] = '_'; + ++ replacementCount; + } + } + + return result; +} + +bool cmCPackWIXGenerator::IsLegalIdCharacter(char c) +{ + return (c >= '0' && c <= '9') || + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + c == '_' || c == '.'; +} diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h index aaccf9d..c96ad5a 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.h +++ b/Source/CPack/WiX/cmCPackWIXGenerator.h @@ -18,6 +18,12 @@ #include <string> #include <map> +struct cmWIXShortcut +{ + std::string textLabel; + std::string workingDirectoryId; +}; + class cmWIXSourceWriter; /** \class cmCPackWIXGenerator @@ -54,6 +60,10 @@ protected: } private: + typedef std::map<std::string, std::string> id_map_t; + typedef std::map<std::string, size_t> ambiguity_map_t; + typedef std::map<std::string, cmWIXShortcut> shortcut_map_t; + bool InitializeWiXConfiguration(); bool PackageFilesImpl(); @@ -68,6 +78,19 @@ private: bool CreateWiXSourceFiles(); + bool CreateStartMenuShortcuts( + cmWIXSourceWriter& directoryDefinitions, + cmWIXSourceWriter& fileDefinitions, + cmWIXSourceWriter& featureDefinitions); + + void CreateUninstallShortcut( + std::string const& packageName, + cmWIXSourceWriter& fileDefinitions); + + void AppendUserSuppliedExtraSources(); + + void AppendUserSuppliedExtraObjects(std::ostream& stream); + bool CreateLicenseFile(); bool RunWiXCommand(const std::string& command); @@ -82,12 +105,7 @@ private: cmWIXSourceWriter& directoryDefinitions, cmWIXSourceWriter& fileDefinitions, cmWIXSourceWriter& featureDefinitions, - size_t& directoryCounter, - size_t& fileCounter, - const std::vector<std::string>& pkgExecutables, - std::vector<std::string>& dirIdExecutables - ); - + const std::vector<std::string>& pkgExecutables); bool RequireOption(const std::string& name, std::string& value) const; @@ -99,7 +117,22 @@ private: static std::string GetRightmostExtension(const std::string& filename); + std::string PathToId(const std::string& path); + + std::string CreateNewIdForPath(const std::string& path); + + static std::string CreateHashedId( + const std::string& path, const std::string& normalizedFilename); + + std::string NormalizeComponentForId( + const std::string& component, size_t& replacementCount); + + static bool IsLegalIdCharacter(char c); + std::vector<std::string> wixSources; + id_map_t pathToIdMap; + ambiguity_map_t idAmbiguityCounter; + shortcut_map_t shortcutMap; }; #endif diff --git a/Source/CPack/WiX/cmWIXSourceWriter.cxx b/Source/CPack/WiX/cmWIXSourceWriter.cxx index af7ba80..214b8ac 100644 --- a/Source/CPack/WiX/cmWIXSourceWriter.cxx +++ b/Source/CPack/WiX/cmWIXSourceWriter.cxx @@ -21,7 +21,8 @@ cmWIXSourceWriter::cmWIXSourceWriter(cmCPackLog* logger, bool isIncludeFile): Logger(logger), file(filename.c_str()), - state(DEFAULT) + state(DEFAULT), + sourceFilename(filename) { WriteXMLDeclaration(); @@ -39,10 +40,15 @@ cmWIXSourceWriter::cmWIXSourceWriter(cmCPackLog* logger, cmWIXSourceWriter::~cmWIXSourceWriter() { - while(elements.size()) + if(elements.size() > 1) { - EndElement(); + cmCPackLogger(cmCPackLog::LOG_ERROR, + elements.size() - 1 << " WiX elements were still open when closing '" << + sourceFilename << "'" << std::endl); + return; } + + EndElement(elements.back()); } void cmWIXSourceWriter::BeginElement(const std::string& name) @@ -60,12 +66,22 @@ void cmWIXSourceWriter::BeginElement(const std::string& name) state = BEGIN; } -void cmWIXSourceWriter::EndElement() +void cmWIXSourceWriter::EndElement(std::string const& name) { if(elements.empty()) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "can not end WiX element with no open elements" << std::endl); + "can not end WiX element with no open elements in '" << + sourceFilename << "'" << std::endl); + return; + } + + if(elements.back() != name) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "WiX element <" << elements.back() << + "> can not be closed by </" << name << "> in '" << + sourceFilename << "'" << std::endl); return; } @@ -173,6 +189,9 @@ std::string cmWIXSourceWriter::EscapeAttributeValue( case '<': result += "<"; break; + case '>': + result += ">"; + break; case '&': result +="&"; break; diff --git a/Source/CPack/WiX/cmWIXSourceWriter.h b/Source/CPack/WiX/cmWIXSourceWriter.h index 1dafc1f..0c7803c 100644 --- a/Source/CPack/WiX/cmWIXSourceWriter.h +++ b/Source/CPack/WiX/cmWIXSourceWriter.h @@ -32,7 +32,7 @@ public: void BeginElement(const std::string& name); - void EndElement(); + void EndElement(const std::string& name); void AddProcessingInstruction( const std::string& target, const std::string& content); @@ -62,6 +62,8 @@ private: State state; std::vector<std::string> elements; + + std::string sourceFilename; }; #endif diff --git a/Source/CPack/cmCPackDocumentMacros.cxx b/Source/CPack/cmCPackDocumentMacros.cxx deleted file mode 100644 index ddc75a4..0000000 --- a/Source/CPack/cmCPackDocumentMacros.cxx +++ /dev/null @@ -1,16 +0,0 @@ -#include "cmCPackDocumentMacros.h" - -void cmCPackDocumentMacros::GetMacrosDocumentation( - std::vector<cmDocumentationEntry>& ) -{ - // Commented-out example of use - // - // cmDocumentationEntry e("cpack_<macro>", - // "Brief Description" - // "which may be on several lines.", - // "Long description in pre-formatted format" - // " blah\n" - // " blah\n" - //); - //v.push_back(e); -} diff --git a/Source/CPack/cmCPackDocumentMacros.h b/Source/CPack/cmCPackDocumentMacros.h deleted file mode 100644 index 544f74f..0000000 --- a/Source/CPack/cmCPackDocumentMacros.h +++ /dev/null @@ -1,21 +0,0 @@ -/*============================================================================ - CMake - Cross Platform Makefile Generator - Copyright 2000-2009 Kitware, Inc., Insight Software Consortium - - Distributed under the OSI-approved BSD License (the "License"); - see accompanying file Copyright.txt for details. - - This software is distributed WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the License for more information. -============================================================================*/ -#ifndef cmCPackDocumentMacros_h -#define cmCPackDocumentMacros_h -#include "cmStandardIncludes.h" -class cmCPackDocumentMacros -{ -public: - static void GetMacrosDocumentation(std::vector<cmDocumentationEntry>& v); -}; - -#endif diff --git a/Source/CPack/cmCPackDocumentVariables.cxx b/Source/CPack/cmCPackDocumentVariables.cxx deleted file mode 100644 index 8b16ae9..0000000 --- a/Source/CPack/cmCPackDocumentVariables.cxx +++ /dev/null @@ -1,122 +0,0 @@ -#include "cmCPackDocumentVariables.h" -#include "cmake.h" - -void cmCPackDocumentVariables::DefineVariables(cmake* cm) -{ - // Subsection: variables defined/used by cpack, - // which are common to all CPack generators - - cm->DefineProperty - ("CPACK_PACKAGING_INSTALL_PREFIX", cmProperty::VARIABLE, - "The prefix used in the built package.", - "Each CPack generator has a default value (like /usr)." - " This default value may" - " be overwritten from the CMakeLists.txt or the cpack command line" - " by setting an alternative value.\n" - "e.g. " - " set(CPACK_PACKAGING_INSTALL_PREFIX \"/opt\")\n" - "This is not the same purpose as CMAKE_INSTALL_PREFIX which" - " is used when installing from the build tree without building" - " a package." - "", false, - "Variables common to all CPack generators"); - - cm->DefineProperty - ("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", cmProperty::VARIABLE, - "Boolean toggle to include/exclude top level directory.", - "When preparing a package CPack installs the item under" - " the so-called top level directory. The purpose of" - " is to include (set to 1 or ON or TRUE) the top level directory" - " in the package or not (set to 0 or OFF or FALSE).\n" - "Each CPack generator has a built-in default value for this" - " variable. E.g. Archive generators (ZIP, TGZ, ...) includes" - " the top level whereas RPM or DEB don't. The user may override" - " the default value by setting this variable.\n" - "There is a similar variable " - "CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY " - "which may be used to override the behavior for the component" - " packaging case which may have different default value for" - " historical (now backward compatibility) reason.", false, - "Variables common to all CPack generators"); - - cm->DefineProperty - ("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY", cmProperty::VARIABLE, - "Boolean toggle to include/exclude top level directory " - "(component case).", - "Similar usage as CPACK_INCLUDE_TOPLEVEL_DIRECTORY" - " but for the component case. " - "See CPACK_INCLUDE_TOPLEVEL_DIRECTORY documentation for" - " the detail.", false, - "Variables common to all CPack generators"); - - cm->DefineProperty - ("CPACK_SET_DESTDIR", cmProperty::VARIABLE, - "Boolean toggle to make CPack use DESTDIR mechanism when" - " packaging.", "DESTDIR means DESTination DIRectory." - " It is commonly used by makefile " - "users in order to install software at non-default location. It " - "is a basic relocation mechanism that should not be used on" - " Windows (see CMAKE_INSTALL_PREFIX documentation). " - "It is usually invoked like this:\n" - " make DESTDIR=/home/john install\n" - "which will install the concerned software using the" - " installation prefix, e.g. \"/usr/local\" prepended with " - "the DESTDIR value which finally gives \"/home/john/usr/local\"." - " When preparing a package, CPack first installs the items to be " - "packaged in a local (to the build tree) directory by using the " - "same DESTDIR mechanism. Nevertheless, if " - "CPACK_SET_DESTDIR is set then CPack will set DESTDIR before" - " doing the local install. The most noticeable difference is" - " that without CPACK_SET_DESTDIR, CPack uses " - "CPACK_PACKAGING_INSTALL_PREFIX as a prefix whereas with " - "CPACK_SET_DESTDIR set, CPack will use CMAKE_INSTALL_PREFIX as" - " a prefix.\n" - "Manually setting CPACK_SET_DESTDIR may help (or simply be" - " necessary) if some install rules uses absolute " - "DESTINATION (see CMake INSTALL command)." - " However, starting with" - " CPack/CMake 2.8.3 RPM and DEB installers tries to handle DESTDIR" - " automatically so that it is seldom necessary for the user to set" - " it.", false, - "Variables common to all CPack generators"); - - cm->DefineProperty - ("CPACK_INSTALL_SCRIPT", cmProperty::VARIABLE, - "Extra CMake script provided by the user.", - "If set this CMake script will be executed by CPack " - "during its local [CPack-private] installation " - "which is done right before packaging the files." - " The script is not called by e.g.: make install.", false, - "Variables common to all CPack generators"); - - cm->DefineProperty - ("CPACK_ABSOLUTE_DESTINATION_FILES", cmProperty::VARIABLE, - "List of files which have been installed using " - " an ABSOLUTE DESTINATION path.", - "This variable is a Read-Only variable which is set internally" - " by CPack during installation and before packaging using" - " CMAKE_ABSOLUTE_DESTINATION_FILES defined in cmake_install.cmake " - "scripts. The value can be used within CPack project configuration" - " file and/or CPack<GEN>.cmake file of <GEN> generator.", false, - "Variables common to all CPack generators"); - - cm->DefineProperty - ("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION", cmProperty::VARIABLE, - "Ask CPack to warn each time a file with absolute INSTALL" - " DESTINATION is encountered.", - "This variable triggers the definition of " - "CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION when CPack runs" - " cmake_install.cmake scripts.", false, - "Variables common to all CPack generators"); - - cm->DefineProperty - ("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION", cmProperty::VARIABLE, - "Ask CPack to error out as soon as a file with absolute INSTALL" - " DESTINATION is encountered.", - "The fatal error is emitted before the installation of " - "the offending file takes place. Some CPack generators, like NSIS," - "enforce this internally. " - "This variable triggers the definition of" - "CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION when CPack runs" - "Variables common to all CPack generators"); -} diff --git a/Source/CPack/cmCPackDocumentVariables.h b/Source/CPack/cmCPackDocumentVariables.h deleted file mode 100644 index e7971be..0000000 --- a/Source/CPack/cmCPackDocumentVariables.h +++ /dev/null @@ -1,21 +0,0 @@ -/*============================================================================ - CMake - Cross Platform Makefile Generator - Copyright 2000-2009 Kitware, Inc., Insight Software Consortium - - Distributed under the OSI-approved BSD License (the "License"); - see accompanying file Copyright.txt for details. - - This software is distributed WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the License for more information. -============================================================================*/ -#ifndef cmCPackDocumentVariables_h -#define cmCPackDocumentVariables_h -class cmake; -class cmCPackDocumentVariables -{ -public: - static void DefineVariables(cmake* cm); -}; - -#endif diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx index d973c01..dfb2f15 100644 --- a/Source/CPack/cmCPackDragNDropGenerator.cxx +++ b/Source/CPack/cmCPackDragNDropGenerator.cxx @@ -474,7 +474,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, udco_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL"); udco_image_command << " convert \"" << temp_image << "\""; udco_image_command << " -format UDCO"; - udco_image_command << " -o \"" << temp_udco << "\""; + udco_image_command << " -ov -o \"" << temp_udco << "\""; std::string error; if(!this->RunCommand(udco_image_command, &error)) @@ -504,6 +504,11 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, // Rez the SLA cmOStringStream embed_sla_command; embed_sla_command << this->GetOption("CPACK_COMMAND_REZ"); + const char* sysroot = this->GetOption("CPACK_OSX_SYSROOT"); + if(sysroot && sysroot[0] != '\0') + { + embed_sla_command << " -isysroot \"" << sysroot << "\""; + } embed_sla_command << " \"" << sla_r << "\""; embed_sla_command << " -a -o "; embed_sla_command << "\"" << temp_udco << "\""; diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 3c685bd..63a7596 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -26,7 +26,8 @@ #include <algorithm> #if defined(__HAIKU__) -#include <StorageKit.h> +#include <FindDirectory.h> +#include <StorageDefs.h> #endif //---------------------------------------------------------------------- @@ -1263,14 +1264,14 @@ const char* cmCPackGenerator::GetInstallPath() this->InstallPath += "-"; this->InstallPath += this->GetOption("CPACK_PACKAGE_VERSION"); #elif defined(__HAIKU__) - BPath dir; - if (find_directory(B_COMMON_DIRECTORY, &dir) == B_OK) + char dir[B_PATH_NAME_LENGTH]; + if (find_directory(B_SYSTEM_DIRECTORY, -1, false, dir, sizeof(dir)) == B_OK) { - this->InstallPath = dir.Path(); + this->InstallPath = dir; } else { - this->InstallPath = "/boot/common"; + this->InstallPath = "/boot/system"; } #else this->InstallPath = "/usr/local/"; diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h index 8fafef9..5cb2280 100644 --- a/Source/CPack/cmCPackGenerator.h +++ b/Source/CPack/cmCPackGenerator.h @@ -160,9 +160,10 @@ protected: * CPack specific generator may mangle CPACK_PACKAGE_FILE_NAME * with CPACK_COMPONENT_xxxx_<NAME>_DISPLAY_NAME if * CPACK_<GEN>_USE_DISPLAY_NAME_IN_FILENAME is ON. - * @param[in] initialPackageFileName - * @param[in] groupOrComponentName - * @param[in] isGroupName + * @param[in] initialPackageFileName the initial package name to be mangled + * @param[in] groupOrComponentName the name of the group/component + * @param[in] isGroupName true if previous name refers to a group, + * false otherwise */ virtual std::string GetComponentPackageFileName( const std::string& initialPackageFileName, @@ -172,7 +173,7 @@ protected: /** * Package the list of files and/or components which * has been prepared by the beginning of DoPackage. - * @pre @ref toplevel has been filled-in + * @pre the @ref toplevel has been filled-in * @pre the list of file @ref files has been populated * @pre packageFileNames contains at least 1 entry * @post packageFileNames may have been updated and contains diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index b188918..9f8cc14 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -14,8 +14,6 @@ // Need these for documentation support. #include "cmake.h" #include "cmDocumentation.h" -#include "cmCPackDocumentVariables.h" -#include "cmCPackDocumentMacros.h" #include "cmCPackGeneratorFactory.h" #include "cmCPackGenerator.h" #include "cmake.h" @@ -29,112 +27,35 @@ #include <cmsys/SystemTools.hxx> //---------------------------------------------------------------------------- -static const char * cmDocumentationName[][3] = +static const char * cmDocumentationName[][2] = { {0, - " cpack - Packaging driver provided by CMake.", 0}, - {0,0,0} + " cpack - Packaging driver provided by CMake."}, + {0,0} }; //---------------------------------------------------------------------------- -static const char * cmDocumentationUsage[][3] = +static const char * cmDocumentationUsage[][2] = { {0, - " cpack -G <generator> [options]", - 0}, - {0,0,0} + " cpack -G <generator> [options]"}, + {0,0} }; //---------------------------------------------------------------------------- -static const char * cmDocumentationDescription[][3] = +static const char * cmDocumentationOptions[][2] = { - {0, - "The \"cpack\" executable is the CMake packaging program. " - "CMake-generated build trees created for projects that use " - "the INSTALL_* commands have packaging support. " - "This program will generate the package.", 0}, - CMAKE_STANDARD_INTRODUCTION, - {0,0,0} -}; - -//---------------------------------------------------------------------------- -static const char * cmDocumentationOptions[][3] = -{ - {"-G <generator>", "Use the specified generator to generate package.", - "CPack may support multiple native packaging systems on certain " - "platforms. A generator is responsible for generating input files for " - "particular system and invoking that systems. Possible generator names " - "are specified in the Generators section." }, - {"-C <Configuration>", "Specify the project configuration", - "This option specifies the configuration that the project was build " - "with, for example 'Debug', 'Release'." }, - {"-D <var>=<value>", "Set a CPack variable.", \ - "Set a variable that can be used by the generator."}, \ - {"--config <config file>", "Specify the config file.", - "Specify the config file to use to create the package. By default " - "CPackConfig.cmake in the current directory will be used." }, - {"--verbose,-V","enable verbose output","Run cpack with verbose output."}, - {"--debug","enable debug output (for CPack developers)", - "Run cpack with debug output (for CPack developers)."}, - {"-P <package name>","override/define CPACK_PACKAGE_NAME", - "If the package name is not specified on cpack commmand line then" - "CPack.cmake defines it as CMAKE_PROJECT_NAME"}, - {"-R <package version>","override/define CPACK_PACKAGE_VERSION", - "If version is not specified on cpack command line then" - "CPack.cmake defines it from CPACK_PACKAGE_VERSION_[MAJOR|MINOR|PATCH]" - "look into CPack.cmake for detail"}, - {"-B <package directory>","override/define CPACK_PACKAGE_DIRECTORY", - "The directory where CPack will be doing its packaging work." - "The resulting package will be found there. Inside this directory" - "CPack creates '_CPack_Packages' sub-directory which is the" - "CPack temporary directory."}, - {"--vendor <vendor name>","override/define CPACK_PACKAGE_VENDOR", - "If vendor is not specified on cpack command line " - "(or inside CMakeLists.txt) then" - "CPack.cmake defines it with a default value"}, - {"--help-command cmd [file]", "Print help for a single command and exit.", - "Full documentation specific to the given command is displayed. " - "If a file is specified, the documentation is written into and the output " - "format is determined depending on the filename suffix. Supported are man " - "page, HTML, DocBook and plain text."}, - {"--help-command-list [file]", "List available commands and exit.", - "The list contains all commands for which help may be obtained by using " - "the --help-command argument followed by a command name. " - "If a file is specified, the documentation is written into and the output " - "format is determined depending on the filename suffix. Supported are man " - "page, HTML, DocBook and plain text."}, - {"--help-commands [file]", "Print help for all commands and exit.", - "Full documentation specific for all current command is displayed." - "If a file is specified, the documentation is written into and the output " - "format is determined depending on the filename suffix. Supported are man " - "page, HTML, DocBook and plain text."}, - {"--help-variable var [file]", - "Print help for a single variable and exit.", - "Full documentation specific to the given variable is displayed." - "If a file is specified, the documentation is written into and the output " - "format is determined depending on the filename suffix. Supported are man " - "page, HTML, DocBook and plain text."}, - {"--help-variable-list [file]", "List documented variables and exit.", - "The list contains all variables for which help may be obtained by using " - "the --help-variable argument followed by a variable name. If a file is " - "specified, the help is written into it." - "If a file is specified, the documentation is written into and the output " - "format is determined depending on the filename suffix. Supported are man " - "page, HTML, DocBook and plain text."}, - {"--help-variables [file]", "Print help for all variables and exit.", - "Full documentation for all variables is displayed." - "If a file is specified, the documentation is written into and the output " - "format is determined depending on the filename suffix. Supported are man " - "page, HTML, DocBook and plain text."}, - {0,0,0} -}; - -//---------------------------------------------------------------------------- -static const char * cmDocumentationSeeAlso[][3] = -{ - {0, "cmake", 0}, - {0, "ccmake", 0}, - {0, 0, 0} + {"-G <generator>", "Use the specified generator to generate package."}, + {"-C <Configuration>", "Specify the project configuration"}, + {"-D <var>=<value>", "Set a CPack variable."}, + {"--config <config file>", "Specify the config file."}, + {"--verbose,-V","enable verbose output"}, + {"--debug","enable debug output (for CPack developers)"}, + {"-P <package name>","override/define CPACK_PACKAGE_NAME"}, + {"-R <package version>","override/define CPACK_PACKAGE_VERSION"}, + {"-B <package directory>","override/define CPACK_PACKAGE_DIRECTORY"}, + {"--vendor <vendor name>","override/define CPACK_PACKAGE_VENDOR"}, + {0,0} }; //---------------------------------------------------------------------------- @@ -307,6 +228,7 @@ int main (int argc, char *argv[]) // This part is used for cpack documentation lookup as well. cminst.AddCMakePaths(); + doc.SetCMakeRoot(cminst.GetCacheDefinition("CMAKE_ROOT")); if ( parsed && !help ) { @@ -481,11 +403,6 @@ int main (int argc, char *argv[]) } if ( parsed ) { -#ifdef _WIN32 - std::string comspec = "cmw9xcom.exe"; - cmSystemTools::SetWindows9xComspecSubstitute(comspec.c_str()); -#endif - const char* projName = mf->GetDefinition("CPACK_PACKAGE_NAME"); cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE, "Use generator: " << cpackGenerator->GetNameOfClass() << std::endl); @@ -533,43 +450,8 @@ int main (int argc, char *argv[]) doc.SetName("cpack"); doc.SetSection("Name",cmDocumentationName); doc.SetSection("Usage",cmDocumentationUsage); - doc.SetSection("Description",cmDocumentationDescription); doc.PrependSection("Options",cmDocumentationOptions); - // statically (in C++ code) defined variables - cmCPackDocumentVariables::DefineVariables(&cminst); - - std::vector<cmDocumentationEntry> commands; - - std::string docedFile; - std::string docPath; - cmDocumentation::documentedModulesList_t docedModList; - - docedFile = globalMF->GetModulesFile("CPack.cmake"); - if (docedFile.length()!=0) - { - docPath = cmSystemTools::GetFilenamePath(docedFile.c_str()); - doc.getDocumentedModulesListInDir(docPath,"CPack*.cmake",docedModList); - } - - // parse the files for documentation. - cmDocumentation::documentedModulesList_t::iterator docedIt; - for (docedIt = docedModList.begin(); - docedIt!= docedModList.end(); ++docedIt) - { - doc.GetStructuredDocFromFile( - (docedIt->first).c_str(), - commands,&cminst); - } - - std::map<std::string,cmDocumentationSection *> propDocs; - cminst.GetPropertiesDocumentation(propDocs); - doc.SetSections(propDocs); - cminst.GetCommandDocumentation(commands,true,false); - // statically (in C++ code) defined macros/commands - cmCPackDocumentMacros::GetMacrosDocumentation(commands); - doc.SetSection("Commands",commands); - std::vector<cmDocumentationEntry> v; cmCPackGeneratorFactory::DescriptionsMap::const_iterator generatorIt; for( generatorIt = generators.GetGeneratorsList().begin(); @@ -579,12 +461,10 @@ int main (int argc, char *argv[]) cmDocumentationEntry e; e.Name = generatorIt->first.c_str(); e.Brief = generatorIt->second.c_str(); - e.Full = ""; v.push_back(e); } doc.SetSection("Generators",v); - doc.SetSeeAlsoList(cmDocumentationSeeAlso); #undef cout return doc.PrintRequestedDocumentation(std::cout)? 0:1; #define cout no_cout_use_cmCPack_Log |