diff options
Diffstat (limited to 'Source/CPack')
-rw-r--r-- | Source/CPack/IFW/cmCPackIFWGenerator.cxx | 4 | ||||
-rw-r--r-- | Source/CPack/IFW/cmCPackIFWInstaller.cxx | 2 | ||||
-rw-r--r-- | Source/CPack/IFW/cmCPackIFWPackage.cxx | 2 | ||||
-rw-r--r-- | Source/CPack/IFW/cmCPackIFWRepository.cxx | 2 | ||||
-rw-r--r-- | Source/CPack/WiX/cmCPackWIXGenerator.cxx | 6 | ||||
-rw-r--r-- | Source/CPack/cmCPackArchiveGenerator.cxx | 12 | ||||
-rw-r--r-- | Source/CPack/cmCPackComponentGroup.h | 25 | ||||
-rw-r--r-- | Source/CPack/cmCPackDebGenerator.cxx | 954 | ||||
-rw-r--r-- | Source/CPack/cmCPackDebGenerator.h | 2 | ||||
-rw-r--r-- | Source/CPack/cmCPackExtGenerator.cxx | 321 | ||||
-rw-r--r-- | Source/CPack/cmCPackExtGenerator.h | 88 | ||||
-rw-r--r-- | Source/CPack/cmCPackFreeBSDGenerator.cxx | 2 | ||||
-rw-r--r-- | Source/CPack/cmCPackGenerator.cxx | 584 | ||||
-rw-r--r-- | Source/CPack/cmCPackGenerator.h | 14 | ||||
-rw-r--r-- | Source/CPack/cmCPackGeneratorFactory.cxx | 5 | ||||
-rw-r--r-- | Source/CPack/cmCPackNSISGenerator.cxx | 10 | ||||
-rw-r--r-- | Source/CPack/cmCPackNuGetGenerator.cxx | 2 | ||||
-rw-r--r-- | Source/CPack/cmCPackProductBuildGenerator.cxx | 4 | ||||
-rw-r--r-- | Source/CPack/cmCPackRPMGenerator.cxx | 4 |
19 files changed, 1348 insertions, 695 deletions
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx index cf8334a..180c92e 100644 --- a/Source/CPack/IFW/cmCPackIFWGenerator.cxx +++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx @@ -90,7 +90,7 @@ int cmCPackIFWGenerator::PackageFiles() ifwCmd.c_str(), &output, &output, &retVal, nullptr, this->GeneratorVerbose, cmDuration::zero()); if (!res || retVal) { - cmGeneratedFileStream ofs(ifwTmpFile.c_str()); + cmGeneratedFileStream ofs(ifwTmpFile); ofs << "# Run command: " << ifwCmd << std::endl << "# Output:" << std::endl << output << std::endl; @@ -203,7 +203,7 @@ int cmCPackIFWGenerator::PackageFiles() ifwCmd.c_str(), &output, &output, &retVal, nullptr, this->GeneratorVerbose, cmDuration::zero()); if (!res || retVal) { - cmGeneratedFileStream ofs(ifwTmpFile.c_str()); + cmGeneratedFileStream ofs(ifwTmpFile); ofs << "# Run command: " << ifwCmd << std::endl << "# Output:" << std::endl << output << std::endl; diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx index 36cf08c..8f492af 100644 --- a/Source/CPack/IFW/cmCPackIFWInstaller.cxx +++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx @@ -306,7 +306,7 @@ void cmCPackIFWInstaller::GenerateInstallerFile() } // Output stream - cmGeneratedFileStream fout((this->Directory + "/config/config.xml").data()); + cmGeneratedFileStream fout(this->Directory + "/config/config.xml"); cmXMLWriter xout(fout); xout.StartDocument(); diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx index f24ab69..67e279c 100644 --- a/Source/CPack/IFW/cmCPackIFWPackage.cxx +++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx @@ -528,7 +528,7 @@ void cmCPackIFWPackage::GeneratePackageFile() } // Output stream - cmGeneratedFileStream fout((this->Directory + "/meta/package.xml").data()); + cmGeneratedFileStream fout(this->Directory + "/meta/package.xml"); cmXMLWriter xout(fout); xout.StartDocument(); diff --git a/Source/CPack/IFW/cmCPackIFWRepository.cxx b/Source/CPack/IFW/cmCPackIFWRepository.cxx index a01fc4e..987cad8 100644 --- a/Source/CPack/IFW/cmCPackIFWRepository.cxx +++ b/Source/CPack/IFW/cmCPackIFWRepository.cxx @@ -183,7 +183,7 @@ bool cmCPackIFWRepository::PatchUpdatesXml() this->Directory + "/repository/UpdatesPatch.xml"; // Output stream - cmGeneratedFileStream fout(updatesPatchXml.data()); + cmGeneratedFileStream fout(updatesPatchXml); cmXMLWriter xout(fout); xout.StartDocument(); diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx index e06efda..398ebd3 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx +++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx @@ -100,6 +100,10 @@ bool cmCPackWIXGenerator::RunCandleCommand(std::string const& sourceFile, command << " -ext " << QuotePath(ext); } + if (sourceFile.rfind(this->CPackTopLevel, 0) != 0) { + command << " " << QuotePath("-I" + this->CPackTopLevel); + } + AddCustomFlags("CPACK_WIX_CANDLE_EXTRA_FLAGS", command); command << " " << QuotePath(sourceFile); @@ -148,7 +152,7 @@ int cmCPackWIXGenerator::PackageFiles() bool cmCPackWIXGenerator::InitializeWiXConfiguration() { - if (!ReadListFile("CPackWIX.cmake")) { + if (!ReadListFile("Internal/CPack/CPackWIX.cmake")) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error while executing CPackWIX.cmake" << std::endl); return false; diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index b734bb4..ee1070f 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -103,18 +103,18 @@ int cmCPackArchiveGenerator::addOneComponentToArchive( */ #define DECLARE_AND_OPEN_ARCHIVE(filename, archive) \ cmGeneratedFileStream gf; \ - gf.Open((filename).c_str(), false, true); \ + gf.Open((filename), false, true); \ if (!GenerateHeader(&gf)) { \ cmCPackLogger(cmCPackLog::LOG_ERROR, \ - "Problem to generate Header for archive < " \ + "Problem to generate Header for archive <" \ << (filename) << ">." << std::endl); \ return 0; \ } \ cmArchiveWrite archive(gf, this->Compress, this->ArchiveFormat); \ if (!(archive)) { \ cmCPackLogger(cmCPackLog::LOG_ERROR, \ - "Problem to create archive < " \ - << (filename) << ">. ERROR =" << (archive).GetError() \ + "Problem to create archive <" \ + << (filename) << ">, ERROR = " << (archive).GetError() \ << std::endl); \ return 0; \ } @@ -262,9 +262,9 @@ int cmCPackArchiveGenerator::PackageFiles() archive.Add(rp, 0, nullptr, false); if (!archive) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "Problem while adding file< " + "Problem while adding file <" << file << "> to archive <" << packageFileNames[0] - << "> .ERROR =" << archive.GetError() << std::endl); + << ">, ERROR = " << archive.GetError() << std::endl); return 0; } } diff --git a/Source/CPack/cmCPackComponentGroup.h b/Source/CPack/cmCPackComponentGroup.h index f2907db..bb980d7 100644 --- a/Source/CPack/cmCPackComponentGroup.h +++ b/Source/CPack/cmCPackComponentGroup.h @@ -143,4 +143,29 @@ public: std::vector<cmCPackComponentGroup*> Subgroups; }; +/** \class cmCPackInstallCMakeProject + * \brief A single quadruplet from the CPACK_INSTALL_CMAKE_PROJECTS variable. + */ +class cmCPackInstallCMakeProject +{ +public: + /// The directory of the CMake project. + std::string Directory; + + /// The name of the CMake project. + std::string ProjectName; + + /// The name of the component (or component set) to install. + std::string Component; + + /// The subdirectory to install into. + std::string SubDirectory; + + /// The list of installation types. + std::vector<cmCPackInstallationType*> InstallationTypes; + + /// The list of components. + std::vector<cmCPackComponent*> Components; +}; + #endif diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx index 8a4c004..ea0ee58 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -12,11 +12,430 @@ #include "cm_sys_stat.h" #include "cmsys/Glob.hxx" +#include <map> #include <ostream> #include <set> #include <string.h> #include <utility> +namespace { + +class DebGenerator +{ +public: + DebGenerator(cmCPackLog* logger, std::string const& outputName, + std::string const& workDir, std::string const& topLevelDir, + std::string const& temporaryDir, + const char* debianCompressionType, + const char* debianArchiveType, + std::map<std::string, std::string> const& controlValues, + bool genShLibs, std::string const& shLibsFilename, + bool genPostInst, std::string const& postInst, bool genPostRm, + std::string const& postRm, const char* controlExtra, + bool permissionStrctPolicy, + std::vector<std::string> const& packageFiles); + + bool generate() const; + +private: + void generateDebianBinaryFile() const; + void generateControlFile() const; + bool generateDataTar() const; + std::string generateMD5File() const; + bool generateControlTar(std::string const& md5Filename) const; + bool generateDeb() const; + + cmCPackLog* Logger; + const std::string OutputName; + const std::string WorkDir; + std::string CompressionSuffix; + const std::string TopLevelDir; + const std::string TemporaryDir; + const char* DebianArchiveType; + const std::map<std::string, std::string> ControlValues; + const bool GenShLibs; + const std::string ShLibsFilename; + const bool GenPostInst; + const std::string PostInst; + const bool GenPostRm; + const std::string PostRm; + const char* ControlExtra; + const bool PermissionStrictPolicy; + const std::vector<std::string> PackageFiles; + cmArchiveWrite::Compress TarCompressionType; +}; + +DebGenerator::DebGenerator( + cmCPackLog* logger, std::string const& outputName, + std::string const& workDir, std::string const& topLevelDir, + std::string const& temporaryDir, const char* debianCompressionType, + const char* debianArchiveType, + std::map<std::string, std::string> const& controlValues, bool genShLibs, + std::string const& shLibsFilename, bool genPostInst, + std::string const& postInst, bool genPostRm, std::string const& postRm, + const char* controlExtra, bool permissionStrictPolicy, + std::vector<std::string> const& packageFiles) + : Logger(logger) + , OutputName(outputName) + , WorkDir(workDir) + , TopLevelDir(topLevelDir) + , TemporaryDir(temporaryDir) + , DebianArchiveType(debianArchiveType ? debianArchiveType : "paxr") + , ControlValues(controlValues) + , GenShLibs(genShLibs) + , ShLibsFilename(shLibsFilename) + , GenPostInst(genPostInst) + , PostInst(postInst) + , GenPostRm(genPostRm) + , PostRm(postRm) + , ControlExtra(controlExtra) + , PermissionStrictPolicy(permissionStrictPolicy) + , PackageFiles(packageFiles) +{ + if (!debianCompressionType) { + debianCompressionType = "gzip"; + } + + if (!strcmp(debianCompressionType, "lzma")) { + CompressionSuffix = ".lzma"; + TarCompressionType = cmArchiveWrite::CompressLZMA; + } else if (!strcmp(debianCompressionType, "xz")) { + CompressionSuffix = ".xz"; + TarCompressionType = cmArchiveWrite::CompressXZ; + } else if (!strcmp(debianCompressionType, "bzip2")) { + CompressionSuffix = ".bz2"; + TarCompressionType = cmArchiveWrite::CompressBZip2; + } else if (!strcmp(debianCompressionType, "gzip")) { + CompressionSuffix = ".gz"; + TarCompressionType = cmArchiveWrite::CompressGZip; + } else if (!strcmp(debianCompressionType, "none")) { + CompressionSuffix.clear(); + TarCompressionType = cmArchiveWrite::CompressNone; + } else { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error unrecognized compression type: " + << debianCompressionType << std::endl); + } +} + +bool DebGenerator::generate() const +{ + generateDebianBinaryFile(); + generateControlFile(); + if (!generateDataTar()) { + return false; + } + std::string md5Filename = generateMD5File(); + if (!generateControlTar(md5Filename)) { + return false; + } + return generateDeb(); +} + +void DebGenerator::generateDebianBinaryFile() const +{ + // debian-binary file + const std::string dbfilename = WorkDir + "/debian-binary"; + cmGeneratedFileStream out(dbfilename); + out << "2.0"; + out << std::endl; // required for valid debian package +} + +void DebGenerator::generateControlFile() const +{ + std::string ctlfilename = WorkDir + "/control"; + + cmGeneratedFileStream out(ctlfilename); + for (auto const& kv : ControlValues) { + out << kv.first << ": " << kv.second << "\n"; + } + + unsigned long totalSize = 0; + { + std::string dirName = TemporaryDir; + dirName += '/'; + for (std::string const& file : PackageFiles) { + totalSize += cmSystemTools::FileLength(file); + } + } + out << "Installed-Size: " << (totalSize + 1023) / 1024 << "\n"; + out << std::endl; +} + +bool DebGenerator::generateDataTar() const +{ + std::string filename_data_tar = WorkDir + "/data.tar" + CompressionSuffix; + cmGeneratedFileStream fileStream_data_tar; + fileStream_data_tar.Open(filename_data_tar, false, true); + if (!fileStream_data_tar) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error opening the file \"" + << filename_data_tar << "\" for writing" << std::endl); + return false; + } + cmArchiveWrite data_tar(fileStream_data_tar, TarCompressionType, + DebianArchiveType); + + // uid/gid should be the one of the root user, and this root user has + // always uid/gid equal to 0. + data_tar.SetUIDAndGID(0u, 0u); + data_tar.SetUNAMEAndGNAME("root", "root"); + + // now add all directories which have to be compressed + // collect all top level install dirs for that + // e.g. /opt/bin/foo, /usr/bin/bar and /usr/bin/baz would + // give /usr and /opt + size_t topLevelLength = WorkDir.length(); + cmCPackLogger(cmCPackLog::LOG_DEBUG, + "WDIR: \"" << WorkDir << "\", length = " << topLevelLength + << std::endl); + std::set<std::string> orderedFiles; + + // we have to reconstruct the parent folders as well + + for (std::string currentPath : PackageFiles) { + while (currentPath != WorkDir) { + // the last one IS WorkDir, but we do not want this one: + // XXX/application/usr/bin/myprogram with GEN_WDIR=XXX/application + // should not add XXX/application + orderedFiles.insert(currentPath); + currentPath = cmSystemTools::CollapseCombinedPath(currentPath, ".."); + } + } + + for (std::string const& file : orderedFiles) { + cmCPackLogger(cmCPackLog::LOG_DEBUG, + "FILEIT: \"" << file << "\"" << std::endl); + std::string::size_type slashPos = file.find('/', topLevelLength + 1); + std::string relativeDir = + file.substr(topLevelLength, slashPos - topLevelLength); + cmCPackLogger(cmCPackLog::LOG_DEBUG, + "RELATIVEDIR: \"" << relativeDir << "\"" << std::endl); + +#ifdef WIN32 + std::string mode_t_adt_filename = file + ":cmake_mode_t"; + cmsys::ifstream permissionStream(mode_t_adt_filename.c_str()); + + mode_t permissions = 0; + + if (permissionStream) { + permissionStream >> std::oct >> permissions; + } + + if (permissions != 0) { + data_tar.SetPermissions(permissions); + } else if (cmSystemTools::FileIsDirectory(file)) { + data_tar.SetPermissions(0755); + } else { + data_tar.ClearPermissions(); + } +#endif + + // do not recurse because the loop will do it + if (!data_tar.Add(file, topLevelLength, ".", false)) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Problem adding file to tar:" + << std::endl + << "#top level directory: " << WorkDir << std::endl + << "#file: " << file << std::endl + << "#error:" << data_tar.GetError() << std::endl); + return false; + } + } + return true; +} + +std::string DebGenerator::generateMD5File() const +{ + std::string md5filename = WorkDir + "/md5sums"; + + cmGeneratedFileStream out(md5filename); + + std::string topLevelWithTrailingSlash = TemporaryDir; + topLevelWithTrailingSlash += '/'; + for (std::string const& file : PackageFiles) { + // hash only regular files + if (cmSystemTools::FileIsDirectory(file) || + cmSystemTools::FileIsSymlink(file)) { + continue; + } + + std::string output = + cmSystemTools::ComputeFileHash(file, cmCryptoHash::AlgoMD5); + if (output.empty()) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Problem computing the md5 of " << file << std::endl); + } + + output += " " + file + "\n"; + // debian md5sums entries are like this: + // 014f3604694729f3bf19263bac599765 usr/bin/ccmake + // thus strip the full path (with the trailing slash) + cmSystemTools::ReplaceString(output, topLevelWithTrailingSlash.c_str(), + ""); + out << output; + } + // each line contains a eol. + // Do not end the md5sum file with yet another (invalid) + return md5filename; +} + +bool DebGenerator::generateControlTar(std::string const& md5Filename) const +{ + std::string filename_control_tar = WorkDir + "/control.tar.gz"; + + cmGeneratedFileStream fileStream_control_tar; + fileStream_control_tar.Open(filename_control_tar, false, true); + if (!fileStream_control_tar) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error opening the file \"" + << filename_control_tar << "\" for writing" << std::endl); + return false; + } + cmArchiveWrite control_tar(fileStream_control_tar, + cmArchiveWrite::CompressGZip, DebianArchiveType); + + // sets permissions and uid/gid for the files + control_tar.SetUIDAndGID(0u, 0u); + control_tar.SetUNAMEAndGNAME("root", "root"); + + /* permissions are set according to + https://www.debian.org/doc/debian-policy/ch-files.html#s-permissions-owners + and + https://lintian.debian.org/tags/control-file-has-bad-permissions.html + */ + const mode_t permission644 = 0644; + const mode_t permissionExecute = 0111; + const mode_t permission755 = permission644 | permissionExecute; + + // for md5sum and control (that we have generated here), we use 644 + // (RW-R--R--) + // so that deb lintian doesn't warn about it + control_tar.SetPermissions(permission644); + + // adds control and md5sums + if (!control_tar.Add(md5Filename, WorkDir.length(), ".") || + !control_tar.Add(WorkDir + "/control", WorkDir.length(), ".")) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error adding file to tar:" + << std::endl + << "#top level directory: " << WorkDir << std::endl + << "#file: \"control\" or \"md5sums\"" << std::endl + << "#error:" << control_tar.GetError() << std::endl); + return false; + } + + // adds generated shlibs file + if (GenShLibs) { + if (!control_tar.Add(ShLibsFilename, WorkDir.length(), ".")) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error adding file to tar:" + << std::endl + << "#top level directory: " << WorkDir << std::endl + << "#file: \"shlibs\"" << std::endl + << "#error:" << control_tar.GetError() << std::endl); + return false; + } + } + + // adds LDCONFIG related files + if (GenPostInst) { + control_tar.SetPermissions(permission755); + if (!control_tar.Add(PostInst, WorkDir.length(), ".")) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error adding file to tar:" + << std::endl + << "#top level directory: " << WorkDir << std::endl + << "#file: \"postinst\"" << std::endl + << "#error:" << control_tar.GetError() << std::endl); + return false; + } + control_tar.SetPermissions(permission644); + } + + if (GenPostRm) { + control_tar.SetPermissions(permission755); + if (!control_tar.Add(PostRm, WorkDir.length(), ".")) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error adding file to tar:" + << std::endl + << "#top level directory: " << WorkDir << std::endl + << "#file: \"postinst\"" << std::endl + << "#error:" << control_tar.GetError() << std::endl); + return false; + } + control_tar.SetPermissions(permission644); + } + + // for the other files, we use + // -either the original permission on the files + // -either a permission strictly defined by the Debian policies + if (ControlExtra) { + // permissions are now controlled by the original file permissions + + static const char* strictFiles[] = { "config", "postinst", "postrm", + "preinst", "prerm" }; + std::set<std::string> setStrictFiles( + strictFiles, strictFiles + sizeof(strictFiles) / sizeof(strictFiles[0])); + + // default + control_tar.ClearPermissions(); + + std::vector<std::string> controlExtraList; + cmSystemTools::ExpandListArgument(ControlExtra, controlExtraList); + for (std::string const& i : controlExtraList) { + std::string filenamename = cmsys::SystemTools::GetFilenameName(i); + std::string localcopy = WorkDir + "/" + filenamename; + + if (PermissionStrictPolicy) { + control_tar.SetPermissions( + setStrictFiles.count(filenamename) ? permission755 : permission644); + } + + // if we can copy the file, it means it does exist, let's add it: + if (cmsys::SystemTools::CopyFileIfDifferent(i, localcopy)) { + control_tar.Add(localcopy, WorkDir.length(), "."); + } + } + } + + return true; +} + +bool DebGenerator::generateDeb() const +{ + // ar -r your-package-name.deb debian-binary control.tar.* data.tar.* + // A debian package .deb is simply an 'ar' archive. The only subtle + // difference is that debian uses the BSD ar style archive whereas most + // Linux distro have a GNU ar. + // See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=161593 for more info + std::string const outputPath = TopLevelDir + "/" + OutputName; + std::string const tlDir = WorkDir + "/"; + cmGeneratedFileStream debStream; + debStream.Open(outputPath, false, true); + cmArchiveWrite deb(debStream, cmArchiveWrite::CompressNone, "arbsd"); + + // uid/gid should be the one of the root user, and this root user has + // always uid/gid equal to 0. + deb.SetUIDAndGID(0u, 0u); + deb.SetUNAMEAndGNAME("root", "root"); + + if (!deb.Add(tlDir + "debian-binary", tlDir.length()) || + !deb.Add(tlDir + "control.tar.gz", tlDir.length()) || + !deb.Add(tlDir + "data.tar" + CompressionSuffix, tlDir.length())) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error creating debian package:" + << std::endl + << "#top level directory: " << TopLevelDir << std::endl + << "#file: " << OutputName << std::endl + << "#error:" << deb.GetError() << std::endl); + return false; + } + return true; +} + +} // end anonymous namespace + cmCPackDebGenerator::cmCPackDebGenerator() { } @@ -61,25 +480,27 @@ int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel, component_path += packageName; this->SetOption("CPACK_DEB_PACKAGE_COMPONENT_PART_PATH", component_path.c_str()); - if (!this->ReadListFile("CPackDeb.cmake")) { + if (!this->ReadListFile("Internal/CPack/CPackDeb.cmake")) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error while execution CPackDeb.cmake" << std::endl); retval = 0; return retval; } - cmsys::Glob gl; - std::string findExpr(this->GetOption("GEN_WDIR")); - findExpr += "/*"; - gl.RecurseOn(); - gl.SetRecurseListDirs(true); - if (!gl.FindFiles(findExpr)) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Cannot find any files in the installed directory" - << std::endl); - return 0; + { // Isolate globbing of binaries vs. dbgsyms + cmsys::Glob gl; + std::string findExpr(this->GetOption("GEN_WDIR")); + findExpr += "/*"; + gl.RecurseOn(); + gl.SetRecurseListDirs(true); + if (!gl.FindFiles(findExpr)) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Cannot find any files in the installed directory" + << std::endl); + return 0; + } + packageFiles = gl.GetFiles(); } - packageFiles = gl.GetFiles(); int res = createDeb(); if (res != 1) { @@ -90,6 +511,32 @@ int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel, packageFileName += "/"; packageFileName += this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME"); packageFileNames.push_back(std::move(packageFileName)); + + if (this->IsOn("GEN_CPACK_DEBIAN_DEBUGINFO_PACKAGE")) { + cmsys::Glob gl; + std::string findExpr(this->GetOption("GEN_DBGSYMDIR")); + findExpr += "/*"; + gl.RecurseOn(); + gl.SetRecurseListDirs(true); + if (!gl.FindFiles(findExpr)) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Cannot find any files in the installed directory" + << std::endl); + return 0; + } + packageFiles = gl.GetFiles(); + + res = createDbgsymDDeb(); + if (res != 1) { + retval = 0; + } + // add the generated package to package file names list + packageFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); + packageFileName += "/"; + packageFileName += this->GetOption("GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME"); + packageFileNames.push_back(std::move(packageFileName)); + } + return retval; } @@ -179,7 +626,7 @@ int cmCPackDebGenerator::PackageComponentsAllInOne( this->SetOption("CPACK_DEB_PACKAGE_COMPONENT_PART_PATH", component_path.c_str()); } - if (!this->ReadListFile("CPackDeb.cmake")) { + if (!this->ReadListFile("Internal/CPack/CPackDeb.cmake")) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error while execution CPackDeb.cmake" << std::endl); retval = 0; @@ -234,112 +681,81 @@ int cmCPackDebGenerator::PackageFiles() int cmCPackDebGenerator::createDeb() { - // debian-binary file - const std::string strGenWDIR(this->GetOption("GEN_WDIR")); - const std::string dbfilename = strGenWDIR + "/debian-binary"; - { // the scope is needed for cmGeneratedFileStream - cmGeneratedFileStream out(dbfilename.c_str()); - out << "2.0"; - out << std::endl; // required for valid debian package - } - - // control file - std::string ctlfilename = strGenWDIR + "/control"; + std::map<std::string, std::string> controlValues; // debian policy enforce lower case for package name - // mandatory entries: - std::string debian_pkg_name = cmsys::SystemTools::LowerCase( + controlValues["Package"] = cmsys::SystemTools::LowerCase( this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_NAME")); - const char* debian_pkg_version = + controlValues["Version"] = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_VERSION"); - const char* debian_pkg_section = + controlValues["Section"] = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SECTION"); - const char* debian_pkg_priority = + controlValues["Priority"] = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PRIORITY"); - const char* debian_pkg_arch = + controlValues["Architecture"] = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_ARCHITECTURE"); - const char* maintainer = + controlValues["Maintainer"] = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_MAINTAINER"); - const char* desc = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_DESCRIPTION"); + controlValues["Description"] = + this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_DESCRIPTION"); - // optional entries + const char* debian_pkg_source = + this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SOURCE"); + if (debian_pkg_source && *debian_pkg_source) { + controlValues["Source"] = debian_pkg_source; + } const char* debian_pkg_dep = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_DEPENDS"); + if (debian_pkg_dep && *debian_pkg_dep) { + controlValues["Depends"] = debian_pkg_dep; + } const char* debian_pkg_rec = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_RECOMMENDS"); + if (debian_pkg_rec && *debian_pkg_rec) { + controlValues["Recommends"] = debian_pkg_rec; + } const char* debian_pkg_sug = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SUGGESTS"); + if (debian_pkg_sug && *debian_pkg_sug) { + controlValues["Suggests"] = debian_pkg_sug; + } const char* debian_pkg_url = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_HOMEPAGE"); + if (debian_pkg_url && *debian_pkg_url) { + controlValues["Homepage"] = debian_pkg_url; + } const char* debian_pkg_predep = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PREDEPENDS"); + if (debian_pkg_predep && *debian_pkg_predep) { + controlValues["Pre-Depends"] = debian_pkg_predep; + } const char* debian_pkg_enhances = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_ENHANCES"); + if (debian_pkg_enhances && *debian_pkg_enhances) { + controlValues["Enhances"] = debian_pkg_enhances; + } const char* debian_pkg_breaks = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_BREAKS"); + if (debian_pkg_breaks && *debian_pkg_breaks) { + controlValues["Breaks"] = debian_pkg_breaks; + } const char* debian_pkg_conflicts = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_CONFLICTS"); + if (debian_pkg_conflicts && *debian_pkg_conflicts) { + controlValues["Conflicts"] = debian_pkg_conflicts; + } const char* debian_pkg_provides = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PROVIDES"); + if (debian_pkg_provides && *debian_pkg_provides) { + controlValues["Provides"] = debian_pkg_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()); - out << "Package: " << debian_pkg_name << "\n"; - out << "Version: " << debian_pkg_version << "\n"; - 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"; - } - if (debian_pkg_rec && *debian_pkg_rec) { - out << "Recommends: " << debian_pkg_rec << "\n"; - } - if (debian_pkg_sug && *debian_pkg_sug) { - out << "Suggests: " << debian_pkg_sug << "\n"; - } - if (debian_pkg_url && *debian_pkg_url) { - out << "Homepage: " << debian_pkg_url << "\n"; - } - if (debian_pkg_predep && *debian_pkg_predep) { - out << "Pre-Depends: " << debian_pkg_predep << "\n"; - } - if (debian_pkg_enhances && *debian_pkg_enhances) { - out << "Enhances: " << debian_pkg_enhances << "\n"; - } - if (debian_pkg_breaks && *debian_pkg_breaks) { - out << "Breaks: " << debian_pkg_breaks << "\n"; - } - if (debian_pkg_conflicts && *debian_pkg_conflicts) { - out << "Conflicts: " << debian_pkg_conflicts << "\n"; - } - if (debian_pkg_provides && *debian_pkg_provides) { - out << "Provides: " << debian_pkg_provides << "\n"; - } - if (debian_pkg_replaces && *debian_pkg_replaces) { - out << "Replaces: " << debian_pkg_replaces << "\n"; - } - unsigned long totalSize = 0; - { - std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY"); - dirName += '/'; - for (std::string const& file : packageFiles) { - totalSize += cmSystemTools::FileLength(file); - } - } - out << "Installed-Size: " << (totalSize + 1023) / 1024 << "\n"; - out << "Maintainer: " << maintainer << "\n"; - out << "Description: " << desc << "\n"; - out << std::endl; + if (debian_pkg_replaces && *debian_pkg_replaces) { + controlValues["Replaces"] = debian_pkg_replaces; } + const std::string strGenWDIR(this->GetOption("GEN_WDIR")); const std::string shlibsfilename = strGenWDIR + "/shlibs"; const char* debian_pkg_shlibs = @@ -347,7 +763,7 @@ int cmCPackDebGenerator::createDeb() const bool gen_shibs = this->IsOn("CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS") && debian_pkg_shlibs && *debian_pkg_shlibs; if (gen_shibs) { - cmGeneratedFileStream out(shlibsfilename.c_str()); + cmGeneratedFileStream out(shlibsfilename); out << debian_pkg_shlibs; out << std::endl; } @@ -355,7 +771,7 @@ int cmCPackDebGenerator::createDeb() const std::string postinst = strGenWDIR + "/postinst"; const std::string postrm = strGenWDIR + "/postrm"; if (this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTINST")) { - cmGeneratedFileStream out(postinst.c_str()); + cmGeneratedFileStream out(postinst); out << "#!/bin/sh\n\n" "set -e\n\n" "if [ \"$1\" = \"configure\" ]; then\n" @@ -363,7 +779,7 @@ int cmCPackDebGenerator::createDeb() "fi\n"; } if (this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTRM")) { - cmGeneratedFileStream out(postrm.c_str()); + cmGeneratedFileStream out(postrm); out << "#!/bin/sh\n\n" "set -e\n\n" "if [ \"$1\" = \"remove\" ]; then\n" @@ -371,314 +787,74 @@ int cmCPackDebGenerator::createDeb() "fi\n"; } - cmArchiveWrite::Compress tar_compression_type = cmArchiveWrite::CompressGZip; - const char* debian_compression_type = - this->GetOption("GEN_CPACK_DEBIAN_COMPRESSION_TYPE"); - if (!debian_compression_type) { - debian_compression_type = "gzip"; - } - - std::string compression_suffix; - if (!strcmp(debian_compression_type, "lzma")) { - compression_suffix = ".lzma"; - tar_compression_type = cmArchiveWrite::CompressLZMA; - } else if (!strcmp(debian_compression_type, "xz")) { - compression_suffix = ".xz"; - tar_compression_type = cmArchiveWrite::CompressXZ; - } else if (!strcmp(debian_compression_type, "bzip2")) { - compression_suffix = ".bz2"; - tar_compression_type = cmArchiveWrite::CompressBZip2; - } else if (!strcmp(debian_compression_type, "gzip")) { - compression_suffix = ".gz"; - tar_compression_type = cmArchiveWrite::CompressGZip; - } else if (!strcmp(debian_compression_type, "none")) { - compression_suffix.clear(); - tar_compression_type = cmArchiveWrite::CompressNone; - } else { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Error unrecognized compression type: " - << debian_compression_type << std::endl); - } - - const char* debian_archive_type = - this->GetOption("GEN_CPACK_DEBIAN_ARCHIVE_TYPE"); - if (!debian_archive_type) { - debian_archive_type = "paxr"; + DebGenerator gen( + Logger, this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME"), strGenWDIR, + this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), + this->GetOption("CPACK_TEMPORARY_DIRECTORY"), + this->GetOption("GEN_CPACK_DEBIAN_COMPRESSION_TYPE"), + this->GetOption("GEN_CPACK_DEBIAN_ARCHIVE_TYPE"), controlValues, gen_shibs, + shlibsfilename, this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTINST"), postinst, + this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTRM"), postrm, + this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA"), + this->IsSet("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION"), + packageFiles); + + if (!gen.generate()) { + return 0; } + return 1; +} - std::string filename_data_tar = - strGenWDIR + "/data.tar" + compression_suffix; - - // atomic file generation for data.tar - { - cmGeneratedFileStream fileStream_data_tar; - fileStream_data_tar.Open(filename_data_tar.c_str(), false, true); - if (!fileStream_data_tar) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Error opening the file \"" - << filename_data_tar << "\" for writing" << std::endl); - return 0; - } - cmArchiveWrite data_tar(fileStream_data_tar, tar_compression_type, - debian_archive_type); - - // uid/gid should be the one of the root user, and this root user has - // always uid/gid equal to 0. - data_tar.SetUIDAndGID(0u, 0u); - data_tar.SetUNAMEAndGNAME("root", "root"); - - // now add all directories which have to be compressed - // collect all top level install dirs for that - // e.g. /opt/bin/foo, /usr/bin/bar and /usr/bin/baz would - // give /usr and /opt - size_t topLevelLength = strGenWDIR.length(); - cmCPackLogger(cmCPackLog::LOG_DEBUG, - "WDIR: \"" << strGenWDIR << "\", length = " << topLevelLength - << std::endl); - std::set<std::string> orderedFiles; - - // we have to reconstruct the parent folders as well - - for (std::string currentPath : packageFiles) { - while (currentPath != strGenWDIR) { - // the last one IS strGenWDIR, but we do not want this one: - // XXX/application/usr/bin/myprogram with GEN_WDIR=XXX/application - // should not add XXX/application - orderedFiles.insert(currentPath); - currentPath = cmSystemTools::CollapseCombinedPath(currentPath, ".."); - } - } - - for (std::string const& file : orderedFiles) { - cmCPackLogger(cmCPackLog::LOG_DEBUG, - "FILEIT: \"" << file << "\"" << std::endl); - std::string::size_type slashPos = file.find('/', topLevelLength + 1); - std::string relativeDir = - file.substr(topLevelLength, slashPos - topLevelLength); - cmCPackLogger(cmCPackLog::LOG_DEBUG, - "RELATIVEDIR: \"" << relativeDir << "\"" << std::endl); - -#ifdef WIN32 - std::string mode_t_adt_filename = file + ":cmake_mode_t"; - cmsys::ifstream permissionStream(mode_t_adt_filename.c_str()); - - mode_t permissions = 0; - - if (permissionStream) { - permissionStream >> std::oct >> permissions; - } - - if (permissions != 0) { - data_tar.SetPermissions(permissions); - } else if (cmSystemTools::FileIsDirectory(file)) { - data_tar.SetPermissions(0755); - } else { - data_tar.ClearPermissions(); - } -#endif - - // do not recurse because the loop will do it - if (!data_tar.Add(file, topLevelLength, ".", false)) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Problem adding file to tar:" - << std::endl - << "#top level directory: " << strGenWDIR << std::endl - << "#file: " << file << std::endl - << "#error:" << data_tar.GetError() << std::endl); - return 0; - } - } - } // scope for file generation +int cmCPackDebGenerator::createDbgsymDDeb() +{ + // Packages containing debug symbols follow the same structure as .debs + // but have different metadata and content. - std::string md5filename = strGenWDIR + "/md5sums"; - { - // the scope is needed for cmGeneratedFileStream - cmGeneratedFileStream out(md5filename.c_str()); - - std::string topLevelWithTrailingSlash = - this->GetOption("CPACK_TEMPORARY_DIRECTORY"); - topLevelWithTrailingSlash += '/'; - for (std::string const& file : packageFiles) { - // hash only regular files - if (cmSystemTools::FileIsDirectory(file) || - cmSystemTools::FileIsSymlink(file)) { - continue; - } + std::map<std::string, std::string> controlValues; + // debian policy enforce lower case for package name + std::string packageNameLower = cmsys::SystemTools::LowerCase( + this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_NAME")); + const char* debian_pkg_version = + this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_VERSION"); - std::string output = - cmSystemTools::ComputeFileHash(file, cmCryptoHash::AlgoMD5); - if (output.empty()) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Problem computing the md5 of " << file << std::endl); - } + controlValues["Package"] = packageNameLower + "-dbgsym"; + controlValues["Package-Type"] = "ddeb"; + controlValues["Version"] = debian_pkg_version; + controlValues["Auto-Built-Package"] = "debug-symbols"; + controlValues["Depends"] = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_NAME") + + std::string(" (= ") + debian_pkg_version + ")"; + controlValues["Section"] = "debug"; + controlValues["Priority"] = "optional"; + controlValues["Architecture"] = + this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_ARCHITECTURE"); + controlValues["Maintainer"] = + this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_MAINTAINER"); + controlValues["Description"] = + std::string("debug symbols for ") + packageNameLower; - output += " " + file + "\n"; - // debian md5sums entries are like this: - // 014f3604694729f3bf19263bac599765 usr/bin/ccmake - // thus strip the full path (with the trailing slash) - cmSystemTools::ReplaceString(output, topLevelWithTrailingSlash.c_str(), - ""); - out << output; - } - // each line contains a eol. - // Do not end the md5sum file with yet another (invalid) + const char* debian_pkg_source = + this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SOURCE"); + if (debian_pkg_source && *debian_pkg_source) { + controlValues["Source"] = debian_pkg_source; } - - std::string filename_control_tar = strGenWDIR + "/control.tar.gz"; - // atomic file generation for control.tar - { - cmGeneratedFileStream fileStream_control_tar; - fileStream_control_tar.Open(filename_control_tar.c_str(), false, true); - if (!fileStream_control_tar) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Error opening the file \"" << filename_control_tar - << "\" for writing" - << std::endl); - return 0; - } - cmArchiveWrite control_tar(fileStream_control_tar, - cmArchiveWrite::CompressGZip, - debian_archive_type); - - // sets permissions and uid/gid for the files - control_tar.SetUIDAndGID(0u, 0u); - control_tar.SetUNAMEAndGNAME("root", "root"); - - /* permissions are set according to - https://www.debian.org/doc/debian-policy/ch-files.html#s-permissions-owners - and - https://lintian.debian.org/tags/control-file-has-bad-permissions.html - */ - const mode_t permission644 = 0644; - const mode_t permissionExecute = 0111; - const mode_t permission755 = permission644 | permissionExecute; - - // for md5sum and control (that we have generated here), we use 644 - // (RW-R--R--) - // so that deb lintian doesn't warn about it - control_tar.SetPermissions(permission644); - - // adds control and md5sums - if (!control_tar.Add(md5filename, strGenWDIR.length(), ".") || - !control_tar.Add(strGenWDIR + "/control", strGenWDIR.length(), ".")) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Error adding file to tar:" - << std::endl - << "#top level directory: " << strGenWDIR << std::endl - << "#file: \"control\" or \"md5sums\"" << std::endl - << "#error:" << control_tar.GetError() << std::endl); - return 0; - } - - // adds generated shlibs file - if (gen_shibs) { - if (!control_tar.Add(shlibsfilename, strGenWDIR.length(), ".")) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Error adding file to tar:" - << std::endl - << "#top level directory: " << strGenWDIR << std::endl - << "#file: \"shlibs\"" << std::endl - << "#error:" << control_tar.GetError() << std::endl); - return 0; - } - } - - // adds LDCONFIG related files - if (this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTINST")) { - control_tar.SetPermissions(permission755); - if (!control_tar.Add(postinst, strGenWDIR.length(), ".")) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Error adding file to tar:" - << std::endl - << "#top level directory: " << strGenWDIR << std::endl - << "#file: \"postinst\"" << std::endl - << "#error:" << control_tar.GetError() << std::endl); - return 0; - } - control_tar.SetPermissions(permission644); - } - - if (this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTRM")) { - control_tar.SetPermissions(permission755); - if (!control_tar.Add(postrm, strGenWDIR.length(), ".")) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Error adding file to tar:" - << std::endl - << "#top level directory: " << strGenWDIR << std::endl - << "#file: \"postinst\"" << std::endl - << "#error:" << control_tar.GetError() << std::endl); - return 0; - } - control_tar.SetPermissions(permission644); - } - - // for the other files, we use - // -either the original permission on the files - // -either a permission strictly defined by the Debian policies - const char* controlExtra = - this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA"); - if (controlExtra) { - // permissions are now controlled by the original file permissions - - const bool permissionStrictPolicy = - this->IsSet("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION"); - - static const char* strictFiles[] = { "config", "postinst", "postrm", - "preinst", "prerm" }; - std::set<std::string> setStrictFiles( - strictFiles, - strictFiles + sizeof(strictFiles) / sizeof(strictFiles[0])); - - // default - control_tar.ClearPermissions(); - - std::vector<std::string> controlExtraList; - cmSystemTools::ExpandListArgument(controlExtra, controlExtraList); - for (std::string const& i : controlExtraList) { - std::string filenamename = cmsys::SystemTools::GetFilenameName(i); - std::string localcopy = strGenWDIR + "/" + filenamename; - - if (permissionStrictPolicy) { - control_tar.SetPermissions(setStrictFiles.count(filenamename) - ? permission755 - : permission644); - } - - // if we can copy the file, it means it does exist, let's add it: - if (cmsys::SystemTools::CopyFileIfDifferent(i, localcopy)) { - control_tar.Add(localcopy, strGenWDIR.length(), "."); - } - } - } + const char* debian_build_ids = this->GetOption("GEN_BUILD_IDS"); + if (debian_build_ids && *debian_build_ids) { + controlValues["Build-Ids"] = debian_build_ids; } - // ar -r your-package-name.deb debian-binary control.tar.* data.tar.* - // A debian package .deb is simply an 'ar' archive. The only subtle - // difference is that debian uses the BSD ar style archive whereas most - // Linux distro have a GNU ar. - // See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=161593 for more info - std::string const outputDir = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - std::string const outputName = this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME"); - std::string const outputPath = outputDir + "/" + outputName; - std::string const tlDir = strGenWDIR + "/"; - cmGeneratedFileStream debStream; - debStream.Open(outputPath.c_str(), false, true); - cmArchiveWrite deb(debStream, cmArchiveWrite::CompressNone, "arbsd"); + DebGenerator gen( + Logger, this->GetOption("GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME"), + this->GetOption("GEN_DBGSYMDIR"), - // uid/gid should be the one of the root user, and this root user has - // always uid/gid equal to 0. - deb.SetUIDAndGID(0u, 0u); - deb.SetUNAMEAndGNAME("root", "root"); + this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), + this->GetOption("CPACK_TEMPORARY_DIRECTORY"), + this->GetOption("GEN_CPACK_DEBIAN_COMPRESSION_TYPE"), + this->GetOption("GEN_CPACK_DEBIAN_ARCHIVE_TYPE"), controlValues, false, "", + false, "", false, "", nullptr, + this->IsSet("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION"), + packageFiles); - if (!deb.Add(tlDir + "debian-binary", tlDir.length()) || - !deb.Add(tlDir + "control.tar.gz", tlDir.length()) || - !deb.Add(tlDir + "data.tar" + compression_suffix, tlDir.length())) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Error creating debian package:" - << std::endl - << "#top level directory: " << outputDir << std::endl - << "#file: " << outputName << std::endl - << "#error:" << deb.GetError() << std::endl); + if (!gen.generate()) { return 0; } return 1; diff --git a/Source/CPack/cmCPackDebGenerator.h b/Source/CPack/cmCPackDebGenerator.h index b4f0c79..2244fe7 100644 --- a/Source/CPack/cmCPackDebGenerator.h +++ b/Source/CPack/cmCPackDebGenerator.h @@ -65,6 +65,8 @@ protected: private: int createDeb(); + int createDbgsymDDeb(); + std::vector<std::string> packageFiles; }; diff --git a/Source/CPack/cmCPackExtGenerator.cxx b/Source/CPack/cmCPackExtGenerator.cxx new file mode 100644 index 0000000..4c560b9 --- /dev/null +++ b/Source/CPack/cmCPackExtGenerator.cxx @@ -0,0 +1,321 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmCPackExtGenerator.h" + +#include "cmAlgorithms.h" +#include "cmCPackComponentGroup.h" +#include "cmCPackLog.h" +#include "cmMakefile.h" +#include "cmSystemTools.h" + +#include "cm_jsoncpp_value.h" +#include "cm_jsoncpp_writer.h" + +#include "cmsys/FStream.hxx" + +#include <utility> +#include <vector> + +int cmCPackExtGenerator::InitializeInternal() +{ + this->SetOption("CPACK_EXT_KNOWN_VERSIONS", "1.0"); + + if (!this->ReadListFile("Internal/CPack/CPackExt.cmake")) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error while executing CPackExt.cmake" << std::endl); + return 0; + } + + std::string major = this->GetOption("CPACK_EXT_SELECTED_MAJOR"); + if (major == "1") { + this->Generator = cm::make_unique<cmCPackExtVersion1Generator>(this); + } + + return this->Superclass::InitializeInternal(); +} + +int cmCPackExtGenerator::PackageFiles() +{ + Json::StreamWriterBuilder builder; + builder["indentation"] = " "; + + std::string filename = "package.json"; + if (!this->packageFileNames.empty()) { + filename = this->packageFileNames[0]; + } + + cmsys::ofstream fout(filename.c_str()); + std::unique_ptr<Json::StreamWriter> jout(builder.newStreamWriter()); + + Json::Value root(Json::objectValue); + + if (!this->Generator->WriteToJSON(root)) { + return 0; + } + + if (jout->write(root, &fout)) { + return 0; + } + + const char* packageScript = this->GetOption("CPACK_EXT_PACKAGE_SCRIPT"); + if (packageScript && *packageScript) { + if (!cmSystemTools::FileIsFullPath(packageScript)) { + cmCPackLogger( + cmCPackLog::LOG_ERROR, + "CPACK_EXT_PACKAGE_SCRIPT does not contain a full file path" + << std::endl); + return 0; + } + + int res = this->MakefileMap->ReadListFile(packageScript); + + if (cmSystemTools::GetErrorOccuredFlag() || !res) { + return 0; + } + } + + return 1; +} + +bool cmCPackExtGenerator::SupportsComponentInstallation() const +{ + return true; +} + +int cmCPackExtGenerator::InstallProjectViaInstallCommands( + bool setDestDir, const std::string& tempInstallDirectory) +{ + if (this->StagingEnabled()) { + return cmCPackGenerator::InstallProjectViaInstallCommands( + setDestDir, tempInstallDirectory); + } + + return 1; +} + +int cmCPackExtGenerator::InstallProjectViaInstallScript( + bool setDestDir, const std::string& tempInstallDirectory) +{ + if (this->StagingEnabled()) { + return cmCPackGenerator::InstallProjectViaInstallScript( + setDestDir, tempInstallDirectory); + } + + return 1; +} + +int cmCPackExtGenerator::InstallProjectViaInstalledDirectories( + bool setDestDir, const std::string& tempInstallDirectory, + const mode_t* default_dir_mode) +{ + if (this->StagingEnabled()) { + return cmCPackGenerator::InstallProjectViaInstalledDirectories( + setDestDir, tempInstallDirectory, default_dir_mode); + } + + return 1; +} + +int cmCPackExtGenerator::RunPreinstallTarget( + const std::string& installProjectName, const std::string& installDirectory, + cmGlobalGenerator* globalGenerator, const std::string& buildConfig) +{ + if (this->StagingEnabled()) { + return cmCPackGenerator::RunPreinstallTarget( + installProjectName, installDirectory, globalGenerator, buildConfig); + } + + return 1; +} + +int cmCPackExtGenerator::InstallCMakeProject( + bool setDestDir, const std::string& installDirectory, + const std::string& baseTempInstallDirectory, const mode_t* default_dir_mode, + const std::string& component, bool componentInstall, + const std::string& installSubDirectory, const std::string& buildConfig, + std::string& absoluteDestFiles) +{ + if (this->StagingEnabled()) { + return cmCPackGenerator::InstallCMakeProject( + setDestDir, installDirectory, baseTempInstallDirectory, default_dir_mode, + component, componentInstall, installSubDirectory, buildConfig, + absoluteDestFiles); + } + + return 1; +} + +bool cmCPackExtGenerator::StagingEnabled() const +{ + return !cmSystemTools::IsOff(this->GetOption("CPACK_EXT_ENABLE_STAGING")); +} + +cmCPackExtGenerator::cmCPackExtVersionGenerator::cmCPackExtVersionGenerator( + cmCPackExtGenerator* parent) + : Parent(parent) +{ +} + +int cmCPackExtGenerator::cmCPackExtVersionGenerator::WriteVersion( + Json::Value& root) +{ + root["formatVersionMajor"] = this->GetVersionMajor(); + root["formatVersionMinor"] = this->GetVersionMinor(); + + return 1; +} + +int cmCPackExtGenerator::cmCPackExtVersionGenerator::WriteToJSON( + Json::Value& root) +{ + if (!this->WriteVersion(root)) { + return 0; + } + + const char* packageName = this->Parent->GetOption("CPACK_PACKAGE_NAME"); + if (packageName) { + root["packageName"] = packageName; + } + + const char* packageVersion = + this->Parent->GetOption("CPACK_PACKAGE_VERSION"); + if (packageVersion) { + root["packageVersion"] = packageVersion; + } + + const char* packageDescriptionFile = + this->Parent->GetOption("CPACK_PACKAGE_DESCRIPTION_FILE"); + if (packageDescriptionFile) { + root["packageDescriptionFile"] = packageDescriptionFile; + } + + const char* packageDescriptionSummary = + this->Parent->GetOption("CPACK_PACKAGE_DESCRIPTION_SUMMARY"); + if (packageDescriptionSummary) { + root["packageDescriptionSummary"] = packageDescriptionSummary; + } + + const char* buildConfigCstr = this->Parent->GetOption("CPACK_BUILD_CONFIG"); + if (buildConfigCstr) { + root["buildConfig"] = buildConfigCstr; + } + + const char* defaultDirectoryPermissions = + this->Parent->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS"); + if (defaultDirectoryPermissions && *defaultDirectoryPermissions) { + root["defaultDirectoryPermissions"] = defaultDirectoryPermissions; + } + if (cmSystemTools::IsInternallyOn( + this->Parent->GetOption("CPACK_SET_DESTDIR"))) { + root["setDestdir"] = true; + root["packagingInstallPrefix"] = + this->Parent->GetOption("CPACK_PACKAGING_INSTALL_PREFIX"); + } else { + root["setDestdir"] = false; + } + + root["stripFiles"] = + !cmSystemTools::IsOff(this->Parent->GetOption("CPACK_STRIP_FILES")); + root["warnOnAbsoluteInstallDestination"] = + this->Parent->IsOn("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION"); + root["errorOnAbsoluteInstallDestination"] = + this->Parent->IsOn("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION"); + + Json::Value& projects = root["projects"] = Json::Value(Json::arrayValue); + for (auto& project : this->Parent->CMakeProjects) { + Json::Value jsonProject(Json::objectValue); + + jsonProject["projectName"] = project.ProjectName; + jsonProject["component"] = project.Component; + jsonProject["directory"] = project.Directory; + jsonProject["subDirectory"] = project.SubDirectory; + + Json::Value& installationTypes = jsonProject["installationTypes"] = + Json::Value(Json::arrayValue); + for (auto& installationType : project.InstallationTypes) { + installationTypes.append(installationType->Name); + } + + Json::Value& components = jsonProject["components"] = + Json::Value(Json::arrayValue); + for (auto& component : project.Components) { + components.append(component->Name); + } + + projects.append(jsonProject); + } + + Json::Value& installationTypes = root["installationTypes"] = + Json::Value(Json::objectValue); + for (auto& installationType : this->Parent->InstallationTypes) { + Json::Value& jsonInstallationType = + installationTypes[installationType.first] = + Json::Value(Json::objectValue); + + jsonInstallationType["name"] = installationType.second.Name; + jsonInstallationType["displayName"] = installationType.second.DisplayName; + jsonInstallationType["index"] = installationType.second.Index; + } + + Json::Value& components = root["components"] = + Json::Value(Json::objectValue); + for (auto& component : this->Parent->Components) { + Json::Value& jsonComponent = components[component.first] = + Json::Value(Json::objectValue); + + jsonComponent["name"] = component.second.Name; + jsonComponent["displayName"] = component.second.DisplayName; + if (component.second.Group) { + jsonComponent["group"] = component.second.Group->Name; + } + jsonComponent["isRequired"] = component.second.IsRequired; + jsonComponent["isHidden"] = component.second.IsHidden; + jsonComponent["isDisabledByDefault"] = + component.second.IsDisabledByDefault; + jsonComponent["isDownloaded"] = component.second.IsDownloaded; + jsonComponent["description"] = component.second.Description; + jsonComponent["archiveFile"] = component.second.ArchiveFile; + + Json::Value& cmpInstallationTypes = jsonComponent["installationTypes"] = + Json::Value(Json::arrayValue); + for (auto& installationType : component.second.InstallationTypes) { + cmpInstallationTypes.append(installationType->Name); + } + + Json::Value& dependencies = jsonComponent["dependencies"] = + Json::Value(Json::arrayValue); + for (auto& dep : component.second.Dependencies) { + dependencies.append(dep->Name); + } + } + + Json::Value& groups = root["componentGroups"] = + Json::Value(Json::objectValue); + for (auto& group : this->Parent->ComponentGroups) { + Json::Value& jsonGroup = groups[group.first] = + Json::Value(Json::objectValue); + + jsonGroup["name"] = group.second.Name; + jsonGroup["displayName"] = group.second.DisplayName; + jsonGroup["description"] = group.second.Description; + jsonGroup["isBold"] = group.second.IsBold; + jsonGroup["isExpandedByDefault"] = group.second.IsExpandedByDefault; + if (group.second.ParentGroup) { + jsonGroup["parentGroup"] = group.second.ParentGroup->Name; + } + + Json::Value& subgroups = jsonGroup["subgroups"] = + Json::Value(Json::arrayValue); + for (auto& subgroup : group.second.Subgroups) { + subgroups.append(subgroup->Name); + } + + Json::Value& groupComponents = jsonGroup["components"] = + Json::Value(Json::arrayValue); + for (auto& component : group.second.Components) { + groupComponents.append(component->Name); + } + } + + return 1; +} diff --git a/Source/CPack/cmCPackExtGenerator.h b/Source/CPack/cmCPackExtGenerator.h new file mode 100644 index 0000000..103e56d --- /dev/null +++ b/Source/CPack/cmCPackExtGenerator.h @@ -0,0 +1,88 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmCPackExtGenerator_h +#define cmCPackExtGenerator_h + +#include "cmCPackGenerator.h" +#include "cm_sys_stat.h" + +#include <memory> +#include <string> + +class cmGlobalGenerator; +namespace Json { +class Value; +} + +/** \class cmCPackExtGenerator + * \brief A generator for CPack External packaging tools + */ +class cmCPackExtGenerator : public cmCPackGenerator +{ +public: + cmCPackTypeMacro(cmCPackExtGenerator, cmCPackGenerator); + + const char* GetOutputExtension() override { return ".json"; } + +protected: + int InitializeInternal() override; + + int PackageFiles() override; + + bool SupportsComponentInstallation() const override; + + int InstallProjectViaInstallCommands( + bool setDestDir, const std::string& tempInstallDirectory) override; + int InstallProjectViaInstallScript( + bool setDestDir, const std::string& tempInstallDirectory) override; + int InstallProjectViaInstalledDirectories( + bool setDestDir, const std::string& tempInstallDirectory, + const mode_t* default_dir_mode) override; + + int RunPreinstallTarget(const std::string& installProjectName, + const std::string& installDirectory, + cmGlobalGenerator* globalGenerator, + const std::string& buildConfig) override; + int InstallCMakeProject(bool setDestDir, const std::string& installDirectory, + const std::string& baseTempInstallDirectory, + const mode_t* default_dir_mode, + const std::string& component, bool componentInstall, + const std::string& installSubDirectory, + const std::string& buildConfig, + std::string& absoluteDestFiles) override; + +private: + bool StagingEnabled() const; + + class cmCPackExtVersionGenerator + { + public: + cmCPackExtVersionGenerator(cmCPackExtGenerator* parent); + + virtual ~cmCPackExtVersionGenerator() = default; + + virtual int WriteToJSON(Json::Value& root); + + protected: + virtual int GetVersionMajor() = 0; + virtual int GetVersionMinor() = 0; + + int WriteVersion(Json::Value& root); + + cmCPackExtGenerator* Parent; + }; + + class cmCPackExtVersion1Generator : public cmCPackExtVersionGenerator + { + public: + using cmCPackExtVersionGenerator::cmCPackExtVersionGenerator; + + protected: + int GetVersionMajor() override { return 1; } + int GetVersionMinor() override { return 0; } + }; + + std::unique_ptr<cmCPackExtVersionGenerator> Generator; +}; + +#endif diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx index 91ae1a2..1433414 100644 --- a/Source/CPack/cmCPackFreeBSDGenerator.cxx +++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx @@ -298,7 +298,7 @@ static bool has_suffix(const std::string& str, const std::string& suffix) int cmCPackFreeBSDGenerator::PackageFiles() { - if (!this->ReadListFile("CPackFreeBSD.cmake")) { + if (!this->ReadListFile("Internal/CPack/CPackFreeBSD.cmake")) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error while execution CPackFreeBSD.cmake" << std::endl); return 0; diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index f15445b..acd6650 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -288,7 +288,7 @@ int cmCPackGenerator::InstallProjectViaInstallCommands( if (!resB || retVal) { std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); tmpFile += "/InstallOutput.log"; - cmGeneratedFileStream ofs(tmpFile.c_str()); + cmGeneratedFileStream ofs(tmpFile); ofs << "# Run command: " << ic << std::endl << "# Output:" << std::endl << output << std::endl; @@ -360,8 +360,6 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories( return 0; } files = gl.GetFiles(); - std::vector<std::string>::iterator gfit; - std::vector<cmsys::RegularExpression>::iterator regIt; for (std::string const& gf : files) { bool skip = false; std::string inFile = gf; @@ -369,7 +367,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories( inFile += '/'; } for (cmsys::RegularExpression& reg : ignoreFilesRegex) { - if (reg.find(inFile.c_str())) { + if (reg.find(inFile)) { cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Ignore file: " << inFile << std::endl); skip = true; @@ -545,10 +543,13 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( ++it; std::string installProjectName = *it; ++it; - std::string installComponent = *it; + cmCPackInstallCMakeProject project; + + project.Directory = installDirectory; + project.ProjectName = installProjectName; + project.Component = *it; ++it; - std::string installSubDirectory = *it; - std::string installFile = installDirectory + "/cmake_install.cmake"; + project.SubDirectory = *it; std::vector<std::string> componentsVector; @@ -559,34 +560,36 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( * - the user did not request Monolithic install * (this works at CPack time too) */ - if (this->SupportsComponentInstallation() & + if (this->SupportsComponentInstallation() && !(this->IsOn("CPACK_MONOLITHIC_INSTALL"))) { // Determine the installation types for this project (if provided). std::string installTypesVar = "CPACK_" + - cmSystemTools::UpperCase(installComponent) + "_INSTALL_TYPES"; + cmSystemTools::UpperCase(project.Component) + "_INSTALL_TYPES"; const char* installTypes = this->GetOption(installTypesVar); if (installTypes && *installTypes) { std::vector<std::string> installTypesVector; cmSystemTools::ExpandListArgument(installTypes, installTypesVector); for (std::string const& installType : installTypesVector) { - this->GetInstallationType(installProjectName, installType); + project.InstallationTypes.push_back( + this->GetInstallationType(project.ProjectName, installType)); } } // Determine the set of components that will be used in this project std::string componentsVar = - "CPACK_COMPONENTS_" + cmSystemTools::UpperCase(installComponent); + "CPACK_COMPONENTS_" + cmSystemTools::UpperCase(project.Component); const char* components = this->GetOption(componentsVar); if (components && *components) { cmSystemTools::ExpandListArgument(components, componentsVector); for (std::string const& comp : componentsVector) { - GetComponent(installProjectName, comp); + project.Components.push_back( + this->GetComponent(project.ProjectName, comp)); } componentInstall = true; } } if (componentsVector.empty()) { - componentsVector.push_back(installComponent); + componentsVector.push_back(project.Component); } const char* buildConfigCstr = this->GetOption("CPACK_BUILD_CONFIG"); @@ -606,297 +609,316 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( // on windows. cmSystemTools::SetForceUnixPaths(globalGenerator->GetForceUnixPaths()); - // Does this generator require pre-install? - if (const char* preinstall = - globalGenerator->GetPreinstallTargetName()) { - std::string buildCommand = globalGenerator->GenerateCMakeBuildCommand( - preinstall, buildConfig, "", false); - cmCPackLogger(cmCPackLog::LOG_DEBUG, - "- Install command: " << buildCommand << std::endl); - cmCPackLogger(cmCPackLog::LOG_OUTPUT, - "- Run preinstall target for: " << installProjectName - << std::endl); - std::string output; - int retVal = 1; - bool resB = cmSystemTools::RunSingleCommand( - buildCommand.c_str(), &output, &output, &retVal, - installDirectory.c_str(), this->GeneratorVerbose, - cmDuration::zero()); - if (!resB || retVal) { - std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - tmpFile += "/PreinstallOutput.log"; - cmGeneratedFileStream ofs(tmpFile.c_str()); - ofs << "# Run command: " << buildCommand << std::endl - << "# Directory: " << installDirectory << std::endl - << "# Output:" << std::endl - << output << std::endl; - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Problem running install command: " - << buildCommand << std::endl - << "Please check " << tmpFile << " for errors" - << std::endl); - return 0; - } + if (!this->RunPreinstallTarget(project.ProjectName, project.Directory, + globalGenerator, buildConfig)) { + return 0; } + delete globalGenerator; cmCPackLogger(cmCPackLog::LOG_OUTPUT, - "- Install project: " << installProjectName << std::endl); + "- Install project: " << project.ProjectName << std::endl); // Run the installation for each component for (std::string const& component : componentsVector) { - std::string tempInstallDirectory = baseTempInstallDirectory; - installComponent = component; - if (componentInstall) { - cmCPackLogger(cmCPackLog::LOG_OUTPUT, - "- Install component: " << installComponent - << std::endl); + if (!this->InstallCMakeProject( + setDestDir, project.Directory, baseTempInstallDirectory, + default_dir_mode, component, componentInstall, + project.SubDirectory, buildConfig, absoluteDestFiles)) { + return 0; } + } - cmake cm(cmake::RoleScript); - cm.SetHomeDirectory(""); - cm.SetHomeOutputDirectory(""); - cm.GetCurrentSnapshot().SetDefaultDefinitions(); - cm.AddCMakePaths(); - cm.SetProgressCallback(cmCPackGeneratorProgress, this); - cm.SetTrace(this->Trace); - cm.SetTraceExpand(this->TraceExpand); - cmGlobalGenerator gg(&cm); - cmMakefile mf(&gg, cm.GetCurrentSnapshot()); - if (!installSubDirectory.empty() && installSubDirectory != "/" && - installSubDirectory != ".") { - tempInstallDirectory += installSubDirectory; - } - if (componentInstall) { - tempInstallDirectory += "/"; - // Some CPack generators would rather chose - // the local installation directory suffix. - // Some (e.g. RPM) use - // one install directory for each component **GROUP** - // instead of the default - // one install directory for each component. - tempInstallDirectory += - GetComponentInstallDirNameSuffix(installComponent); - if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY")) { - tempInstallDirectory += "/"; - tempInstallDirectory += this->GetOption("CPACK_PACKAGE_FILE_NAME"); - } - } + this->CMakeProjects.push_back(project); + } + } + this->SetOption("CPACK_ABSOLUTE_DESTINATION_FILES", + absoluteDestFiles.c_str()); + return 1; +} - const char* default_dir_inst_permissions = - this->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS"); - if (default_dir_inst_permissions && *default_dir_inst_permissions) { - mf.AddDefinition("CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS", - default_dir_inst_permissions); - } +int cmCPackGenerator::RunPreinstallTarget( + const std::string& installProjectName, const std::string& installDirectory, + cmGlobalGenerator* globalGenerator, const std::string& buildConfig) +{ + // Does this generator require pre-install? + if (const char* preinstall = globalGenerator->GetPreinstallTargetName()) { + std::string buildCommand = globalGenerator->GenerateCMakeBuildCommand( + preinstall, buildConfig, "", false); + cmCPackLogger(cmCPackLog::LOG_DEBUG, + "- Install command: " << buildCommand << std::endl); + cmCPackLogger(cmCPackLog::LOG_OUTPUT, + "- Run preinstall target for: " << installProjectName + << std::endl); + std::string output; + int retVal = 1; + bool resB = cmSystemTools::RunSingleCommand( + buildCommand.c_str(), &output, &output, &retVal, + installDirectory.c_str(), this->GeneratorVerbose, cmDuration::zero()); + if (!resB || retVal) { + std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); + tmpFile += "/PreinstallOutput.log"; + cmGeneratedFileStream ofs(tmpFile); + ofs << "# Run command: " << buildCommand << std::endl + << "# Directory: " << installDirectory << std::endl + << "# Output:" << std::endl + << output << std::endl; + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Problem running install command: " + << buildCommand << std::endl + << "Please check " << tmpFile << " for errors" + << std::endl); + return 0; + } + } - if (!setDestDir) { - tempInstallDirectory += this->GetPackagingInstallPrefix(); - } + return 1; +} - if (setDestDir) { - // For DESTDIR based packaging, use the *project* - // CMAKE_INSTALL_PREFIX underneath the tempInstallDirectory. The - // value of the project's CMAKE_INSTALL_PREFIX is sent in here as - // the value of the CPACK_INSTALL_PREFIX variable. - // - // If DESTDIR has been 'internally set ON' this means that - // the underlying CPack specific generator did ask for that - // In this case we may override CPACK_INSTALL_PREFIX with - // CPACK_PACKAGING_INSTALL_PREFIX - // I know this is tricky and awkward but it's the price for - // CPACK_SET_DESTDIR backward compatibility. - if (cmSystemTools::IsInternallyOn( - this->GetOption("CPACK_SET_DESTDIR"))) { - this->SetOption("CPACK_INSTALL_PREFIX", - this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX")); - } - std::string dir; - if (this->GetOption("CPACK_INSTALL_PREFIX")) { - dir += this->GetOption("CPACK_INSTALL_PREFIX"); - } - mf.AddDefinition("CMAKE_INSTALL_PREFIX", dir.c_str()); +int cmCPackGenerator::InstallCMakeProject( + bool setDestDir, const std::string& installDirectory, + const std::string& baseTempInstallDirectory, const mode_t* default_dir_mode, + const std::string& component, bool componentInstall, + const std::string& installSubDirectory, const std::string& buildConfig, + std::string& absoluteDestFiles) +{ + std::string tempInstallDirectory = baseTempInstallDirectory; + std::string installFile = installDirectory + "/cmake_install.cmake"; - cmCPackLogger( - cmCPackLog::LOG_DEBUG, - "- Using DESTDIR + CPACK_INSTALL_PREFIX... (mf.AddDefinition)" - << std::endl); - cmCPackLogger(cmCPackLog::LOG_DEBUG, - "- Setting CMAKE_INSTALL_PREFIX to '" << dir << "'" - << std::endl); - - // Make sure that DESTDIR + CPACK_INSTALL_PREFIX directory - // exists: - // - if (cmSystemTools::StringStartsWith(dir.c_str(), "/")) { - dir = tempInstallDirectory + dir; - } else { - dir = tempInstallDirectory + "/" + dir; - } - /* - * We must re-set DESTDIR for each component - * We must not add the CPACK_INSTALL_PREFIX part because - * it will be added using the override of CMAKE_INSTALL_PREFIX - * The main reason for this awkward trick is that - * are using DESTDIR for 2 different reasons: - * - Because it was asked by the CPack Generator or the user - * using CPACK_SET_DESTDIR - * - Because it was already used for component install - * in order to put things in subdirs... - */ - cmSystemTools::PutEnv(std::string("DESTDIR=") + - tempInstallDirectory); - cmCPackLogger(cmCPackLog::LOG_DEBUG, - "- Creating directory: '" << dir << "'" << std::endl); + if (componentInstall) { + cmCPackLogger(cmCPackLog::LOG_OUTPUT, + "- Install component: " << component << std::endl); + } - if (!cmsys::SystemTools::MakeDirectory(dir, default_dir_mode)) { - cmCPackLogger( - cmCPackLog::LOG_ERROR, - "Problem creating temporary directory: " << dir << std::endl); - return 0; - } - } else { - mf.AddDefinition("CMAKE_INSTALL_PREFIX", - tempInstallDirectory.c_str()); + cmake cm(cmake::RoleScript); + cm.SetHomeDirectory(""); + cm.SetHomeOutputDirectory(""); + cm.GetCurrentSnapshot().SetDefaultDefinitions(); + cm.AddCMakePaths(); + cm.SetProgressCallback(cmCPackGeneratorProgress, this); + cm.SetTrace(this->Trace); + cm.SetTraceExpand(this->TraceExpand); + cmGlobalGenerator gg(&cm); + cmMakefile mf(&gg, cm.GetCurrentSnapshot()); + if (!installSubDirectory.empty() && installSubDirectory != "/" && + installSubDirectory != ".") { + tempInstallDirectory += installSubDirectory; + } + if (componentInstall) { + tempInstallDirectory += "/"; + // Some CPack generators would rather chose + // the local installation directory suffix. + // Some (e.g. RPM) use + // one install directory for each component **GROUP** + // instead of the default + // one install directory for each component. + tempInstallDirectory += GetComponentInstallDirNameSuffix(component); + if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY")) { + tempInstallDirectory += "/"; + tempInstallDirectory += this->GetOption("CPACK_PACKAGE_FILE_NAME"); + } + } - if (!cmsys::SystemTools::MakeDirectory(tempInstallDirectory, - default_dir_mode)) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Problem creating temporary directory: " - << tempInstallDirectory << std::endl); - return 0; - } + const char* default_dir_inst_permissions = + this->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS"); + if (default_dir_inst_permissions && *default_dir_inst_permissions) { + mf.AddDefinition("CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS", + default_dir_inst_permissions); + } - cmCPackLogger(cmCPackLog::LOG_DEBUG, - "- Using non-DESTDIR install... (mf.AddDefinition)" - << std::endl); - cmCPackLogger(cmCPackLog::LOG_DEBUG, - "- Setting CMAKE_INSTALL_PREFIX to '" - << tempInstallDirectory << "'" << std::endl); - } + if (!setDestDir) { + tempInstallDirectory += this->GetPackagingInstallPrefix(); + } - if (!buildConfig.empty()) { - mf.AddDefinition("BUILD_TYPE", buildConfig.c_str()); - } - std::string installComponentLowerCase = - cmSystemTools::LowerCase(installComponent); - if (installComponentLowerCase != "all") { - mf.AddDefinition("CMAKE_INSTALL_COMPONENT", - installComponent.c_str()); - } + if (setDestDir) { + // For DESTDIR based packaging, use the *project* + // CMAKE_INSTALL_PREFIX underneath the tempInstallDirectory. The + // value of the project's CMAKE_INSTALL_PREFIX is sent in here as + // the value of the CPACK_INSTALL_PREFIX variable. + // + // If DESTDIR has been 'internally set ON' this means that + // the underlying CPack specific generator did ask for that + // In this case we may override CPACK_INSTALL_PREFIX with + // CPACK_PACKAGING_INSTALL_PREFIX + // I know this is tricky and awkward but it's the price for + // CPACK_SET_DESTDIR backward compatibility. + if (cmSystemTools::IsInternallyOn(this->GetOption("CPACK_SET_DESTDIR"))) { + this->SetOption("CPACK_INSTALL_PREFIX", + this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX")); + } + std::string dir; + if (this->GetOption("CPACK_INSTALL_PREFIX")) { + dir += this->GetOption("CPACK_INSTALL_PREFIX"); + } + mf.AddDefinition("CMAKE_INSTALL_PREFIX", dir.c_str()); - // strip on TRUE, ON, 1, one or several file names, but not on - // FALSE, OFF, 0 and an empty string - if (!cmSystemTools::IsOff(this->GetOption("CPACK_STRIP_FILES"))) { - mf.AddDefinition("CMAKE_INSTALL_DO_STRIP", "1"); - } - // Remember the list of files before installation - // of the current component (if we are in component install) - std::string const& InstallPrefix = tempInstallDirectory; - std::vector<std::string> filesBefore; - std::string findExpr = tempInstallDirectory; - if (componentInstall) { - cmsys::Glob glB; - findExpr += "/*"; - glB.RecurseOn(); - glB.SetRecurseListDirs(true); - glB.FindFiles(findExpr); - filesBefore = glB.GetFiles(); - std::sort(filesBefore.begin(), filesBefore.end()); - } + cmCPackLogger( + cmCPackLog::LOG_DEBUG, + "- Using DESTDIR + CPACK_INSTALL_PREFIX... (mf.AddDefinition)" + << std::endl); + cmCPackLogger(cmCPackLog::LOG_DEBUG, + "- Setting CMAKE_INSTALL_PREFIX to '" << dir << "'" + << std::endl); + + // Make sure that DESTDIR + CPACK_INSTALL_PREFIX directory + // exists: + // + if (cmSystemTools::StringStartsWith(dir.c_str(), "/")) { + dir = tempInstallDirectory + dir; + } else { + dir = tempInstallDirectory + "/" + dir; + } + /* + * We must re-set DESTDIR for each component + * We must not add the CPACK_INSTALL_PREFIX part because + * it will be added using the override of CMAKE_INSTALL_PREFIX + * The main reason for this awkward trick is that + * are using DESTDIR for 2 different reasons: + * - Because it was asked by the CPack Generator or the user + * using CPACK_SET_DESTDIR + * - Because it was already used for component install + * in order to put things in subdirs... + */ + cmSystemTools::PutEnv(std::string("DESTDIR=") + tempInstallDirectory); + cmCPackLogger(cmCPackLog::LOG_DEBUG, + "- Creating directory: '" << dir << "'" << std::endl); - // If CPack was asked to warn on ABSOLUTE INSTALL DESTINATION - // then forward request to cmake_install.cmake script - if (this->IsOn("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION")) { - mf.AddDefinition("CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION", "1"); - } - // If current CPack generator does support - // ABSOLUTE INSTALL DESTINATION or CPack has been asked for - // then ask cmake_install.cmake script to error out - // as soon as it occurs (before installing file) - if (!SupportsAbsoluteDestination() || - this->IsOn("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION")) { - mf.AddDefinition("CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION", "1"); - } - // do installation - int res = mf.ReadListFile(installFile.c_str()); - // forward definition of CMAKE_ABSOLUTE_DESTINATION_FILES - // to CPack (may be used by generators like CPack RPM or DEB) - // in order to transparently handle ABSOLUTE PATH - if (mf.GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES")) { - mf.AddDefinition( - "CPACK_ABSOLUTE_DESTINATION_FILES", - mf.GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES")); - } + if (!cmsys::SystemTools::MakeDirectory(dir, default_dir_mode)) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Problem creating temporary directory: " << dir + << std::endl); + return 0; + } + } else { + mf.AddDefinition("CMAKE_INSTALL_PREFIX", tempInstallDirectory.c_str()); - // Now rebuild the list of files after installation - // of the current component (if we are in component install) - if (componentInstall) { - cmsys::Glob glA; - glA.RecurseOn(); - glA.SetRecurseListDirs(true); - glA.SetRecurseThroughSymlinks(false); - glA.FindFiles(findExpr); - std::vector<std::string> filesAfter = glA.GetFiles(); - std::sort(filesAfter.begin(), filesAfter.end()); - std::vector<std::string>::iterator diff; - std::vector<std::string> result(filesAfter.size()); - diff = std::set_difference(filesAfter.begin(), filesAfter.end(), - filesBefore.begin(), filesBefore.end(), - result.begin()); - - std::vector<std::string>::iterator fit; - std::string localFileName; - // Populate the File field of each component - for (fit = result.begin(); fit != diff; ++fit) { - localFileName = cmSystemTools::RelativePath(InstallPrefix, *fit); - localFileName = - localFileName.substr(localFileName.find_first_not_of('/')); - Components[installComponent].Files.push_back(localFileName); - cmCPackLogger(cmCPackLog::LOG_DEBUG, - "Adding file <" - << localFileName << "> to component <" - << installComponent << ">" << std::endl); - } - } + if (!cmsys::SystemTools::MakeDirectory(tempInstallDirectory, + default_dir_mode)) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Problem creating temporary directory: " + << tempInstallDirectory << std::endl); + return 0; + } - if (nullptr != mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")) { - if (!absoluteDestFiles.empty()) { - absoluteDestFiles += ";"; - } - absoluteDestFiles += - mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES"); - cmCPackLogger(cmCPackLog::LOG_DEBUG, - "Got some ABSOLUTE DESTINATION FILES: " - << absoluteDestFiles << std::endl); - // define component specific var - if (componentInstall) { - std::string absoluteDestFileComponent = - std::string("CPACK_ABSOLUTE_DESTINATION_FILES") + "_" + - GetComponentInstallDirNameSuffix(installComponent); - if (nullptr != this->GetOption(absoluteDestFileComponent)) { - std::string absoluteDestFilesListComponent = - this->GetOption(absoluteDestFileComponent); - absoluteDestFilesListComponent += ";"; - absoluteDestFilesListComponent += - mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES"); - this->SetOption(absoluteDestFileComponent, - absoluteDestFilesListComponent.c_str()); - } else { - this->SetOption( - absoluteDestFileComponent, - mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")); - } - } - } - if (cmSystemTools::GetErrorOccuredFlag() || !res) { - return 0; - } + cmCPackLogger(cmCPackLog::LOG_DEBUG, + "- Using non-DESTDIR install... (mf.AddDefinition)" + << std::endl); + cmCPackLogger(cmCPackLog::LOG_DEBUG, + "- Setting CMAKE_INSTALL_PREFIX to '" << tempInstallDirectory + << "'" << std::endl); + } + + if (!buildConfig.empty()) { + mf.AddDefinition("BUILD_TYPE", buildConfig.c_str()); + } + std::string installComponentLowerCase = cmSystemTools::LowerCase(component); + if (installComponentLowerCase != "all") { + mf.AddDefinition("CMAKE_INSTALL_COMPONENT", component.c_str()); + } + + // strip on TRUE, ON, 1, one or several file names, but not on + // FALSE, OFF, 0 and an empty string + if (!cmSystemTools::IsOff(this->GetOption("CPACK_STRIP_FILES"))) { + mf.AddDefinition("CMAKE_INSTALL_DO_STRIP", "1"); + } + // Remember the list of files before installation + // of the current component (if we are in component install) + std::string const& InstallPrefix = tempInstallDirectory; + std::vector<std::string> filesBefore; + std::string findExpr = tempInstallDirectory; + if (componentInstall) { + cmsys::Glob glB; + findExpr += "/*"; + glB.RecurseOn(); + glB.SetRecurseListDirs(true); + glB.FindFiles(findExpr); + filesBefore = glB.GetFiles(); + std::sort(filesBefore.begin(), filesBefore.end()); + } + + // If CPack was asked to warn on ABSOLUTE INSTALL DESTINATION + // then forward request to cmake_install.cmake script + if (this->IsOn("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION")) { + mf.AddDefinition("CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION", "1"); + } + // If current CPack generator does support + // ABSOLUTE INSTALL DESTINATION or CPack has been asked for + // then ask cmake_install.cmake script to error out + // as soon as it occurs (before installing file) + if (!SupportsAbsoluteDestination() || + this->IsOn("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION")) { + mf.AddDefinition("CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION", "1"); + } + // do installation + int res = mf.ReadListFile(installFile.c_str()); + // forward definition of CMAKE_ABSOLUTE_DESTINATION_FILES + // to CPack (may be used by generators like CPack RPM or DEB) + // in order to transparently handle ABSOLUTE PATH + if (mf.GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES")) { + mf.AddDefinition("CPACK_ABSOLUTE_DESTINATION_FILES", + mf.GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES")); + } + + // Now rebuild the list of files after installation + // of the current component (if we are in component install) + if (componentInstall) { + cmsys::Glob glA; + glA.RecurseOn(); + glA.SetRecurseListDirs(true); + glA.SetRecurseThroughSymlinks(false); + glA.FindFiles(findExpr); + std::vector<std::string> filesAfter = glA.GetFiles(); + std::sort(filesAfter.begin(), filesAfter.end()); + std::vector<std::string>::iterator diff; + std::vector<std::string> result(filesAfter.size()); + diff = std::set_difference(filesAfter.begin(), filesAfter.end(), + filesBefore.begin(), filesBefore.end(), + result.begin()); + + std::vector<std::string>::iterator fit; + std::string localFileName; + // Populate the File field of each component + for (fit = result.begin(); fit != diff; ++fit) { + localFileName = cmSystemTools::RelativePath(InstallPrefix, *fit); + localFileName = + localFileName.substr(localFileName.find_first_not_of('/')); + Components[component].Files.push_back(localFileName); + cmCPackLogger(cmCPackLog::LOG_DEBUG, + "Adding file <" << localFileName << "> to component <" + << component << ">" << std::endl); + } + } + + if (nullptr != mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")) { + if (!absoluteDestFiles.empty()) { + absoluteDestFiles += ";"; + } + absoluteDestFiles += mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES"); + cmCPackLogger(cmCPackLog::LOG_DEBUG, + "Got some ABSOLUTE DESTINATION FILES: " << absoluteDestFiles + << std::endl); + // define component specific var + if (componentInstall) { + std::string absoluteDestFileComponent = + std::string("CPACK_ABSOLUTE_DESTINATION_FILES") + "_" + + GetComponentInstallDirNameSuffix(component); + if (nullptr != this->GetOption(absoluteDestFileComponent)) { + std::string absoluteDestFilesListComponent = + this->GetOption(absoluteDestFileComponent); + absoluteDestFilesListComponent += ";"; + absoluteDestFilesListComponent += + mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES"); + this->SetOption(absoluteDestFileComponent, + absoluteDestFilesListComponent.c_str()); + } else { + this->SetOption(absoluteDestFileComponent, + mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")); } } } - this->SetOption("CPACK_ABSOLUTE_DESTINATION_FILES", - absoluteDestFiles.c_str()); + if (cmSystemTools::GetErrorOccuredFlag() || !res) { + return 0; + } return 1; } @@ -1475,7 +1497,6 @@ cmCPackComponent* cmCPackGenerator::GetComponent( if (installTypes && *installTypes) { std::vector<std::string> installTypesVector; cmSystemTools::ExpandListArgument(installTypes, installTypesVector); - std::vector<std::string>::iterator installTypesIt; for (std::string const& installType : installTypesVector) { component->InstallationTypes.push_back( this->GetInstallationType(projectName, installType)); @@ -1487,7 +1508,6 @@ cmCPackComponent* cmCPackGenerator::GetComponent( if (depends && *depends) { std::vector<std::string> dependsVector; cmSystemTools::ExpandListArgument(depends, dependsVector); - std::vector<std::string>::iterator dependIt; for (std::string const& depend : dependsVector) { cmCPackComponent* child = GetComponent(projectName, depend); component->Dependencies.push_back(child); diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h index c22f36b..4755f94 100644 --- a/Source/CPack/cmCPackGenerator.h +++ b/Source/CPack/cmCPackGenerator.h @@ -15,6 +15,7 @@ #include "cm_sys_stat.h" class cmCPackLog; +class cmGlobalGenerator; class cmInstalledFile; class cmMakefile; @@ -185,6 +186,17 @@ protected: bool setDestDir, const std::string& tempInstallDirectory, const mode_t* default_dir_mode); + virtual int RunPreinstallTarget(const std::string& installProjectName, + const std::string& installDirectory, + cmGlobalGenerator* globalGenerator, + const std::string& buildConfig); + virtual int InstallCMakeProject( + bool setDestDir, const std::string& installDirectory, + const std::string& baseTempInstallDirectory, + const mode_t* default_dir_mode, const std::string& component, + bool componentInstall, const std::string& installSubDirectory, + const std::string& buildConfig, std::string& absoluteDestFiles); + /** * The various level of support of * CPACK_SET_DESTDIR used by the generator. @@ -271,6 +283,7 @@ protected: */ std::vector<std::string> files; + std::vector<cmCPackInstallCMakeProject> CMakeProjects; std::map<std::string, cmCPackInstallationType> InstallationTypes; /** * The set of components. @@ -308,7 +321,6 @@ protected: bool Trace; bool TraceExpand; -private: cmMakefile* MakefileMap; }; diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx index d47e5ed..8ef24f7 100644 --- a/Source/CPack/cmCPackGeneratorFactory.cxx +++ b/Source/CPack/cmCPackGeneratorFactory.cxx @@ -12,6 +12,7 @@ # include "cmCPackFreeBSDGenerator.h" #endif #include "cmCPackDebGenerator.h" +#include "cmCPackExtGenerator.h" #include "cmCPackGenerator.h" #include "cmCPackLog.h" #include "cmCPackNSISGenerator.h" @@ -110,6 +111,10 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory() this->RegisterGenerator("NuGet", "NuGet packages", cmCPackNuGetGenerator::CreateGenerator); } + if (cmCPackExtGenerator::CanGenerate()) { + this->RegisterGenerator("Ext", "CPack External packages", + cmCPackExtGenerator::CreateGenerator); + } #ifdef __APPLE__ if (cmCPackDragNDropGenerator::CanGenerate()) { this->RegisterGenerator("DragNDrop", "Mac OSX Drag And Drop", diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx index a893a0f..f75a750 100644 --- a/Source/CPack/cmCPackNSISGenerator.cxx +++ b/Source/CPack/cmCPackNSISGenerator.cxx @@ -305,7 +305,7 @@ int cmCPackNSISGenerator::PackageFiles() nsisCmd.c_str(), &output, &output, &retVal, nullptr, this->GeneratorVerbose, cmDuration::zero()); if (!res || retVal) { - cmGeneratedFileStream ofs(tmpFile.c_str()); + cmGeneratedFileStream ofs(tmpFile); ofs << "# Run command: " << nsisCmd << std::endl << "# Output:" << std::endl << output << std::endl; @@ -416,7 +416,7 @@ int cmCPackNSISGenerator::InitializeInternal() const char* topDir = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); std::string tmpFile = topDir ? topDir : "."; tmpFile += "/NSISOutput.log"; - cmGeneratedFileStream ofs(tmpFile.c_str()); + cmGeneratedFileStream ofs(tmpFile); ofs << "# Run command: " << nsisCmd << std::endl << "# Output:" << std::endl << output << std::endl; @@ -703,7 +703,7 @@ std::string cmCPackNSISGenerator::CreateComponentDescription( // Find a ZIP program if (!this->IsSet("ZIP_EXECUTABLE")) { - this->ReadListFile("CPackZIP.cmake"); + this->ReadListFile("Internal/CPack/CPackZIP.cmake"); if (!this->IsSet("ZIP_EXECUTABLE")) { cmCPackLogger(cmCPackLog::LOG_ERROR, @@ -726,7 +726,7 @@ std::string cmCPackNSISGenerator::CreateComponentDescription( cmSystemTools::IsOn(this->GetOption("CPACK_ZIP_NEED_QUOTES")); unsigned long totalSize = 0; { // the scope is needed for cmGeneratedFileStream - cmGeneratedFileStream out(zipListFileName.c_str()); + cmGeneratedFileStream out(zipListFileName); for (std::string const& file : component->Files) { if (needQuotesInFile) { out << "\""; @@ -754,7 +754,7 @@ std::string cmCPackNSISGenerator::CreateComponentDescription( if (!res || retVal) { std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); tmpFile += "/CompressZip.log"; - cmGeneratedFileStream ofs(tmpFile.c_str()); + cmGeneratedFileStream ofs(tmpFile); ofs << "# Run command: " << cmd << std::endl << "# Output:" << std::endl << output << std::endl; diff --git a/Source/CPack/cmCPackNuGetGenerator.cxx b/Source/CPack/cmCPackNuGetGenerator.cxx index 2ae8cba..76f0699 100644 --- a/Source/CPack/cmCPackNuGetGenerator.cxx +++ b/Source/CPack/cmCPackNuGetGenerator.cxx @@ -49,7 +49,7 @@ int cmCPackNuGetGenerator::PackageFiles() this->SetOption("CPACK_NUGET_ORDINAL_MONOLITIC", "TRUE"); } - auto retval = this->ReadListFile("CPackNuGet.cmake"); + auto retval = this->ReadListFile("Internal/CPack/CPackNuGet.cmake"); if (retval) { AddGeneratedPackageNames(); } else { diff --git a/Source/CPack/cmCPackProductBuildGenerator.cxx b/Source/CPack/cmCPackProductBuildGenerator.cxx index 4ca0fa8..76b3275 100644 --- a/Source/CPack/cmCPackProductBuildGenerator.cxx +++ b/Source/CPack/cmCPackProductBuildGenerator.cxx @@ -144,10 +144,10 @@ bool cmCPackProductBuildGenerator::RunProductBuild(const std::string& command) tmpFile += "/ProductBuildOutput.log"; cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << command << std::endl); - std::string output, error_output; + std::string output; int retVal = 1; bool res = cmSystemTools::RunSingleCommand( - command.c_str(), &output, &error_output, &retVal, nullptr, + command.c_str(), &output, &output, &retVal, nullptr, this->GeneratorVerbose, cmDuration::zero()); cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Done running command" << std::endl); if (!res || retVal) { diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx index c389884..5834829 100644 --- a/Source/CPack/cmCPackRPMGenerator.cxx +++ b/Source/CPack/cmCPackRPMGenerator.cxx @@ -89,7 +89,7 @@ int cmCPackRPMGenerator::PackageOnePack(std::string const& initialToplevel, component_path += packageName; this->SetOption("CPACK_RPM_PACKAGE_COMPONENT_PART_PATH", component_path.c_str()); - if (!this->ReadListFile("CPackRPM.cmake")) { + if (!this->ReadListFile("Internal/CPack/CPackRPM.cmake")) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error while execution CPackRPM.cmake" << std::endl); retval = 0; @@ -385,7 +385,7 @@ int cmCPackRPMGenerator::PackageComponentsAllInOne( component_path.c_str()); } - if (this->ReadListFile("CPackRPM.cmake")) { + if (this->ReadListFile("Internal/CPack/CPackRPM.cmake")) { AddGeneratedPackageNames(); } else { cmCPackLogger(cmCPackLog::LOG_ERROR, |