CPackRPM add basic component support to CPackRPM

basic means 1 RPM per component and no dependency handling
this implies some CPackGenerator refactoring
This commit is contained in:
Eric NOULARD 2010-11-13 17:56:36 +01:00
parent d95017deec
commit 2c84d169b3
7 changed files with 194 additions and 81 deletions

View File

@ -331,7 +331,7 @@ ELSE(CPACK_RPM_COMPRESSION_TYPE)
ENDIF(CPACK_RPM_COMPRESSION_TYPE)
if(CPACK_PACKAGE_RELOCATABLE)
set(CPACK_RPM_PACKAGE_RELOCATABLE TRUE)
set(CPACK_RPM_PACKAGE_RELOCATABLE TRUE)
endif(CPACK_PACKAGE_RELOCATABLE)
if(CPACK_RPM_PACKAGE_RELOCATABLE)
if(CPACK_RPM_PACKAGE_DEBUG)
@ -453,6 +453,17 @@ SET(CPACK_RPM_FILE_NAME "${CPACK_OUTPUT_FILE_NAME}")
#STRING(REGEX REPLACE " " "\\\\ " CPACK_RPM_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}")
SET(CPACK_RPM_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}")
# Are we packaging components ?
IF(CPACK_RPM_PACKAGE_COMPONENT)
SET(CPACK_RPM_PACKAGE_COMPONENT_PART_NAME "-${CPACK_RPM_PACKAGE_COMPONENT}")
SET(CPACK_RPM_PACKAGE_COMPONENT_PART_PATH "/${CPACK_RPM_PACKAGE_COMPONENT}")
SET(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/${CPACK_RPM_PACKAGE_COMPONENT}")
ELSE(CPACK_RPM_PACKAGE_COMPONENT)
SET(CPACK_RPM_PACKAGE_COMPONENT_PART_NAME "")
SET(CPACK_RPM_PACKAGE_COMPONENT_PART_PATH "")
SET(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}")
ENDIF(CPACK_RPM_PACKAGE_COMPONENT)
# Use files tree to construct files command (spec file)
# We should not forget to include symlinks (thus -o -type l)
# We must remove the './' due to the local search and escape the
@ -460,10 +471,10 @@ SET(CPACK_RPM_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}")
# Then we must authorize any man pages extension (adding * at the end)
# because rpmbuild may automatically compress those files
EXECUTE_PROCESS(COMMAND find -type f -o -type l
COMMAND sed {s:.*/man.*/.*:&*:}
COMMAND sed {s/\\.\\\(.*\\\)/\"\\1\"/}
WORKING_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}"
OUTPUT_VARIABLE CPACK_RPM_INSTALL_FILES)
COMMAND sed {s:.*/man.*/.*:&*:}
COMMAND sed {s/\\.\\\(.*\\\)/\"\\1\"/}
WORKING_DIRECTORY "${WDIR}"
OUTPUT_VARIABLE CPACK_RPM_INSTALL_FILES)
if (CPACK_ABSOLUTE_DESTINATION_FILES)
IF(CPACK_RPM_PACKAGE_DEBUG)
@ -494,7 +505,7 @@ if (CPACK_ABSOLUTE_DESTINATION_FILES)
endif(CPACK_ABSOLUTE_DESTINATION_FILES)
# The name of the final spec file to be used by rpmbuild
SET(CPACK_RPM_BINARY_SPECFILE "${CPACK_RPM_ROOTDIR}/SPECS/${CPACK_RPM_PACKAGE_NAME}.spec")
SET(CPACK_RPM_BINARY_SPECFILE "${CPACK_RPM_ROOTDIR}/SPECS/${CPACK_RPM_PACKAGE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.spec")
# Print out some debug information if we were asked for that
IF(CPACK_RPM_PACKAGE_DEBUG)
@ -517,7 +528,7 @@ ENDIF(CPACK_RPM_PACKAGE_DEBUG)
IF(CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE OR NOT CPACK_RPM_USER_BINARY_SPECFILE)
FILE(WRITE ${CPACK_RPM_BINARY_SPECFILE}.in
"# -*- rpm-spec -*-
BuildRoot: \@CPACK_RPM_DIRECTORY\@/\@CPACK_PACKAGE_FILE_NAME\@
BuildRoot: \@CPACK_RPM_DIRECTORY\@/\@CPACK_PACKAGE_FILE_NAME\@\@CPACK_RPM_PACKAGE_COMPONENT_PART_PATH\@
Summary: \@CPACK_RPM_PACKAGE_SUMMARY\@
Name: \@CPACK_RPM_PACKAGE_NAME\@
Version: \@CPACK_RPM_PACKAGE_VERSION\@
@ -608,15 +619,15 @@ IF(RPMBUILD_EXECUTABLE)
# Now call rpmbuild using the SPECFILE
EXECUTE_PROCESS(
COMMAND "${RPMBUILD_EXECUTABLE}" -bb
--buildroot "${CPACK_RPM_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}"
--buildroot "${CPACK_RPM_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}"
"${CPACK_RPM_BINARY_SPECFILE}"
WORKING_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}"
ERROR_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild.err"
OUTPUT_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild.out")
WORKING_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}"
ERROR_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.err"
OUTPUT_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.out")
IF(CPACK_RPM_PACKAGE_DEBUG)
MESSAGE("CPackRPM:Debug: You may consult rpmbuild logs in: ")
MESSAGE("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild.err")
MESSAGE("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild.out")
MESSAGE("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.err")
MESSAGE("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.out")
ENDIF(CPACK_RPM_PACKAGE_DEBUG)
ELSE(RPMBUILD_EXECUTABLE)
IF(ALIEN_EXECUTABLE)

View File

@ -105,12 +105,12 @@ if (!archive) \
}
//----------------------------------------------------------------------
int cmCPackArchiveGenerator::PackageComponents(bool ignoreComponentGroup)
int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup)
{
packageFileNames.clear();
// The default behavior is to have one package by component group
// unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
if (!ignoreComponentGroup)
if (!ignoreGroup)
{
std::map<std::string, cmCPackComponentGroup>::iterator compGIt;
for (compGIt=this->ComponentGroups.begin();
@ -170,7 +170,7 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreComponentGroup)
}
//----------------------------------------------------------------------
int cmCPackArchiveGenerator::PackageComponentsAllInOne(bool allComponentInOne)
int cmCPackArchiveGenerator::PackageComponentsAllInOne(bool allComponent)
{
// reset the package file names
packageFileNames.clear();
@ -185,7 +185,7 @@ int cmCPackArchiveGenerator::PackageComponentsAllInOne(bool allComponentInOne)
DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0],archive);
// The ALL GROUP in ONE package case
if (! allComponentInOne) {
if (! allComponent) {
// iterate over the component groups
std::map<std::string, cmCPackComponentGroup>::iterator compGIt;
for (compGIt=this->ComponentGroups.begin();
@ -226,63 +226,8 @@ int cmCPackArchiveGenerator::PackageFiles()
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: "
<< toplevel << std::endl);
// 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")));
PrepareGroupingKind();
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.

View File

@ -60,12 +60,12 @@ protected:
* install is used. This will create one
* archive for each component group.
*/
int PackageComponents(bool ignoreComponentGroup);
int PackageComponents(bool ignoreGroup);
/**
* Special case of component install where all
* components will be put in a single installer.
*/
int PackageComponentsAllInOne(bool allComponentInOne);
int PackageComponentsAllInOne(bool allComponent);
virtual const char* GetOutputExtension() = 0;
cmArchiveWrite::Compress Compress;
cmArchiveWrite::Type Archive;

View File

@ -35,6 +35,9 @@ cmCPackGenerator::cmCPackGenerator()
this->GeneratorVerbose = false;
this->MakefileMap = 0;
this->Logger = 0;
this->allGroupInOne = false;
this->allComponentInOne = false;
this->ignoreComponentGroup = false;
}
//----------------------------------------------------------------------
@ -220,7 +223,7 @@ int cmCPackGenerator::InstallProject()
// If the CPackConfig file sets CPACK_INSTALLED_DIRECTORIES
// then glob it and copy it to CPACK_TEMPORARY_DIRECTORY
// This is used in Source packageing
// This is used in Source packaging
if ( !this->InstallProjectViaInstalledDirectories(
setDestDir, tempInstallDirectory) )
{
@ -691,7 +694,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
//
// If DESTDIR has been 'internally set ON' this means that
// the underlying CPack specific generator did ask for that
// In this case we may overrode CPACK_INSTALL_PREFIX with
// 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.
@ -727,7 +730,18 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
{
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).c_str());
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"- Creating directory: '" << dir << "'" << std::endl);
@ -1195,6 +1209,70 @@ int cmCPackGenerator::CleanTemporaryDirectory()
return 1;
}
//----------------------------------------------------------------------
int cmCPackGenerator::PrepareGroupingKind()
{
// The default behavior is to create 1 package by component group
// unless the user asked to put all COMPONENTS in a single package
allGroupInOne = (NULL !=
(this->GetOption(
"CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE")));
allComponentInOne = (NULL !=
(this->GetOption(
"CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE")));
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;
}
return 1;
}
//----------------------------------------------------------------------
bool cmCPackGenerator::SupportsComponentInstallation() const
{

View File

@ -119,6 +119,17 @@ protected:
virtual const char* GetOutputExtension() { return ".cpack"; }
virtual const char* GetOutputPostfix() { return 0; }
/**
* Prepare requested grouping kind from CPACK_xxx vars
* CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE
* CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE
* CPACK_COMPONENTS_IGNORE_GROUPS
* or
* CPACK_COMPONENTS_GROUPING
* @return 1 on success 0 on failure.
*/
virtual int PrepareGroupingKind();
/**
* Package the list of files and/or components which
* has been prepared by the beginning of DoPackage.
@ -200,6 +211,20 @@ protected:
*/
std::map<std::string, cmCPackComponent> Components;
std::map<std::string, cmCPackComponentGroup> ComponentGroups;
/**
* If true All component groups will be put in a single package.
*/
bool allGroupInOne;
/**
* If true All component will be put in a single package.
*/
bool allComponentInOne;
/**
* If true component grouping will be ignored.
* You will still get 1 package for each component unless
* allComponentInOne is true.
*/
bool ignoreComponentGroup;
cmCPackLog* Logger;
private:

View File

@ -37,13 +37,66 @@ int cmCPackRPMGenerator::InitializeInternal()
//----------------------------------------------------------------------
int cmCPackRPMGenerator::PackageFiles()
{
this->ReadListFile("CPackRPM.cmake");
int retval = 1;
/* Digest Component grouping specification */
retval = PrepareGroupingKind();
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: "
<< toplevel << std::endl);
/* Are we in the component packaging case */
if (!this->ComponentGroups.empty())
{
/* Reset package file name list it will be populated during the
* component packaging run*/
packageFileNames.clear();
std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
/* One Package per component CASE */
/* Iterate over components */
std::map<std::string, cmCPackComponent>::iterator compIt;
for (compIt=this->Components.begin();
compIt!=this->Components.end(); ++compIt )
{
std::string localToplevel(initialTopLevel);
std::string packageFileName(cmSystemTools::GetParentDirectory(toplevel.c_str()));
std::string outputFileName(std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))
+"-"+compIt->first + this->GetOutputExtension());
localToplevel += "/"+ compIt->first;
/* replace the TEMP DIRECTORY with the component one */
this->SetOption("CPACK_TEMPORARY_DIRECTORY",localToplevel.c_str());
packageFileName += "/"+ outputFileName;
/* replace proposed CPACK_OUTPUT_FILE_NAME */
this->SetOption("CPACK_OUTPUT_FILE_NAME",outputFileName.c_str());
/* replace the TEMPORARY package file name */
this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME",packageFileName.c_str());
this->SetOption("CPACK_RPM_PACKAGE_COMPONENT",compIt->first.c_str());
if (!this->ReadListFile("CPackRPM.cmake"))
{
cmCPackLogger(cmCPackLog::LOG_ERROR, "Error while execution CPackRPM.cmake" << std::endl);
retval = 0;
}
// add the generated package to package file names list
packageFileNames.push_back(packageFileName);
}
}
/* This is the non component case */
else
{
if (!this->ReadListFile("CPackRPM.cmake"))
{
cmCPackLogger(cmCPackLog::LOG_ERROR, "Error while execution CPackRPM.cmake" << std::endl);
retval = 0;
}
}
if (!this->IsSet("RPMBUILD_EXECUTABLE"))
{
cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find rpmbuild" << std::endl);
return 0;
retval = 0;
}
return 1;
return retval;
}

View File

@ -39,6 +39,7 @@ protected:
virtual int InitializeInternal();
virtual int PackageFiles();
virtual const char* GetOutputExtension() { return ".rpm"; }
virtual bool SupportsComponentInstallation() const {return true;}
};