View Issue Details [ Jump to Notes ] | [ Print ] | ||||||||
ID | Project | Category | View Status | Date Submitted | Last Update | ||||
0010736 | CMake | CPack | public | 2010-05-20 07:10 | 2010-10-06 14:40 | ||||
Reporter | Stefan Sablatnoeg | ||||||||
Assigned To | Eric NOULARD | ||||||||
Priority | normal | Severity | feature | Reproducibility | N/A | ||||
Status | closed | Resolution | fixed | ||||||
Platform | OS | OS Version | |||||||
Product Version | |||||||||
Target Version | CMake 2.8.3 | Fixed in Version | CMake 2.8.3 | ||||||
Summary | 0010736: Enable CPack generators to produce more than one package | ||||||||
Description | It would be nice if it would be possible to build multiple packages from one cmake project using cpack. Especially for the "simple" generators like ZIP etc. a seperation based on the COMPONENT given in the install command woould be very helpful (and probably easy to implement), but even for "active installers" there might be the need to provide different modules from one source tree. | ||||||||
Tags | No tags attached. | ||||||||
Attached Files | 0001-CPack-enable-generators-to-produce-more-than-one-pac.patch [^] (22,505 bytes) 2010-08-03 20:18 [Show Content] [Hide Content]From b0732c13c5e9a2f6a040b2f0ad437d2924a4ef0a Mon Sep 17 00:00:00 2001 From: Eric NOULARD <eric.noulard@gmail.com> Date: Tue, 3 Aug 2010 20:58:27 +0200 Subject: [PATCH 1/3] CPack enable generators to produce more than one package (part1) The current patch modifies the API of compressFile by adding an extra packageNames list argument. This argument is handled by the upper level generator (cmCPackGenerator.*) but the lower level specific generators do not change behavior (besides the API change). The modifications for each specific generators will come afterwards. --- Source/CPack/cmCPackArchiveGenerator.cxx | 2 +- Source/CPack/cmCPackArchiveGenerator.h | 2 +- Source/CPack/cmCPackBundleGenerator.cxx | 3 +- Source/CPack/cmCPackBundleGenerator.h | 2 +- Source/CPack/cmCPackDebGenerator.cxx | 3 +- Source/CPack/cmCPackDebGenerator.h | 2 +- Source/CPack/cmCPackDragNDropGenerator.cxx | 3 +- Source/CPack/cmCPackDragNDropGenerator.h | 2 +- Source/CPack/cmCPackGenerator.cxx | 93 ++++++++++++++++++++----- Source/CPack/cmCPackGenerator.h | 23 ++++++- Source/CPack/cmCPackNSISGenerator.cxx | 3 +- Source/CPack/cmCPackNSISGenerator.h | 3 +- Source/CPack/cmCPackOSXX11Generator.cxx | 3 +- Source/CPack/cmCPackOSXX11Generator.h | 3 +- Source/CPack/cmCPackPackageMakerGenerator.cxx | 3 +- Source/CPack/cmCPackPackageMakerGenerator.h | 3 +- Source/CPack/cmCPackRPMGenerator.cxx | 3 +- Source/CPack/cmCPackRPMGenerator.h | 2 +- Source/CPack/cmCPackSTGZGenerator.cxx | 4 +- Source/CPack/cmCPackSTGZGenerator.h | 2 +- 20 files changed, 126 insertions(+), 38 deletions(-) diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index a52d05e..42a7552 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -167,7 +167,7 @@ int cmCPackArchiveGenerator::InitializeInternal() } int cmCPackArchiveGenerator::CompressFiles(const char* outFileName, - const char* toplevel, const std::vector<std::string>& files) + const char* toplevel, const std::vector<std::string>& files, std::list<std::string>& packageFileNames) { int res = ARCHIVE_OK; #define CHECK_ARCHIVE_ERROR(res, msg) \ diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h index 486db8e..19b939e 100644 --- a/Source/CPack/cmCPackArchiveGenerator.h +++ b/Source/CPack/cmCPackArchiveGenerator.h @@ -38,7 +38,7 @@ public: protected: virtual int InitializeInternal(); int CompressFiles(const char* outFileName, const char* toplevel, - const std::vector<std::string>& files); + const std::vector<std::string>& files, std::list<std::string>& packageFileNames); virtual const char* GetOutputExtension() = 0; CompressType Compress; ArchiveType Archive; diff --git a/Source/CPack/cmCPackBundleGenerator.cxx b/Source/CPack/cmCPackBundleGenerator.cxx index 247a043..06baa31 100644 --- a/Source/CPack/cmCPackBundleGenerator.cxx +++ b/Source/CPack/cmCPackBundleGenerator.cxx @@ -54,7 +54,8 @@ const char* cmCPackBundleGenerator::GetPackagingInstallPrefix() //---------------------------------------------------------------------- int cmCPackBundleGenerator::CompressFiles(const char* outFileName, - const char* toplevel, const std::vector<std::string>& files) + const char* toplevel, const std::vector<std::string>& files, + std::list<std::string>& packageFileNames) { (void) files; diff --git a/Source/CPack/cmCPackBundleGenerator.h b/Source/CPack/cmCPackBundleGenerator.h index ce05541..46125bd 100644 --- a/Source/CPack/cmCPackBundleGenerator.h +++ b/Source/CPack/cmCPackBundleGenerator.h @@ -32,7 +32,7 @@ protected: virtual int InitializeInternal(); virtual const char* GetPackagingInstallPrefix(); int CompressFiles(const char* outFileName, const char* toplevel, - const std::vector<std::string>& files); + const std::vector<std::string>& files, std::list<std::string>& packageFileNames); std::string InstallPrefix; }; diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx index cee24ef..78e464d 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -50,7 +50,8 @@ int cmCPackDebGenerator::InitializeInternal() //---------------------------------------------------------------------- int cmCPackDebGenerator::CompressFiles(const char* outFileName, const char* toplevel, - const std::vector<std::string>& files) + const std::vector<std::string>& files, + std::list<std::string>& packageFileNames) { this->ReadListFile("CPackDeb.cmake"); const char* cmakeExecutable = this->GetOption("CMAKE_COMMAND"); diff --git a/Source/CPack/cmCPackDebGenerator.h b/Source/CPack/cmCPackDebGenerator.h index d229944..33b35c7 100644 --- a/Source/CPack/cmCPackDebGenerator.h +++ b/Source/CPack/cmCPackDebGenerator.h @@ -34,7 +34,7 @@ public: protected: virtual int InitializeInternal(); virtual int CompressFiles(const char* outFileName, const char* toplevel, - const std::vector<std::string>& files); + const std::vector<std::string>& files, std::list<std::string>& packageFileNames); virtual const char* GetOutputExtension() { return ".deb"; } }; diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx index 95324cf..1fa99e4 100644 --- a/Source/CPack/cmCPackDragNDropGenerator.cxx +++ b/Source/CPack/cmCPackDragNDropGenerator.cxx @@ -105,7 +105,8 @@ const char* cmCPackDragNDropGenerator::GetOutputExtension() //---------------------------------------------------------------------- int cmCPackDragNDropGenerator::CompressFiles(const char* outFileName, - const char* toplevel, const std::vector<std::string>& files) + const char* toplevel, const std::vector<std::string>& files, + std::list<std::string>& packageFileNames) { (void) files; diff --git a/Source/CPack/cmCPackDragNDropGenerator.h b/Source/CPack/cmCPackDragNDropGenerator.h index 43a9617..fa82872 100644 --- a/Source/CPack/cmCPackDragNDropGenerator.h +++ b/Source/CPack/cmCPackDragNDropGenerator.h @@ -30,7 +30,7 @@ protected: virtual int InitializeInternal(); virtual const char* GetOutputExtension(); int CompressFiles(const char* outFileName, const char* toplevel, - const std::vector<std::string>& files); + const std::vector<std::string>& files, std::list<std::string>& packageFileNames); bool CopyFile(cmOStringStream& source, cmOStringStream& target); bool RunCommand(cmOStringStream& command, std::string* output = 0); diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 4a4b428..d90a375 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -100,6 +100,7 @@ int cmCPackGenerator::PrepareNames() } std::string destFile = pdir; + this->SetOptionIfNotSet("CPACK_OUTPUT_FILE_PREFIX", destFile.c_str()); destFile += "/" + outName; std::string outFile = topDirectory + "/" + outName; this->SetOptionIfNotSet("CPACK_TOPLEVEL_DIRECTORY", topDirectory.c_str()); @@ -813,6 +814,7 @@ int cmCPackGenerator::DoPackage() const char* tempPackageFileName = this->GetOption( "CPACK_TEMPORARY_PACKAGE_FILE_NAME"); const char* packageFileName = this->GetOption("CPACK_OUTPUT_FILE_PATH"); + const char* packageFileNamePrefix = this->GetOption("CPACK_OUTPUT_FILE_PREFIX"); const char* tempDirectory = this->GetOption("CPACK_TEMPORARY_DIRECTORY"); cmCPackLogger(cmCPackLog::LOG_DEBUG, "Find files" << std::endl); @@ -845,6 +847,9 @@ int cmCPackGenerator::DoPackage() // The files to be installed std::vector<std::string> files = gl.GetFiles(); + cmCPackLogger(cmCPackLog::LOG_DEBUG, "tempDirectory = " + << tempDirectory + << std::endl); // For component installations, determine which files go into which // components. if (!this->Components.empty()) @@ -852,22 +857,32 @@ int cmCPackGenerator::DoPackage() std::vector<std::string>::const_iterator it; for ( it = files.begin(); it != files.end(); ++ it ) { - std::string fileN = cmSystemTools::RelativePath(tempDirectory, + cmCPackLogger(cmCPackLog::LOG_DEBUG, "CPACK_TOPLEVEL_DIRECTORY =" + << this->GetOption("CPACK_TOPLEVEL_DIRECTORY") + << "CPACK_TEMPORARY_DIRECTORY =" + << this->GetOption("CPACK_TEMPORARY_DIRECTORY") + << std::endl); + std::string fileN = cmSystemTools::RelativePath(this->GetOption("CPACK_TEMPORARY_DIRECTORY"), it->c_str()); - // Determine which component we are in. std::string componentName = fileN.substr(0, fileN.find('/')); // Strip off the component part of the path. fileN = fileN.substr(fileN.find('/')+1, std::string::npos); + cmCPackLogger(cmCPackLog::LOG_DEBUG, "component <" + << componentName + << "> contains : " + << fileN << std::endl); // Add this file to the list of files for the component. this->Components[componentName].Files.push_back(fileN); } } + std::list<std::string> packageFileNames; + if ( !this->CompressFiles(tempPackageFileName, - tempDirectory, files) || cmSystemTools::GetErrorOccuredFlag()) + tempDirectory, files, packageFileNames) || cmSystemTools::GetErrorOccuredFlag()) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem compressing the directory" << std::endl); @@ -875,25 +890,65 @@ int cmCPackGenerator::DoPackage() } cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Finalize package" << std::endl); - cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Copy final package: " + + /* check whether if the specific generator did change the provided + * tempPackageFileName or decided to generate several packages + */ + if (packageFileNames.size()>0) + { + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Copying final package(s) [" + <<packageFileNames.size() + <<"]:"<<std::endl); + std::list<std::string>::iterator it; + /* now copy package one by one */ + for (it=packageFileNames.begin();it!=packageFileNames.end();++it) + { + std::string tmpPF(packageFileNamePrefix); + tempPackageFileName = it->c_str(); + tmpPF += "/"+cmSystemTools::GetFilenameName(*it); + packageFileName = tmpPF.c_str(); + cmCPackLogger(cmCPackLog::LOG_DEBUG, "Copy final package(s): " + << (tempPackageFileName ? tempPackageFileName : "(NULL)" ) + << " to " + << (packageFileName ? packageFileName : "(NULL)") + << std::endl); + cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Created package: " + << cmSystemTools::GetFilenameName(*it) + << std::endl); + if ( !cmSystemTools::CopyFileIfDifferent(tempPackageFileName, + packageFileName) ) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying the package: " + << (tempPackageFileName ? tempPackageFileName : "(NULL)" ) + << " to " + << (packageFileName ? packageFileName : "(NULL)") + << std::endl); + return 0; + } + } + } + else + { + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Copy final package: " << (tempPackageFileName ? tempPackageFileName : "(NULL)" ) << " to " << (packageFileName ? packageFileName : "(NULL)") << std::endl); - if ( !cmSystemTools::CopyFileIfDifferent(tempPackageFileName, - packageFileName) ) - { - cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying the package: " - << (tempPackageFileName ? tempPackageFileName : "(NULL)" ) - << " to " - << (packageFileName ? packageFileName : "(NULL)") - << std::endl); - return 0; - } + if ( !cmSystemTools::CopyFileIfDifferent(tempPackageFileName, + packageFileName) ) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying the package: " + << (tempPackageFileName ? tempPackageFileName : "(NULL)" ) + << " to " + << (packageFileName ? packageFileName : "(NULL)") + << std::endl); + return 0; + } - cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Package " - << (packageFileName ? packageFileName : "(NULL)") - << " generated." << std::endl); + cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Package " + << (packageFileName ? packageFileName : "(NULL)") + << " generated." << std::endl); + } return 1; } @@ -985,11 +1040,13 @@ int cmCPackGenerator::SetCMakeRoot() //---------------------------------------------------------------------- int cmCPackGenerator::CompressFiles(const char* outFileName, - const char* toplevel, const std::vector<std::string>& files) + const char* toplevel, const std::vector<std::string>& files, + std::list<std::string>& packageFileNames) { (void)outFileName; (void)toplevel; (void)files; + (void)packageFileNames; return 0; } diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h index 45188fe..ef623b2 100644 --- a/Source/CPack/cmCPackGenerator.h +++ b/Source/CPack/cmCPackGenerator.h @@ -99,8 +99,29 @@ protected: int CleanTemporaryDirectory(); virtual const char* GetOutputExtension() { return ".cpack"; } virtual const char* GetOutputPostfix() { return 0; } + /** + * Compress the list of files provided by the generic generator. + * This method must be redefined in each specific generator. + * @param[in] outFileName the name of the package file to create + * this is used if the specific generator obey the upper-level + * generator. If the specific generator wants to enforce some + * naming rules and/or wants to generates multiple files + * then packageFileNames argument should be used. + * @param[in] toplevel the name of the top level directory + * @param[in] files the list of files to be included in the package(s). + * @param[in,out] packageFileNames the list of package file names which have + * been created by the specific generator. On entry the list + * is empty on return the list may be + * - empty: meaning the generator did create a single package + * file whose name is outFileName + * - list of 1 or more names: meaning that the generator did create + * the specified sets of packages. The list may contain + * a single name which means that the generator probably + * renamed the suggested outFileName to something else. + * @return 0 if an error occurred. Non-zero otherwise. + */ virtual int CompressFiles(const char* outFileName, const char* toplevel, - const std::vector<std::string>& files); + const std::vector<std::string>& files, std::list<std::string>& packageFileNames); virtual const char* GetInstallPath(); virtual const char* GetPackagingInstallPrefix(); diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx index 8329546..0eb96c0 100644 --- a/Source/CPack/cmCPackNSISGenerator.cxx +++ b/Source/CPack/cmCPackNSISGenerator.cxx @@ -44,7 +44,8 @@ cmCPackNSISGenerator::~cmCPackNSISGenerator() //---------------------------------------------------------------------- int cmCPackNSISGenerator::CompressFiles(const char* outFileName, - const char* toplevel, const std::vector<std::string>& files) + const char* toplevel, const std::vector<std::string>& files, + std::list<std::string>& packageFileNames) { (void)outFileName; // TODO: Fix nsis to force out file name (void)toplevel; diff --git a/Source/CPack/cmCPackNSISGenerator.h b/Source/CPack/cmCPackNSISGenerator.h index dff5b8f..01c9b6f 100644 --- a/Source/CPack/cmCPackNSISGenerator.h +++ b/Source/CPack/cmCPackNSISGenerator.h @@ -38,7 +38,8 @@ protected: void CreateMenuLinks( cmOStringStream& str, cmOStringStream& deleteStr); int CompressFiles(const char* outFileName, const char* toplevel, - const std::vector<std::string>& files); + const std::vector<std::string>& files, + std::list<std::string>& packageFileNames); virtual const char* GetOutputExtension() { return ".exe"; } virtual const char* GetOutputPostfix() { return "win32"; } diff --git a/Source/CPack/cmCPackOSXX11Generator.cxx b/Source/CPack/cmCPackOSXX11Generator.cxx index a3b5759..78af6a6 100644 --- a/Source/CPack/cmCPackOSXX11Generator.cxx +++ b/Source/CPack/cmCPackOSXX11Generator.cxx @@ -35,7 +35,8 @@ cmCPackOSXX11Generator::~cmCPackOSXX11Generator() //---------------------------------------------------------------------- int cmCPackOSXX11Generator::CompressFiles(const char* outFileName, const char* toplevel, - const std::vector<std::string>& files) + const std::vector<std::string>& files, + std::list<std::string>& packageFileNames) { (void) files; // TODO: Fix api to not need files. (void) toplevel; // TODO: Use toplevel diff --git a/Source/CPack/cmCPackOSXX11Generator.h b/Source/CPack/cmCPackOSXX11Generator.h index 7fd60b4..6dad0f6 100644 --- a/Source/CPack/cmCPackOSXX11Generator.h +++ b/Source/CPack/cmCPackOSXX11Generator.h @@ -34,7 +34,8 @@ public: protected: virtual int InitializeInternal(); int CompressFiles(const char* outFileName, const char* toplevel, - const std::vector<std::string>& files); + const std::vector<std::string>& files, + std::list<std::string>& packageFileNames); virtual const char* GetPackagingInstallPrefix(); virtual const char* GetOutputExtension() { return ".dmg"; } diff --git a/Source/CPack/cmCPackPackageMakerGenerator.cxx b/Source/CPack/cmCPackPackageMakerGenerator.cxx index 9333131..1f3bdbc 100644 --- a/Source/CPack/cmCPackPackageMakerGenerator.cxx +++ b/Source/CPack/cmCPackPackageMakerGenerator.cxx @@ -61,7 +61,8 @@ int cmCPackPackageMakerGenerator::CopyInstallScript(const char* resdir, //---------------------------------------------------------------------- int cmCPackPackageMakerGenerator::CompressFiles(const char* outFileName, const char* toplevel, - const std::vector<std::string>& files) + const std::vector<std::string>& files, + std::list<std::string>& packageFileNames) { (void) files; // TODO: Fix api to not need files. (void) toplevel; // TODO: Use toplevel diff --git a/Source/CPack/cmCPackPackageMakerGenerator.h b/Source/CPack/cmCPackPackageMakerGenerator.h index 36cd594..2c9a680 100644 --- a/Source/CPack/cmCPackPackageMakerGenerator.h +++ b/Source/CPack/cmCPackPackageMakerGenerator.h @@ -43,7 +43,8 @@ protected: const char* name); virtual int InitializeInternal(); int CompressFiles(const char* outFileName, const char* toplevel, - const std::vector<std::string>& files); + const std::vector<std::string>& files, + std::list<std::string>& packageFileNames); virtual const char* GetOutputExtension() { return ".dmg"; } virtual const char* GetOutputPostfix() { return "darwin"; } diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx index fb85581..849d75e 100644 --- a/Source/CPack/cmCPackRPMGenerator.cxx +++ b/Source/CPack/cmCPackRPMGenerator.cxx @@ -33,7 +33,8 @@ int cmCPackRPMGenerator::InitializeInternal() //---------------------------------------------------------------------- int cmCPackRPMGenerator::CompressFiles(const char* /*outFileName*/, const char* /*toplevel*/, - const std::vector<std::string>& /*files*/) + const std::vector<std::string>& /*files*/, + std::list<std::string>& /* packageFileNames*/) { this->ReadListFile("CPackRPM.cmake"); if (!this->IsSet("RPMBUILD_EXECUTABLE")) diff --git a/Source/CPack/cmCPackRPMGenerator.h b/Source/CPack/cmCPackRPMGenerator.h index c607f35..4b8f6de 100644 --- a/Source/CPack/cmCPackRPMGenerator.h +++ b/Source/CPack/cmCPackRPMGenerator.h @@ -38,7 +38,7 @@ public: protected: virtual int InitializeInternal(); virtual int CompressFiles(const char* outFileName, const char* toplevel, - const std::vector<std::string>& files); + const std::vector<std::string>& files, std::list<std::string>& packageFileNames); virtual const char* GetOutputExtension() { return ".rpm"; } }; diff --git a/Source/CPack/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx index a687e0d..1ca063d 100644 --- a/Source/CPack/cmCPackSTGZGenerator.cxx +++ b/Source/CPack/cmCPackSTGZGenerator.cxx @@ -53,9 +53,9 @@ int cmCPackSTGZGenerator::InitializeInternal() //---------------------------------------------------------------------- int cmCPackSTGZGenerator::CompressFiles(const char* outFileName, - const char* toplevel, const std::vector<std::string>& files) + const char* toplevel, const std::vector<std::string>& files, std::list<std::string>& packageFileNames) { - if ( !this->Superclass::CompressFiles(outFileName, toplevel, files) ) + if ( !this->Superclass::CompressFiles(outFileName, toplevel, files, packageFileNames) ) { return 0; } diff --git a/Source/CPack/cmCPackSTGZGenerator.h b/Source/CPack/cmCPackSTGZGenerator.h index fc51e4d..3198add 100644 --- a/Source/CPack/cmCPackSTGZGenerator.h +++ b/Source/CPack/cmCPackSTGZGenerator.h @@ -33,7 +33,7 @@ public: protected: int CompressFiles(const char* outFileName, const char* toplevel, - const std::vector<std::string>& files); + const std::vector<std::string>& files, std::list<std::string>& packageFileNames); virtual int InitializeInternal(); int GenerateHeader(std::ostream* os); virtual const char* GetOutputExtension() { return ".sh"; } -- 1.7.1 0002-CPack-enable-generators-to-produce-more-than-one-pac.patch [^] (4,554 bytes) 2010-08-03 20:18 [Show Content] [Hide Content] From 480006d24f63839b43349ae7e0abd5e4bac2b41c Mon Sep 17 00:00:00 2001 From: Eric NOULARD <eric.noulard@gmail.com> Date: Tue, 3 Aug 2010 21:17:40 +0200 Subject: [PATCH 2/3] CPack enable generators to produce more than one package (part1.1) Some modification for generators not available on Linux were missing --- Source/CPack/cmCPackBundleGenerator.cxx | 1 + Source/CPack/cmCPackCygwinBinaryGenerator.cxx | 5 ++++- Source/CPack/cmCPackCygwinBinaryGenerator.h | 2 +- Source/CPack/cmCPackCygwinSourceGenerator.cxx | 4 +++- Source/CPack/cmCPackCygwinSourceGenerator.h | 2 +- Source/CPack/cmCPackDragNDropGenerator.cxx | 1 + 6 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Source/CPack/cmCPackBundleGenerator.cxx b/Source/CPack/cmCPackBundleGenerator.cxx index 06baa31..1ea54a2 100644 --- a/Source/CPack/cmCPackBundleGenerator.cxx +++ b/Source/CPack/cmCPackBundleGenerator.cxx @@ -58,6 +58,7 @@ int cmCPackBundleGenerator::CompressFiles(const char* outFileName, std::list<std::string>& packageFileNames) { (void) files; + (void) packageFileNames; // Get required arguments ... const std::string cpack_bundle_name = this->GetOption("CPACK_BUNDLE_NAME") diff --git a/Source/CPack/cmCPackCygwinBinaryGenerator.cxx b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx index 853a1be..92ca81b 100644 --- a/Source/CPack/cmCPackCygwinBinaryGenerator.cxx +++ b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx @@ -42,8 +42,11 @@ int cmCPackCygwinBinaryGenerator::InitializeInternal() //---------------------------------------------------------------------- int cmCPackCygwinBinaryGenerator::CompressFiles(const char* outFileName, - const char* toplevel, const std::vector<std::string>& files) + const char* toplevel, const std::vector<std::string>& files, + std::list<std::string>& packageFileNames) { + (void) packageFileNames; + std::string packageName = this->GetOption("CPACK_PACKAGE_NAME"); packageName += "-"; packageName += this->GetOption("CPACK_PACKAGE_VERSION"); diff --git a/Source/CPack/cmCPackCygwinBinaryGenerator.h b/Source/CPack/cmCPackCygwinBinaryGenerator.h index 19b09f0..3b24d79 100644 --- a/Source/CPack/cmCPackCygwinBinaryGenerator.h +++ b/Source/CPack/cmCPackCygwinBinaryGenerator.h @@ -31,7 +31,7 @@ public: protected: virtual int InitializeInternal(); int CompressFiles(const char* outFileName, const char* toplevel, - const std::vector<std::string>& files); + const std::vector<std::string>& files, std::list<std::string>& packageFileNames); virtual const char* GetOutputExtension(); std::string OutputExtension; }; diff --git a/Source/CPack/cmCPackCygwinSourceGenerator.cxx b/Source/CPack/cmCPackCygwinSourceGenerator.cxx index cca8338..0f51c29 100644 --- a/Source/CPack/cmCPackCygwinSourceGenerator.cxx +++ b/Source/CPack/cmCPackCygwinSourceGenerator.cxx @@ -49,8 +49,10 @@ int cmCPackCygwinSourceGenerator::InitializeInternal() //---------------------------------------------------------------------- int cmCPackCygwinSourceGenerator::CompressFiles(const char* outFileName, - const char* toplevel, const std::vector<std::string>& files) + const char* toplevel, const std::vector<std::string>& files, + std::list<std::string>& packageFileNames) { + void (packageFileNames); // Create a tar file of the sources std::string packageDirFileName = this->GetOption("CPACK_TEMPORARY_DIRECTORY"); diff --git a/Source/CPack/cmCPackCygwinSourceGenerator.h b/Source/CPack/cmCPackCygwinSourceGenerator.h index 9817cf9..f5ebb5b 100644 --- a/Source/CPack/cmCPackCygwinSourceGenerator.h +++ b/Source/CPack/cmCPackCygwinSourceGenerator.h @@ -32,7 +32,7 @@ protected: const char* GetPackagingInstallPrefix(); virtual int InitializeInternal(); int CompressFiles(const char* outFileName, const char* toplevel, - const std::vector<std::string>& files); + const std::vector<std::string>& files, std::list<std::string>& packageFileNames); virtual const char* GetOutputExtension(); std::string InstallPrefix; std::string OutputExtension; diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx index 1fa99e4..62f923c 100644 --- a/Source/CPack/cmCPackDragNDropGenerator.cxx +++ b/Source/CPack/cmCPackDragNDropGenerator.cxx @@ -109,6 +109,7 @@ int cmCPackDragNDropGenerator::CompressFiles(const char* outFileName, std::list<std::string>& packageFileNames) { (void) files; + (void) packageFileNames; return this->CreateDMG(toplevel, outFileName); } -- 1.7.1 0003-CPack-enable-generators-to-produce-more-than-one-pac.patch [^] (12,085 bytes) 2010-08-03 20:18 [Show Content] [Hide Content] From 6ce54b7de5a734824441be469993fa17f1f2fc55 Mon Sep 17 00:00:00 2001 From: Eric NOULARD <eric.noulard@gmail.com> Date: Tue, 3 Aug 2010 22:54:58 +0200 Subject: [PATCH 3/3] CPack enable generators to produce more than one package (part2) Add component support for ArchiveGenerators. In this patch Only the 1 component == 1 package is supported. The 1 component group == 1 package will come in another patch. (there is already some code for that but it is unfinished) --- Source/CPack/cmCPackArchiveGenerator.cxx | 116 +++++++++++++++++++++++++++--- Source/CPack/cmCPackArchiveGenerator.h | 3 + Source/CPack/cmCPackGenerator.cxx | 6 +- Source/CPack/cmCPackSTGZGenerator.cxx | 40 ++++++++-- 4 files changed, 143 insertions(+), 22 deletions(-) diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index 42a7552..7452044 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -22,6 +22,7 @@ #include <errno.h> #include <cmsys/SystemTools.hxx> +#include <cmsys/Directory.hxx> #include <cmlibarchive/libarchive/archive.h> #include <cmlibarchive/libarchive/archive_entry.h> @@ -166,10 +167,6 @@ int cmCPackArchiveGenerator::InitializeInternal() return this->Superclass::InitializeInternal(); } -int cmCPackArchiveGenerator::CompressFiles(const char* outFileName, - const char* toplevel, const std::vector<std::string>& files, std::list<std::string>& packageFileNames) -{ - int res = ARCHIVE_OK; #define CHECK_ARCHIVE_ERROR(res, msg) \ if(res != ARCHIVE_OK) \ {\ @@ -179,8 +176,15 @@ int cmCPackArchiveGenerator::CompressFiles(const char* outFileName, << " " << res \ << "\n"); \ } - cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: " - << (toplevel ? toplevel : "(NULL)") << std::endl); + +int cmCPackArchiveGenerator::CompressOneSetOfFiles(const char* outFileName, + const char* toplevel, const std::vector<std::string>& files) +{ + cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel (C1): " + << (toplevel ? toplevel : "(NULL)") + << ", outFileName = " << outFileName + << std::endl); + int res = ARCHIVE_OK; // create a new archive struct archive* a = archive_write_new(); // Set the compress and archive types for the archive @@ -193,7 +197,7 @@ int cmCPackArchiveGenerator::CompressFiles(const char* outFileName, res = archive_write_open(a, &data, OpenArchive, - WriteArchive, + WriteArchive, CloseArchive); CHECK_ARCHIVE_ERROR(res, "archive_write_open:"); // create a new disk struct @@ -210,9 +214,17 @@ int cmCPackArchiveGenerator::CompressFiles(const char* outFileName, // create a new entry for each file struct archive_entry *entry = archive_entry_new(); // Get the relative path to the file - std::string rp = cmSystemTools::RelativePath(toplevel, fileIt->c_str()); + std::string rp; + if (cmSystemTools::FileIsFullPath(fileIt->c_str())) + { + rp = cmSystemTools::RelativePath(toplevel, fileIt->c_str()); + } + else + { + rp = (*fileIt); + } // Set the name of the entry to the file name - archive_entry_set_pathname(entry, rp.c_str()); + archive_entry_set_pathname(entry, rp.c_str()); res = archive_read_disk_entry_from_file(disk, entry, -1, 0); CHECK_ARCHIVE_ERROR(res, "archive_read_disk_entry_from_file:"); // write entry header @@ -225,7 +237,7 @@ int cmCPackArchiveGenerator::CompressFiles(const char* outFileName, FILE* file = fopen(fileIt->c_str(), "rb"); if(!file) { - cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem with fopen(): " + cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem with fopen(): " << fileIt->c_str() << strerror(errno) << std::endl); @@ -238,7 +250,7 @@ int cmCPackArchiveGenerator::CompressFiles(const char* outFileName, size_t wlen = archive_write_data(a, buff, len); if(wlen != len) { - cmCPackLogger(cmCPackLog::LOG_ERROR, "archive_write_data(): " + cmCPackLogger(cmCPackLog::LOG_ERROR, "archive_write_data(): " << "tried to write " << len << "\n" << "write " << wlen << "\n"); return 0; @@ -258,8 +270,90 @@ int cmCPackArchiveGenerator::CompressFiles(const char* outFileName, return 1; } +int cmCPackArchiveGenerator::CompressFiles(const char* outFileName, + const char* toplevel, const std::vector<std::string>& files, + std::list<std::string>& packageFileNames) +{ + int res = 0; + cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: " + << (toplevel ? toplevel : "(NULL)") << std::endl); + packageFileNames.clear(); + // FIXME this is temporary because the idea of + // 1 component == 1 package file is not "that" easy to do + this->SetOption("CPACK_COMPONENT_IGNORE_COMPONENT_GROUP","1"); + // The default behavior is to have one package by component group + // unless CPACK_COMPONENT_IGNORE_COMPONENT_GROUP is specified. + if ((!this->ComponentGroups.empty()) && + (!this->GetOption("CPACK_COMPONENT_IGNORE_COMPONENT_GROUP"))) + { + std::map<std::string, cmCPackComponentGroup>::iterator compGIt; + for (compGIt=this->ComponentGroups.begin(); + compGIt!=this->ComponentGroups.end(); ++compGIt) + { + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: " + << compGIt->first + << std::endl); + std::vector<std::string> filesInPackage; + // now iterate over the component of this group + std::vector<cmCPackComponent*>::iterator compIt; + for (compIt=(compGIt->second).Components.begin(); + compIt!=(compGIt->second).Components.end(); + ++compIt) + { + cmCPackLogger(cmCPackLog::LOG_VERBOSE, " - packaging component: " + << (*compIt)->Name + << std::endl); + // Add the file + filesInPackage.insert(filesInPackage.begin(), + (*compIt)->Files.begin(), + (*compIt)->Files.end()); + } + // now create the package file for this component group + std::string localToplevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY")); + std::string packageFileName(toplevel); + + } + } + else if (!this->Components.empty()) + { + std::map<std::string, cmCPackComponent>::iterator compIt; + for (compIt=this->Components.begin();compIt!=this->Components.end(); ++compIt ) + { + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component: " + << compIt->first + << std::endl); + std::string localToplevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY")); + std::string packageFileName(toplevel); + + localToplevel += "/"+ compIt->first; + packageFileName += "/"+std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))+"-"+compIt->first + this->GetOutputExtension(); + res = CompressOneSetOfFiles(packageFileName.c_str(),localToplevel.c_str(),(compIt->second).Files); + if (0==res) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, "Failed to package component: " + << compIt->first + << std::endl); + break; + } + else + { + packageFileNames.push_back(packageFileName); + } + } + } + else + { + res = CompressOneSetOfFiles(outFileName,toplevel,files); + } + return res; +} + //---------------------------------------------------------------------- int cmCPackArchiveGenerator::GenerateHeader(std::ostream*) { return 1; } + +bool cmCPackArchiveGenerator::SupportsComponentInstallation() const { + return true; +} diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h index 19b939e..20ea4b4 100644 --- a/Source/CPack/cmCPackArchiveGenerator.h +++ b/Source/CPack/cmCPackArchiveGenerator.h @@ -39,7 +39,10 @@ protected: virtual int InitializeInternal(); int CompressFiles(const char* outFileName, const char* toplevel, const std::vector<std::string>& files, std::list<std::string>& packageFileNames); + int CompressOneSetOfFiles(const char* outFileName, + const char* toplevel, const std::vector<std::string>& files); virtual const char* GetOutputExtension() = 0; + virtual bool SupportsComponentInstallation() const; CompressType Compress; ArchiveType Archive; }; diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index d90a375..5d5ada5 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -912,9 +912,6 @@ int cmCPackGenerator::DoPackage() << " to " << (packageFileName ? packageFileName : "(NULL)") << std::endl); - cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Created package: " - << cmSystemTools::GetFilenameName(*it) - << std::endl); if ( !cmSystemTools::CopyFileIfDifferent(tempPackageFileName, packageFileName) ) { @@ -925,6 +922,9 @@ int cmCPackGenerator::DoPackage() << std::endl); return 0; } + cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Component package: " + << packageFileName + << " generated." << std::endl); } } else diff --git a/Source/CPack/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx index 1ca063d..04c179f 100644 --- a/Source/CPack/cmCPackSTGZGenerator.cxx +++ b/Source/CPack/cmCPackSTGZGenerator.cxx @@ -53,23 +53,47 @@ int cmCPackSTGZGenerator::InitializeInternal() //---------------------------------------------------------------------- int cmCPackSTGZGenerator::CompressFiles(const char* outFileName, - const char* toplevel, const std::vector<std::string>& files, std::list<std::string>& packageFileNames) + const char* toplevel, const std::vector<std::string>& files, + std::list<std::string>& packageFileNames) { + bool res=true; if ( !this->Superclass::CompressFiles(outFileName, toplevel, files, packageFileNames) ) { return 0; } - return cmSystemTools::SetPermissions(outFileName, + if (packageFileNames.size()>0) + {std::list<std::string>::iterator it; + for (it=packageFileNames.begin(); it!=packageFileNames.end();++it) + { + res = res & + cmSystemTools::SetPermissions((*it).c_str(), + #if defined( _MSC_VER ) || defined( __MINGW32__ ) + S_IREAD | S_IWRITE | S_IEXEC + #elif defined( __BORLANDC__ ) + S_IRUSR | S_IWUSR | S_IXUSR + #else + S_IRUSR | S_IWUSR | S_IXUSR | + S_IRGRP | S_IWGRP | S_IXGRP | + S_IROTH | S_IWOTH | S_IXOTH + #endif + ); + } + } + else + { + res = cmSystemTools::SetPermissions(outFileName, #if defined( _MSC_VER ) || defined( __MINGW32__ ) - S_IREAD | S_IWRITE | S_IEXEC + S_IREAD | S_IWRITE | S_IEXEC #elif defined( __BORLANDC__ ) - S_IRUSR | S_IWUSR | S_IXUSR + S_IRUSR | S_IWUSR | S_IXUSR #else - S_IRUSR | S_IWUSR | S_IXUSR | - S_IRGRP | S_IWGRP | S_IXGRP | - S_IROTH | S_IWOTH | S_IXOTH + S_IRUSR | S_IWUSR | S_IXUSR | + S_IRGRP | S_IWGRP | S_IXGRP | + S_IROTH | S_IWOTH | S_IXOTH #endif - ); + ); + } + return res; } //---------------------------------------------------------------------- -- 1.7.1 0004-CPack-enable-generators-to-produce-more-than-one-pac.patch [^] (11,474 bytes) 2010-08-04 10:08 [Show Content] [Hide Content] From 44392bfb7b9d3ea3e7104c4f41e46879ccd66a21 Mon Sep 17 00:00:00 2001 From: Eric NOULARD <eric.noulard@gmail.com> Date: Wed, 4 Aug 2010 16:05:40 +0200 Subject: [PATCH 4/4] CPack enable generators to produce more than one package (part2) Archives Generators now produce 1 package per component group unless someone specifies CPACK_COMPONENT_IGNORE_COMPONENT_GROUP=1 Signed-off-by: Eric NOULARD <eric.noulard@gmail.com> --- Source/CPack/cmCPackArchiveGenerator.cxx | 114 ++++++++++++++++++----------- Source/CPack/cmCPackArchiveGenerator.h | 17 ++++- 2 files changed, 86 insertions(+), 45 deletions(-) diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index 7452044..ac95143 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -26,7 +26,6 @@ #include <cmlibarchive/libarchive/archive.h> #include <cmlibarchive/libarchive/archive_entry.h> - //---------------------------------------------------------------------- cmCPackArchiveGenerator::cmCPackArchiveGenerator(CompressType t, ArchiveType at) @@ -112,7 +111,6 @@ struct StreamData cmCPackArchiveGenerator* Generator; }; - extern "C" { int OpenArchive(struct archive *, void *client_data) @@ -171,42 +169,48 @@ int cmCPackArchiveGenerator::InitializeInternal() if(res != ARCHIVE_OK) \ {\ cmCPackLogger(cmCPackLog::LOG_ERROR, msg \ - << archive_error_string(a) \ + << archive_error_string(archive.a) \ << cmSystemTools::GetLastSystemError() \ << " " << res \ << "\n"); \ } -int cmCPackArchiveGenerator::CompressOneSetOfFiles(const char* outFileName, - const char* toplevel, const std::vector<std::string>& files) -{ - cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel (C1): " - << (toplevel ? toplevel : "(NULL)") - << ", outFileName = " << outFileName - << std::endl); +struct cmCPackArchiveGenerator::OpenedArchive cmCPackArchiveGenerator::BeginArchive(const char* outFileName) + { + struct OpenedArchive archive; int res = ARCHIVE_OK; // create a new archive - struct archive* a = archive_write_new(); + archive.a = archive_write_new(); // Set the compress and archive types for the archive - SetArchiveType(a, this->Compress, this->Archive); + SetArchiveType(archive.a, this->Compress, this->Archive); // Open binary stream - cmGeneratedFileStream* gf = new cmGeneratedFileStream; - gf->Open(outFileName, false, true); - StreamData data(gf, this); + archive.gf = new cmGeneratedFileStream; + archive.gf->Open(outFileName, false, true); + archive.sdata = new StreamData(archive.gf, this); // pass callbacks to archive_write_open to handle stream - res = archive_write_open(a, - &data, - OpenArchive, - WriteArchive, - CloseArchive); + res = archive_write_open(archive.a, + archive.sdata, + OpenArchive, + WriteArchive, + CloseArchive); CHECK_ARCHIVE_ERROR(res, "archive_write_open:"); // create a new disk struct - struct archive* disk = archive_read_disk_new(); + archive.disk = archive_read_disk_new(); #if !defined(_WIN32) || defined(__CYGWIN__) - res = archive_read_disk_set_standard_lookup(disk); + res = archive_read_disk_set_standard_lookup(archive.disk); #endif CHECK_ARCHIVE_ERROR(res, "archive_read_disk_set_standard_lookup:"); + return archive; + } + +int cmCPackArchiveGenerator::AddFilesToArchive(struct OpenedArchive archive, const char* toplevel, const std::vector<std::string>& files) + { + int res = ARCHIVE_OK; std::vector<std::string>::const_iterator fileIt; + cmCPackLogger(cmCPackLog::LOG_DEBUG, " - Adding <" + << files.size() <<"> files from TOPLEVEL <" + << toplevel <<"> to archive" + << std::endl); std::string dir = cmSystemTools::GetCurrentWorkingDirectory(); cmSystemTools::ChangeDirectory(toplevel); for ( fileIt = files.begin(); fileIt != files.end(); ++ fileIt ) @@ -225,10 +229,10 @@ int cmCPackArchiveGenerator::CompressOneSetOfFiles(const char* outFileName, } // Set the name of the entry to the file name archive_entry_set_pathname(entry, rp.c_str()); - res = archive_read_disk_entry_from_file(disk, entry, -1, 0); + res = archive_read_disk_entry_from_file(archive.disk, entry, -1, 0); CHECK_ARCHIVE_ERROR(res, "archive_read_disk_entry_from_file:"); // write entry header - res = archive_write_header(a, entry); + res = archive_write_header(archive.a, entry); CHECK_ARCHIVE_ERROR(res, "archive_write_header:"); // the entry size can be 0 if it is a symlink if(archive_entry_size(entry) > 0) @@ -247,7 +251,7 @@ int cmCPackArchiveGenerator::CompressOneSetOfFiles(const char* outFileName, size_t len = fread(buff, 1, sizeof(buff), file); while (len > 0) { - size_t wlen = archive_write_data(a, buff, len); + size_t wlen = archive_write_data(archive.a, buff, len); if(wlen != len) { cmCPackLogger(cmCPackLog::LOG_ERROR, "archive_write_data(): " @@ -263,12 +267,19 @@ int cmCPackArchiveGenerator::CompressOneSetOfFiles(const char* outFileName, archive_entry_free(entry); } cmSystemTools::ChangeDirectory(dir.c_str()); + return 1; + } + +int cmCPackArchiveGenerator::EndArchive(struct OpenedArchive archive) + { // close the archive and finish the write - archive_write_close(a); - archive_write_finish(a); - archive_read_finish(disk); + archive_write_close(archive.a); + archive_write_finish(archive.a); + archive_read_finish(archive.disk); return 1; -} + } + + int cmCPackArchiveGenerator::CompressFiles(const char* outFileName, const char* toplevel, const std::vector<std::string>& files, @@ -278,9 +289,6 @@ int cmCPackArchiveGenerator::CompressFiles(const char* outFileName, cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: " << (toplevel ? toplevel : "(NULL)") << std::endl); packageFileNames.clear(); - // FIXME this is temporary because the idea of - // 1 component == 1 package file is not "that" easy to do - this->SetOption("CPACK_COMPONENT_IGNORE_COMPONENT_GROUP","1"); // The default behavior is to have one package by component group // unless CPACK_COMPONENT_IGNORE_COMPONENT_GROUP is specified. if ((!this->ComponentGroups.empty()) && @@ -293,9 +301,17 @@ int cmCPackArchiveGenerator::CompressFiles(const char* outFileName, cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: " << compGIt->first << std::endl); - std::vector<std::string> filesInPackage; + // Begin the archive for this group + std::string packageFileName(toplevel); + packageFileName += "/"+std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))+"-"+compGIt->first + this->GetOutputExtension(); + cmCPackLogger(cmCPackLog::LOG_VERBOSE, " - Will create archive: " + << packageFileName + << std::endl); + struct OpenedArchive oa = BeginArchive(packageFileName.c_str()); + // now iterate over the component of this group std::vector<cmCPackComponent*>::iterator compIt; + res = 1; for (compIt=(compGIt->second).Components.begin(); compIt!=(compGIt->second).Components.end(); ++compIt) @@ -303,15 +319,23 @@ int cmCPackArchiveGenerator::CompressFiles(const char* outFileName, cmCPackLogger(cmCPackLog::LOG_VERBOSE, " - packaging component: " << (*compIt)->Name << std::endl); - // Add the file - filesInPackage.insert(filesInPackage.begin(), - (*compIt)->Files.begin(), - (*compIt)->Files.end()); + // Add the files of this component to the archive + std::string localToplevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY")); + localToplevel += "/"+ (*compIt)->Name; + res = res & AddFilesToArchive(oa,localToplevel.c_str(),(*compIt)->Files); + } + res = res & EndArchive(oa); + if (0==res) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, "Failed to package component group: " + << compGIt->first + << std::endl); + break; + } + else + { + packageFileNames.push_back(packageFileName); } - // now create the package file for this component group - std::string localToplevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY")); - std::string packageFileName(toplevel); - } } else if (!this->Components.empty()) @@ -327,7 +351,9 @@ int cmCPackArchiveGenerator::CompressFiles(const char* outFileName, localToplevel += "/"+ compIt->first; packageFileName += "/"+std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))+"-"+compIt->first + this->GetOutputExtension(); - res = CompressOneSetOfFiles(packageFileName.c_str(),localToplevel.c_str(),(compIt->second).Files); + struct OpenedArchive oa = BeginArchive(packageFileName.c_str()); + res = AddFilesToArchive(oa,localToplevel.c_str(),(compIt->second).Files); + res = res & EndArchive(oa); if (0==res) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Failed to package component: " @@ -343,7 +369,9 @@ int cmCPackArchiveGenerator::CompressFiles(const char* outFileName, } else { - res = CompressOneSetOfFiles(outFileName,toplevel,files); + struct OpenedArchive oa = BeginArchive(outFileName); + res = AddFilesToArchive(oa,toplevel,files); + res = res & EndArchive(oa); } return res; } diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h index 20ea4b4..79dc86d 100644 --- a/Source/CPack/cmCPackArchiveGenerator.h +++ b/Source/CPack/cmCPackArchiveGenerator.h @@ -14,6 +14,7 @@ #define cmCPackArchiveGenerator_h #include "cmCPackGenerator.h" +#include "cmGeneratedFileStream.h" /** \class cmCPackArchiveGenerator @@ -36,11 +37,23 @@ public: virtual int GenerateHeader(std::ostream* os); protected: + + // Internal structure used to incrementally build an archive. + struct OpenedArchive { + struct archive* a; + cmGeneratedFileStream* gf; + struct archive* disk; + void* sdata; + }; + virtual int InitializeInternal(); + + struct OpenedArchive BeginArchive(const char* outFileName); + int AddFilesToArchive(struct OpenedArchive archive, const char* toplevel, const std::vector<std::string>& files); + int EndArchive(struct OpenedArchive archive); + int CompressFiles(const char* outFileName, const char* toplevel, const std::vector<std::string>& files, std::list<std::string>& packageFileNames); - int CompressOneSetOfFiles(const char* outFileName, - const char* toplevel, const std::vector<std::string>& files); virtual const char* GetOutputExtension() = 0; virtual bool SupportsComponentInstallation() const; CompressType Compress; -- 1.7.1 0005-CPack-enable-generators-to-produce-more-than-one-pac.patch [^] (5,469 bytes) 2010-08-05 18:30 [Show Content] [Hide Content] From b5996c0189f3c64738d83965724b24db6a63a01a Mon Sep 17 00:00:00 2001 From: Eric NOULARD <eric.noulard@gmail.com> Date: Thu, 5 Aug 2010 19:58:13 +0200 Subject: [PATCH 5/6] CPack enable generators to produce more than one package (part2.1) Archives Generators now produce 1 package per component group unless someone specifies CPACK_COMPONENTS_IGNORE_GROUPS=1 Archive may also produce ALL GROUPS in one packages if CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE=1 Signed-off-by: Eric NOULARD <eric.noulard@gmail.com> --- Source/CPack/cmCPackArchiveGenerator.cxx | 62 +++++++++++++++++++++++------ 1 files changed, 49 insertions(+), 13 deletions(-) diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index ac95143..6166118 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -289,10 +289,22 @@ int cmCPackArchiveGenerator::CompressFiles(const char* outFileName, cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: " << (toplevel ? toplevel : "(NULL)") << std::endl); packageFileNames.clear(); + bool allInOne = (NULL != (this->GetOption("CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE"))); + std::string packageFileName(toplevel); + struct OpenedArchive oa; + + // If ALL GROUPS in ONE package has been requested then the package + // file is unique and should be open here. + if (allInOne && (!this->ComponentGroups.empty())) { + packageFileName += "/"+std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))+"-ALL" + this->GetOutputExtension(); + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging all groups in one package...(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE is set)" + << std::endl); + oa = BeginArchive(packageFileName.c_str()); + } // The default behavior is to have one package by component group - // unless CPACK_COMPONENT_IGNORE_COMPONENT_GROUP is specified. + // unless CPACK_COMPONENTS_IGNORE_GROUP is specified. if ((!this->ComponentGroups.empty()) && - (!this->GetOption("CPACK_COMPONENT_IGNORE_COMPONENT_GROUP"))) + (!this->GetOption("CPACK_COMPONENTS_IGNORE_GROUPS"))) { std::map<std::string, cmCPackComponentGroup>::iterator compGIt; for (compGIt=this->ComponentGroups.begin(); @@ -302,13 +314,16 @@ int cmCPackArchiveGenerator::CompressFiles(const char* outFileName, << compGIt->first << std::endl); // Begin the archive for this group - std::string packageFileName(toplevel); - packageFileName += "/"+std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))+"-"+compGIt->first + this->GetOutputExtension(); - cmCPackLogger(cmCPackLog::LOG_VERBOSE, " - Will create archive: " - << packageFileName - << std::endl); - struct OpenedArchive oa = BeginArchive(packageFileName.c_str()); + if (!allInOne) + { + packageFileName= std::string(toplevel); + packageFileName += "/"+std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))+"-"+compGIt->first + this->GetOutputExtension(); + cmCPackLogger(cmCPackLog::LOG_VERBOSE, " - Will create archive: " + << packageFileName + << std::endl); + oa = BeginArchive(packageFileName.c_str()); + } // now iterate over the component of this group std::vector<cmCPackComponent*>::iterator compIt; res = 1; @@ -324,7 +339,11 @@ int cmCPackArchiveGenerator::CompressFiles(const char* outFileName, localToplevel += "/"+ (*compIt)->Name; res = res & AddFilesToArchive(oa,localToplevel.c_str(),(*compIt)->Files); } - res = res & EndArchive(oa); + // Do not end archive now if all in one + if (!allInOne) + { + res = res & EndArchive(oa); + } if (0==res) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Failed to package component group: " @@ -334,9 +353,26 @@ int cmCPackArchiveGenerator::CompressFiles(const char* outFileName, } else { - packageFileNames.push_back(packageFileName); - } - } + if (!allInOne) + { + packageFileNames.push_back(packageFileName); + } + } // else of if(0==res) + } // end for loop over component groups + if (allInOne) + { + res = res & EndArchive(oa); + if (0==res) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, "Failed to package All-in-one package: " + << packageFileName + << std::endl); + } + else + { + packageFileNames.push_back(packageFileName); + } + } // end if (allInOne) } else if (!this->Components.empty()) { @@ -347,7 +383,7 @@ int cmCPackArchiveGenerator::CompressFiles(const char* outFileName, << compIt->first << std::endl); std::string localToplevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY")); - std::string packageFileName(toplevel); + packageFileName = std::string(toplevel); localToplevel += "/"+ compIt->first; packageFileName += "/"+std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))+"-"+compIt->first + this->GetOutputExtension(); -- 1.7.1 0001-CPackArchiveGenerator-use-cmArchiveWrite-wrapper.patch [^] (12,927 bytes) 2010-08-21 07:44 [Show Content] [Hide Content] From 533cac635d456a79638cbf98ae65145313417dd1 Mon Sep 17 00:00:00 2001 From: Eric NOULARD <eric.noulard@gmail.com> Date: Sun, 15 Aug 2010 17:56:03 +0200 Subject: [PATCH 1/2] CPackArchiveGenerator use cmArchiveWrite wrapper --- Source/CPack/cmCPackArchiveGenerator.cxx | 226 ++++---------------------- Source/CPack/cmCPackArchiveGenerator.h | 13 +- Source/CPack/cmCPackTGZGenerator.cxx | 4 +- Source/CPack/cmCPackTarBZip2Generator.cxx | 4 +- Source/CPack/cmCPackTarCompressGenerator.cxx | 4 +- Source/CPack/cmCPackZIPGenerator.cxx | 4 +- 6 files changed, 47 insertions(+), 208 deletions(-) diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index 8799330..01a6cf1 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -25,8 +25,8 @@ #include <cm_libarchive.h> //---------------------------------------------------------------------- -cmCPackArchiveGenerator::cmCPackArchiveGenerator(CompressType t, - ArchiveType at) +cmCPackArchiveGenerator::cmCPackArchiveGenerator(cmArchiveWrite::Compress t, + cmArchiveWrite::Type at) { this->Compress = t; this->Archive = at; @@ -37,126 +37,6 @@ cmCPackArchiveGenerator::~cmCPackArchiveGenerator() { } -static const size_t cmCPackTGZ_Data_BlockSize = 16384; - -// make this an anonymous namespace so that archive.h does not -// have to be included in the .h file for this class -namespace -{ -bool SetArchiveType(struct archive* a, - cmCPackArchiveGenerator::CompressType ct, - cmCPackArchiveGenerator::ArchiveType at) -{ - int res = 0; - // pick the archive type - switch(at) - { - case cmCPackArchiveGenerator::TAR: - // maybe this: - res = archive_write_set_format_pax_restricted(a); - break; - case cmCPackArchiveGenerator::ZIP: - res = archive_write_set_format_zip(a); - break; - } - if(res != ARCHIVE_OK) - { - return false; - } - - // pick a compression type - switch(ct) - { - case cmCPackArchiveGenerator::GZIP: - res = archive_write_set_compression_gzip(a); - break; - case cmCPackArchiveGenerator::BZIP2: - res = archive_write_set_compression_bzip2(a); - break; - case cmCPackArchiveGenerator::COMPRESS: - res = archive_write_set_compression_compress(a); - break; - case cmCPackArchiveGenerator::LZMA: - res = archive_write_set_compression_lzma(a); - break; - case cmCPackArchiveGenerator::NONE: - default: - res = archive_write_set_compression_none(a); - } - if(res != ARCHIVE_OK) - { - return false; - } - // do not pad the last block!! - res = archive_write_set_bytes_in_last_block(a, 1); - if(res != ARCHIVE_OK) - { - return false; - } - - return true; -} - -struct StreamData -{ - StreamData(cmGeneratedFileStream* gfs, - cmCPackArchiveGenerator* ag) - { - this->GeneratedFileStream = gfs; - this->Generator = ag; - } - cmGeneratedFileStream* GeneratedFileStream; - cmCPackArchiveGenerator* Generator; -}; - - -extern "C" -{ -int OpenArchive(struct archive *, void *client_data) -{ - struct StreamData *data = (StreamData*)client_data; - if(data->GeneratedFileStream && - *data->GeneratedFileStream) - { - if(data->Generator-> - GenerateHeader(data->GeneratedFileStream)) - { - return ARCHIVE_OK; - } - } - return (ARCHIVE_FATAL); -} - -__LA_SSIZE_T WriteArchive(struct archive *, - void *client_data, - const void *buff, - size_t n) -{ - struct StreamData *data = (StreamData*)client_data; - data->GeneratedFileStream-> - write(reinterpret_cast<const char*>(buff),n); - if(!data->GeneratedFileStream->bad()) - { - return n; - } - return 0; -} - - -int CloseArchive(struct archive *, void *client_data) -{ - struct StreamData *data = (StreamData*)client_data; - if(data->GeneratedFileStream->Close()) - { - delete data->GeneratedFileStream; - return ARCHIVE_OK; - } - return ARCHIVE_FATAL; -} -} //extern C -} // anon name space - - //---------------------------------------------------------------------- int cmCPackArchiveGenerator::InitializeInternal() { @@ -166,93 +46,51 @@ int cmCPackArchiveGenerator::InitializeInternal() int cmCPackArchiveGenerator::PackageFiles() { - int res = ARCHIVE_OK; -#define CHECK_ARCHIVE_ERROR(res, msg) \ - if(res != ARCHIVE_OK) \ - {\ - cmCPackLogger(cmCPackLog::LOG_ERROR, msg \ - << archive_error_string(a) \ - << cmSystemTools::GetLastSystemError() \ - << " " << res \ - << "\n"); \ - } cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: " << toplevel << std::endl); - // create a new archive - struct archive* a = archive_write_new(); - // Set the compress and archive types for the archive - SetArchiveType(a, this->Compress, this->Archive); // Open binary stream - cmGeneratedFileStream* gf = new cmGeneratedFileStream; - gf->Open(packageFileNames[0].c_str(), false, true); - StreamData data(gf, this); - // pass callbacks to archive_write_open to handle stream - res = archive_write_open(a, - &data, - OpenArchive, - WriteArchive, - CloseArchive); - CHECK_ARCHIVE_ERROR(res, "archive_write_open:"); - // create a new disk struct - struct archive* disk = archive_read_disk_new(); -#if !defined(_WIN32) || defined(__CYGWIN__) - res = archive_read_disk_set_standard_lookup(disk); -#endif - CHECK_ARCHIVE_ERROR(res, "archive_read_disk_set_standard_lookup:"); + cmGeneratedFileStream gf; + gf.Open(packageFileNames[0].c_str(), false, true); + // Add an eventual header to the archive + if (!GenerateHeader(&gf)) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem to generate Header for archive < " + << packageFileNames[0] + << ">." << std::endl); + } + // create a new archive + cmArchiveWrite archive(gf,this->Compress, this->Archive); + if (!archive) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem to create archive < " + << packageFileNames[0] + << ">. ERROR =" + << archive.GetError() + << std::endl); + return 0; + } std::vector<std::string>::const_iterator fileIt; std::string dir = cmSystemTools::GetCurrentWorkingDirectory(); cmSystemTools::ChangeDirectory(toplevel.c_str()); for ( fileIt = files.begin(); fileIt != files.end(); ++ fileIt ) { - // create a new entry for each file - struct archive_entry *entry = archive_entry_new(); // Get the relative path to the file std::string rp = cmSystemTools::RelativePath(toplevel.c_str(), fileIt->c_str()); - // Set the name of the entry to the file name - archive_entry_set_pathname(entry, rp.c_str()); - res = archive_read_disk_entry_from_file(disk, entry, -1, 0); - CHECK_ARCHIVE_ERROR(res, "archive_read_disk_entry_from_file:"); - // write entry header - res = archive_write_header(a, entry); - CHECK_ARCHIVE_ERROR(res, "archive_write_header:"); - // the entry size can be 0 if it is a symlink - if(archive_entry_size(entry) > 0) + archive.Add(rp); + if(!archive) { - // now copy contents of file into archive a - FILE* file = fopen(fileIt->c_str(), "rb"); - if(!file) - { - cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem with fopen(): " - << fileIt->c_str() - << strerror(errno) - << std::endl); - return 0; - } - char buff[cmCPackTGZ_Data_BlockSize]; - size_t len = fread(buff, 1, sizeof(buff), file); - while (len > 0) - { - size_t wlen = archive_write_data(a, buff, len); - if(wlen != len) - { - cmCPackLogger(cmCPackLog::LOG_ERROR, "archive_write_data(): " - << "tried to write " << len << "\n" - << "write " << wlen << "\n"); - return 0; - } - len = fread(buff, 1, sizeof(buff), file); - } - // close the file and free the entry - fclose(file); + cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem while adding file< " + << *fileIt + << "> to archive <" + << packageFileNames[0] << "> .ERROR =" + << archive.GetError() + << std::endl); + return 0; } - archive_entry_free(entry); } cmSystemTools::ChangeDirectory(dir.c_str()); - // close the archive and finish the write - archive_write_close(a); - archive_write_finish(a); - archive_read_finish(disk); + // The destructor of cmArchiveWrite will close and finish the write return 1; } diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h index d3409ae..49ae112 100644 --- a/Source/CPack/cmCPackArchiveGenerator.h +++ b/Source/CPack/cmCPackArchiveGenerator.h @@ -13,24 +13,25 @@ #ifndef cmCPackArchiveGenerator_h #define cmCPackArchiveGenerator_h +#include "cmArchiveWrite.h" #include "cmCPackGenerator.h" /** \class cmCPackArchiveGenerator - * \brief A generator base for libarchive generation + * \brief A generator base for libarchive generation. + * The generator itself uses the libarchive wrapper + * \ref cmArchiveWrite. * */ class cmCPackArchiveGenerator : public cmCPackGenerator { public: - enum CompressType{ GZIP, BZIP2, COMPRESS, LZMA, NONE}; - enum ArchiveType{ TAR, ZIP}; cmTypeMacro(cmCPackArchiveGenerator, cmCPackGenerator); /** * Construct generator */ - cmCPackArchiveGenerator(CompressType, ArchiveType); + cmCPackArchiveGenerator(cmArchiveWrite::Compress, cmArchiveWrite::Type); virtual ~cmCPackArchiveGenerator(); // Used to add a header to the archive virtual int GenerateHeader(std::ostream* os); @@ -39,8 +40,8 @@ protected: virtual int InitializeInternal(); int PackageFiles(); virtual const char* GetOutputExtension() = 0; - CompressType Compress; - ArchiveType Archive; + cmArchiveWrite::Compress Compress; + cmArchiveWrite::Type Archive; }; #endif diff --git a/Source/CPack/cmCPackTGZGenerator.cxx b/Source/CPack/cmCPackTGZGenerator.cxx index c6ef8ae..509c7f8 100644 --- a/Source/CPack/cmCPackTGZGenerator.cxx +++ b/Source/CPack/cmCPackTGZGenerator.cxx @@ -14,8 +14,8 @@ //---------------------------------------------------------------------- cmCPackTGZGenerator::cmCPackTGZGenerator() - :cmCPackArchiveGenerator(cmCPackArchiveGenerator::GZIP, - cmCPackArchiveGenerator::TAR) + :cmCPackArchiveGenerator(cmArchiveWrite::CompressGZip, + cmArchiveWrite::TypeTAR) { } diff --git a/Source/CPack/cmCPackTarBZip2Generator.cxx b/Source/CPack/cmCPackTarBZip2Generator.cxx index 52826dc..971d166 100644 --- a/Source/CPack/cmCPackTarBZip2Generator.cxx +++ b/Source/CPack/cmCPackTarBZip2Generator.cxx @@ -13,8 +13,8 @@ #include "cmCPackTarBZip2Generator.h" //---------------------------------------------------------------------- cmCPackTarBZip2Generator::cmCPackTarBZip2Generator() - :cmCPackArchiveGenerator(cmCPackArchiveGenerator::BZIP2, - cmCPackArchiveGenerator::TAR) + :cmCPackArchiveGenerator(cmArchiveWrite::CompressBZip2, + cmArchiveWrite::TypeTAR) { } diff --git a/Source/CPack/cmCPackTarCompressGenerator.cxx b/Source/CPack/cmCPackTarCompressGenerator.cxx index e9b5e2e..7a8f697 100644 --- a/Source/CPack/cmCPackTarCompressGenerator.cxx +++ b/Source/CPack/cmCPackTarCompressGenerator.cxx @@ -14,8 +14,8 @@ //---------------------------------------------------------------------- cmCPackTarCompressGenerator::cmCPackTarCompressGenerator() - :cmCPackArchiveGenerator(cmCPackArchiveGenerator::COMPRESS, - cmCPackArchiveGenerator::TAR) + :cmCPackArchiveGenerator(cmArchiveWrite::CompressCompress, + cmArchiveWrite::TypeTAR) { } diff --git a/Source/CPack/cmCPackZIPGenerator.cxx b/Source/CPack/cmCPackZIPGenerator.cxx index e195f83..e6e4e77 100644 --- a/Source/CPack/cmCPackZIPGenerator.cxx +++ b/Source/CPack/cmCPackZIPGenerator.cxx @@ -14,8 +14,8 @@ //---------------------------------------------------------------------- cmCPackZIPGenerator::cmCPackZIPGenerator() - :cmCPackArchiveGenerator(cmCPackArchiveGenerator::NONE, - cmCPackArchiveGenerator::ZIP) + :cmCPackArchiveGenerator(cmArchiveWrite::CompressNone, + cmArchiveWrite::TypeZIP) { } -- 1.7.1 0002-CPackArchiveGenerator-add-component-supports.patch [^] (13,331 bytes) 2010-08-21 07:44 [Show Content] [Hide Content] From fc78b6c01e279920a553028804b5264f376ab7eb Mon Sep 17 00:00:00 2001 From: Eric NOULARD <eric.noulard@gmail.com> Date: Sat, 21 Aug 2010 13:33:36 +0200 Subject: [PATCH 2/2] CPackArchiveGenerator add component supports --- Source/CPack/cmCPackArchiveGenerator.cxx | 205 +++++++++++++++++++++++++++--- Source/CPack/cmCPackArchiveGenerator.h | 32 ++++- Source/CPack/cmCPackGenerator.cxx | 10 +- 3 files changed, 224 insertions(+), 23 deletions(-) diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index 01a6cf1..d42aee6 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -22,6 +22,7 @@ #include <errno.h> #include <cmsys/SystemTools.hxx> +#include <cmsys/Directory.hxx> #include <cm_libarchive.h> //---------------------------------------------------------------------- @@ -43,33 +44,198 @@ int cmCPackArchiveGenerator::InitializeInternal() this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "1"); return this->Superclass::InitializeInternal(); } +//---------------------------------------------------------------------- +int cmCPackArchiveGenerator::addOneComponentToArchive(cmArchiveWrite& archive, + cmCPackComponent* component) +{ + cmCPackLogger(cmCPackLog::LOG_VERBOSE, " - packaging component: " + << component->Name + << std::endl); + // Add the files of this component to the archive + std::string localToplevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY")); + localToplevel += "/"+ component->Name; + std::string dir = cmSystemTools::GetCurrentWorkingDirectory(); + // Change to local toplevel + cmSystemTools::ChangeDirectory(localToplevel.c_str()); + std::vector<std::string>::const_iterator fileIt; + for (fileIt = component->Files.begin(); fileIt != component->Files.end(); ++fileIt ) + { + cmCPackLogger(cmCPackLog::LOG_DEBUG,"Adding file: " << (*fileIt) << std::endl); + archive.Add(*fileIt); + if (!archive) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, "ERROR while packaging files: " + << archive.GetError() + << std::endl); + return 0; + } + } + // Go back to previous dir + cmSystemTools::ChangeDirectory(dir.c_str()); + return 1; +} + +/* + * The macro will open/create a file 'filename' + * an declare and open the associated + * cmArchiveWrite 'archive' object. + */ +#define DECLARE_AND_OPEN_ARCHIVE(filename,archive) \ +cmGeneratedFileStream gf; \ +gf.Open(filename.c_str(), false, true); \ +if (!GenerateHeader(&gf)) \ + { \ + cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem to generate Header for archive < " \ + << filename \ + << ">." << std::endl); \ + return 0; \ + } \ +cmArchiveWrite archive(gf,this->Compress, this->Archive); \ +if (!archive) \ + { \ + cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem to create archive < " \ + << filename \ + << ">. ERROR =" \ + << archive.GetError() \ + << std::endl); \ + return 0; \ + } + +//---------------------------------------------------------------------- +int cmCPackArchiveGenerator::PackageComponents(bool ignoreComponentGroup) +{ + packageFileNames.clear(); + // The default behavior is to have one package by component group + // unless CPACK_COMPONENTS_IGNORE_GROUP is specified. + if (!ignoreComponentGroup) + { + std::map<std::string, cmCPackComponentGroup>::iterator compGIt; + for (compGIt=this->ComponentGroups.begin(); + compGIt!=this->ComponentGroups.end(); ++compGIt) + { + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: " + << compGIt->first + << std::endl); + // Begin the archive for this group + std::string packageFileName= std::string(toplevel); + packageFileName += "/"+std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))+"-"+compGIt->first + this->GetOutputExtension(); + // open a block in order to automatically close archive + // at the end of the block + { + DECLARE_AND_OPEN_ARCHIVE(packageFileName,archive); + // now iterate over the component of this group + std::vector<cmCPackComponent*>::iterator compIt; + for (compIt=(compGIt->second).Components.begin(); + compIt!=(compGIt->second).Components.end(); + ++compIt) + { + // Add the files of this component to the archive + addOneComponentToArchive(archive,*compIt); + } + } + // add the generated package to package file names list + packageFileNames.push_back(packageFileName); + } + } + // CPACK_COMPONENTS_IGNORE_GROUPS is set + // We build 1 package per component + else + { + std::map<std::string, cmCPackComponent>::iterator compIt; + for (compIt=this->Components.begin();compIt!=this->Components.end(); ++compIt ) + { + std::string localToplevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY")); + std::string packageFileName = std::string(toplevel); + localToplevel += "/"+ compIt->first; + packageFileName += "/"+std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))+"-"+compIt->first + this->GetOutputExtension(); + { + DECLARE_AND_OPEN_ARCHIVE(packageFileName,archive); + // Add the files of this component to the archive + addOneComponentToArchive(archive,&(compIt->second)); + } + // add the generated package to package file names list + packageFileNames.push_back(packageFileName); + } + } + return 1; +} + +//---------------------------------------------------------------------- +int cmCPackArchiveGenerator::PackageComponentsAllInOne(bool allComponentInOne) +{ + // reset the package file names + packageFileNames.clear(); + packageFileNames.push_back(std::string(toplevel)); + packageFileNames[0] += "/"+std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))+"-ALL" + this->GetOutputExtension(); + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging all groups in one package...(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE is set)" + << std::endl); + DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0],archive); + + // The ALL GROUP in ONE package case + if (! allComponentInOne) { + // iterate over the component groups + std::map<std::string, cmCPackComponentGroup>::iterator compGIt; + for (compGIt=this->ComponentGroups.begin(); + compGIt!=this->ComponentGroups.end(); ++compGIt) + { + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: " + << compGIt->first + << std::endl); + // now iterate over the component of this group + std::vector<cmCPackComponent*>::iterator compIt; + for (compIt=(compGIt->second).Components.begin(); + compIt!=(compGIt->second).Components.end(); + ++compIt) + { + // Add the files of this component to the archive + addOneComponentToArchive(archive,*compIt); + } + } + } + // The ALL COMPONENT in ONE package case + else + { + std::map<std::string, cmCPackComponent>::iterator compIt; + for (compIt=this->Components.begin();compIt!=this->Components.end(); ++compIt ) + { + // Add the files of this component to the archive + addOneComponentToArchive(archive,&(compIt->second)); + } + } + // archive goes out of scope so it will finalized and closed. + return 1; +} + +//---------------------------------------------------------------------- int cmCPackArchiveGenerator::PackageFiles() { cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: " << toplevel << std::endl); - // Open binary stream - cmGeneratedFileStream gf; - gf.Open(packageFileNames[0].c_str(), false, true); - // Add an eventual header to the archive - if (!GenerateHeader(&gf)) + // The default behavior is to create 1 package by component group + // unless the user asked to put all COMPONENTS in a single package + bool allGroupInOne = (NULL != (this->GetOption("CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE"))); + bool allComponentInOne = (NULL != (this->GetOption("CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE"))); + bool ignoreComponentGroup = ( NULL != (this->GetOption("CPACK_COMPONENTS_IGNORE_GROUPS"))); + // CASE 1 : COMPONENT ALL-IN-ONE package + // If ALL GROUPS or ALL COMPONENTS in ONE package has been requested + // then the package file is unique and should be open here. + if ((allComponentInOne || allGroupInOne) && (!this->ComponentGroups.empty())) { - cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem to generate Header for archive < " - << packageFileNames[0] - << ">." << std::endl); + return PackageComponentsAllInOne(allComponentInOne); } - // create a new archive - cmArchiveWrite archive(gf,this->Compress, this->Archive); - if (!archive) + // CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one) + // There will be 1 package for each component group + // however one may require to ignore component group and + // in this case you'll get 1 package for each component. + else if (!this->ComponentGroups.empty()) { - cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem to create archive < " - << packageFileNames[0] - << ">. ERROR =" - << archive.GetError() - << std::endl); - return 0; + return PackageComponents(ignoreComponentGroup); } + + // CASE 3 : NON COMPONENT package. + DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0],archive); std::vector<std::string>::const_iterator fileIt; std::string dir = cmSystemTools::GetCurrentWorkingDirectory(); cmSystemTools::ChangeDirectory(toplevel.c_str()); @@ -99,3 +265,8 @@ int cmCPackArchiveGenerator::GenerateHeader(std::ostream*) { return 1; } + +bool cmCPackArchiveGenerator::SupportsComponentInstallation() const { + return true; +} + diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h index 49ae112..ae545c8 100644 --- a/Source/CPack/cmCPackArchiveGenerator.h +++ b/Source/CPack/cmCPackArchiveGenerator.h @@ -24,7 +24,7 @@ * */ class cmCPackArchiveGenerator : public cmCPackGenerator -{ + { public: cmTypeMacro(cmCPackArchiveGenerator, cmCPackGenerator); @@ -35,13 +35,39 @@ public: virtual ~cmCPackArchiveGenerator(); // Used to add a header to the archive virtual int GenerateHeader(std::ostream* os); - + // component support + virtual bool SupportsComponentInstallation() const; protected: virtual int InitializeInternal(); + /** + * Add the files belonging to the specified component + * to the provided (already opened) archive. + * @param[in,out] archive the archive object + * @param[in] component the component whose file will be added to archive + */ + int addOneComponentToArchive(cmArchiveWrite& archive, cmCPackComponent* component); + + /** + * The main package file method. + * If component install was required this + * method will call either PackageComponents or + * PackageComponentsAllInOne. + */ int PackageFiles(); + /** + * The method used to package files when component + * install is used. This will create one + * archive for each component group. + */ + int PackageComponents(bool ignoreComponentGroup); + /** + * Special case of component install where all + * components will be put in a single installer. + */ + int PackageComponentsAllInOne(bool allComponentInOne); virtual const char* GetOutputExtension() = 0; cmArchiveWrite::Compress Compress; cmArchiveWrite::Type Archive; -}; + }; #endif diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 4ae2d1f..ca3f074 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -828,8 +828,8 @@ int cmCPackGenerator::DoPackage() return 0; } - cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Compress package" << std::endl); - cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Compress files to: " + cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Create package" << std::endl); + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Package files to: " << (tempPackageFileName ? tempPackageFileName : "(NULL)") << std::endl); if ( cmSystemTools::FileExists(tempPackageFileName) ) { @@ -853,7 +853,10 @@ int cmCPackGenerator::DoPackage() std::vector<std::string>::const_iterator it; for ( it = files.begin(); it != files.end(); ++ it ) { - std::string fileN = cmSystemTools::RelativePath(tempDirectory, + // beware we cannot just use tempDirectory as before + // because some generator will "CPACK_INCLUDE_TOPLEVEL_DIRECTORY" + // we really want "CPACK_TEMPORARY_DIRECTORY" + std::string fileN = cmSystemTools::RelativePath(this->GetOption("CPACK_TEMPORARY_DIRECTORY"), it->c_str()); // Determine which component we are in. @@ -864,6 +867,7 @@ int cmCPackGenerator::DoPackage() // Add this file to the list of files for the component. this->Components[componentName].Files.push_back(fileN); + cmCPackLogger(cmCPackLog::LOG_DEBUG, "Adding file <" <<fileN<<"> to component <"<<componentName<<">"<<std::endl); } } -- 1.7.1 0003-CPackArchiveGenerator-improve-usability-and-robustne.patch [^] (3,354 bytes) 2010-08-22 12:21 [Show Content] [Hide Content] From ec2e2511eeef3f1849cc453fb7559221b8a94b40 Mon Sep 17 00:00:00 2001 From: Eric NOULARD <eric.noulard@gmail.com> Date: Sun, 22 Aug 2010 18:18:39 +0200 Subject: [PATCH 3/3] CPackArchiveGenerator improve usability and robustness Handle the "no group defined" case Implement the idea from Rolf Eike Beer to have a single var CPACK_COMPONENTS_GROUPING with several values --- Source/CPack/cmCPackArchiveGenerator.cxx | 48 ++++++++++++++++++++++++++++- 1 files changed, 46 insertions(+), 2 deletions(-) diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index d42aee6..452267b 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -218,10 +218,54 @@ int cmCPackArchiveGenerator::PackageFiles() bool allGroupInOne = (NULL != (this->GetOption("CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE"))); bool allComponentInOne = (NULL != (this->GetOption("CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE"))); bool ignoreComponentGroup = ( NULL != (this->GetOption("CPACK_COMPONENTS_IGNORE_GROUPS"))); + + std::string groupingType; + + // Second way to specify grouping + if (NULL != this->GetOption("CPACK_COMPONENTS_GROUPING")) { + groupingType = this->GetOption("CPACK_COMPONENTS_GROUPING"); + } + + if (groupingType.length()>0) + { + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "[" + << this->Name << "]" + << " requested component grouping = "<< groupingType <<std::endl); + if (groupingType == "ALL_GROUP_IN_ONE") + { + allGroupInOne = true; + } + else if (groupingType == "ALL_COMPONENT_IN_ONE") + { + allComponentInOne = true; + } + else if (groupingType == "IGNORE") + { + ignoreComponentGroup = true; + } + else + { + cmCPackLogger(cmCPackLog::LOG_WARNING, "[" + << this->Name << "]" + << " requested component grouping type <"<< groupingType + << "> UNKNOWN not in (ALL_GROUP_IN_ONE,ALL_COMPONENT_IN_ONE,IGNORE)" <<std::endl); + } + } + + // Some components were defined but NO group + // force ignoreGroups + if (this->ComponentGroups.empty() && (!this->Components.empty()) && (!ignoreComponentGroup)) { + cmCPackLogger(cmCPackLog::LOG_WARNING, "[" + << this->Name << "]" + << " Some Components defined but NO component group:" + << " Ignoring component group." + << std::endl); + ignoreComponentGroup = true; + } // CASE 1 : COMPONENT ALL-IN-ONE package // If ALL GROUPS or ALL COMPONENTS in ONE package has been requested // then the package file is unique and should be open here. - if ((allComponentInOne || allGroupInOne) && (!this->ComponentGroups.empty())) + if (allComponentInOne || (allGroupInOne && (!this->ComponentGroups.empty()))) { return PackageComponentsAllInOne(allComponentInOne); } @@ -229,7 +273,7 @@ int cmCPackArchiveGenerator::PackageFiles() // There will be 1 package for each component group // however one may require to ignore component group and // in this case you'll get 1 package for each component. - else if (!this->ComponentGroups.empty()) + else if ((!this->ComponentGroups.empty()) || (ignoreComponentGroup)) { return PackageComponents(ignoreComponentGroup); } -- 1.7.1 | ||||||||
Relationships | ||||||||||||||||
|
Relationships |
Notes | |
(0020798) Bill Hoffman (manager) 2010-05-20 08:14 |
Is this what you are looking for: http://www.vtk.org/Wiki/CMake:Component_Install_With_CPack [^] |
(0020804) Eric NOULARD (developer) 2010-05-20 13:36 |
To Bill: Currently there is only two CPack generators that supports components: NSIS and PackageMaker. This is pending for a long time for RPM because: - lack of time (as usual) - because generic generator was not meant to support "several files" generation in the first place see there http://public.kitware.com/Bug/view.php?id=9900 [^] I'll add relationship with those related bugs / features requests |
(0021592) Eric NOULARD (developer) 2010-08-02 07:24 |
Hi All, Here comes a patch which provides the necessary changes to all CPack Generators for supporting the requested features. The patch contains changes to the Archive Generators which will produce a set of files for a componentized project. For example using the example from http://www.itk.org/Wiki/CMake:Component_Install_With_CPack [^] using the ZIP generator it produces: $ cpack -G ZIP CPack: Create package using ZIP CPack: Install projects CPack: - Run preinstall target for: MyLib CPack: - Install project: MyLib CPack: - Install component: applications CPack: - Install component: libraries CPack: - Install component: headers CPack: Compress package CPack: Finalize package CPack: Created package: MyLib-1.0.0-Linux-applications.zip CPack: Created package: MyLib-1.0.0-Linux-headers.zip CPack: Created package: MyLib-1.0.0-Linux-libraries.zip Waiting for feedback before going on... |
(0021601) Stefan Sablatnoeg (reporter) 2010-08-03 03:04 |
Hi all, first of all many thanks for providing a patch. I tried it on an small example yesterday and it worked as expected (I patched against cmake 2.8.2), a larger test will follow as soon as I find the time. One minor thing (maybe a different issue?), I am not quite sure of yet is how to handle the destination of the packages? Is there already way to produce (or copy) the packages to a user defined place (we usually put our final deliveries under revision control, so it would be ideal if the package would be in the "right" place automatically after each build.) |
(0021621) Eric NOULARD (developer) 2010-08-03 20:23 |
Updated patch set. 0001 and 0002 contains the change of API for compressFile 0003 contains the updated ArchiveGenerator(s) for handling the 1 component == 1 package case. A next patch should enable the 1 component group == 1 package case. Could someone test those patches (at least 0001 and 0002) on Windows and/or OS X, I won't be able to test on those platforms. Unless someone has more remarks concerning the change of API I think 0001 and 0002 may be applied now to next/master. |
(0021632) Eric NOULARD (developer) 2010-08-04 10:09 |
Adding 0004 patch to patchset. With 0004 the Archive Generators will produce 1 package file per component group unless there is no group or CPACK_COMPONENT_IGNORE_COMPONENT_GROUP=1 is specified. |
(0021637) Eric NOULARD (developer) 2010-08-04 12:28 |
Small note: The patch series are cumulative. One must apply 0001 before 0002 etc... Applying all those patches using git should be as simple as git apply 000?-CPack-enable-generators-to-produce-more-than-one-pac.patch |
(0021692) harmy (reporter) 2010-08-08 13:09 |
hi, Eric: thanks for your patches,can you post a sixth patch that makes CPackDebGenerator work? |
(0021696) Eric NOULARD (developer) 2010-08-08 14:08 |
Hi Harmy, I will certainly work on a multi-package for DEB and RPM but there are some overlapping change going on (related to bug http://public.kitware.com/Bug/view.php?id=11020 [^]) so I may have to stall this in order to avoid to "double" the work. So the short answer is: Yes I will but not now. You can monitor this bug and you will be kept informed. Thank you for your interest in this. |
(0021869) Eric NOULARD (developer) 2010-08-21 07:54 |
Here comes a new set of patches for Archive Generators (ZIP, TGZ, STGZ etc...) 0001-CPackArchiveGenerator-use-cmArchiveWrite-wrapper.patch 0002-CPackArchiveGenerator-add-component-supports.patch the previous work has been rebased on the redesigned CPack API. The patches may be applied starting from current master. you may pull the same content from my github branch: http://github.com/TheErk/CMake/tree/CPackArchiveGenerator-ComponentSupport [^] I think this can now go in upstream CMake and I will ask for this. A usual I'm not able to test on Windows or MacOS so testers are welcomed. I will send more "user" information on CMake ML. Basically the patch introduces 3 new variables: CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE CPACK_COMPONENTS_IGNORE_GROUPS which may set at CPack time in order to chose how many package files are generated and how the "grouping" takes place. The default behavior is to create 1 package for each component group. |
(0021933) Eric NOULARD (developer) 2010-08-24 16:37 |
latest patch proposal have been pushed to next |
(0022037) Eric NOULARD (developer) 2010-08-31 16:37 |
Merged to master: commit 65fa0f02351e1564d60b266594b425094dce1959 Merge: f95074b a986daf Author: Brad King <brad.king@kitware.com> Date: Tue Aug 31 14:24:32 2010 -0400 Merge topic 'CPackArchiveGenerator-ComponentSupport' a986daf CPack fix broken compilation for CygwinSource generator 873e99a CPackArchiveGenerator improve usability and robustness 654683a CPackArchiveGenerator add component supports 36a550a CPackArchiveGenerator use cmArchiveWrite wrapper |
Notes |
Issue History | |||
Date Modified | Username | Field | Change |
2010-05-20 07:10 | Stefan Sablatnoeg | New Issue | |
2010-05-20 08:14 | Bill Hoffman | Note Added: 0020798 | |
2010-05-20 13:36 | Eric NOULARD | Note Added: 0020804 | |
2010-05-20 13:36 | Eric NOULARD | Relationship added | related to 0009900 |
2010-05-20 13:36 | Eric NOULARD | Relationship added | parent of 0007645 |
2010-08-02 07:15 | Eric NOULARD | Status | new => assigned |
2010-08-02 07:15 | Eric NOULARD | Assigned To | => Eric NOULARD |
2010-08-02 07:21 | Eric NOULARD | File Added: 0001-CPack-enable-generators-to-produce-more-than-one-pac.patch | |
2010-08-02 07:24 | Eric NOULARD | Note Added: 0021592 | |
2010-08-02 19:03 | Eric NOULARD | Relationship added | related to 0010130 |
2010-08-03 03:04 | Stefan Sablatnoeg | Note Added: 0021601 | |
2010-08-03 20:18 | Eric NOULARD | File Deleted: 0001-CPack-enable-generators-to-produce-more-than-one-pac.patch | |
2010-08-03 20:18 | Eric NOULARD | File Added: 0001-CPack-enable-generators-to-produce-more-than-one-pac.patch | |
2010-08-03 20:18 | Eric NOULARD | File Added: 0002-CPack-enable-generators-to-produce-more-than-one-pac.patch | |
2010-08-03 20:18 | Eric NOULARD | File Added: 0003-CPack-enable-generators-to-produce-more-than-one-pac.patch | |
2010-08-03 20:23 | Eric NOULARD | Note Added: 0021621 | |
2010-08-04 10:08 | Eric NOULARD | File Added: 0004-CPack-enable-generators-to-produce-more-than-one-pac.patch | |
2010-08-04 10:09 | Eric NOULARD | Note Added: 0021632 | |
2010-08-04 12:28 | Eric NOULARD | Note Added: 0021637 | |
2010-08-05 18:30 | Eric NOULARD | File Added: 0005-CPack-enable-generators-to-produce-more-than-one-pac.patch | |
2010-08-08 13:09 | harmy | Note Added: 0021692 | |
2010-08-08 14:08 | Eric NOULARD | Note Added: 0021696 | |
2010-08-21 07:44 | Eric NOULARD | File Added: 0001-CPackArchiveGenerator-use-cmArchiveWrite-wrapper.patch | |
2010-08-21 07:44 | Eric NOULARD | File Added: 0002-CPackArchiveGenerator-add-component-supports.patch | |
2010-08-21 07:54 | Eric NOULARD | Note Added: 0021869 | |
2010-08-22 12:21 | Eric NOULARD | File Added: 0003-CPackArchiveGenerator-improve-usability-and-robustne.patch | |
2010-08-24 16:37 | Eric NOULARD | Note Added: 0021933 | |
2010-08-31 16:37 | Eric NOULARD | Note Added: 0022037 | |
2010-08-31 16:37 | Eric NOULARD | Status | assigned => closed |
2010-08-31 16:37 | Eric NOULARD | Resolution | open => fixed |
2010-08-31 16:37 | Eric NOULARD | Fixed in Version | => CMake-2-8 |
2010-08-31 18:03 | David Cole | Target Version | => CMake 2.8.3 |
2010-10-06 14:40 | David Cole | Fixed in Version | CMake-2-8 => CMake 2.8.3 |
Issue History |
Copyright © 2000 - 2018 MantisBT Team |