CPackDeb: use of libarchive and removal of fakeroot

This commit is contained in:
Raffi Enficiaud 2015-09-11 20:58:18 +02:00 committed by Brad King
parent 415405a308
commit 7044e8ee4b
4 changed files with 243 additions and 122 deletions

View File

@ -0,0 +1,4 @@
cpack-deb-fakeroot-removal
--------------------------
* :module:`CPackDeb` no longer uses fakeroot and system tar program for packaging.

View File

@ -326,6 +326,34 @@
# #
# set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA # set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
# "${CMAKE_CURRENT_SOURCE_DIR/prerm;${CMAKE_CURRENT_SOURCE_DIR}/postrm") # "${CMAKE_CURRENT_SOURCE_DIR/prerm;${CMAKE_CURRENT_SOURCE_DIR}/postrm")
#
# .. note::
#
# The original permissions of the files will be used in the final
# package unless the variable
# :variable:`CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION` is set.
# In particular, the scripts should have the proper executable
# flag prior to the generation of the package.
#
# .. variable:: CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION
# CPACK_DEBIAN_<COMPONENT>_PACKAGE_CONTROL_STRICT_PERMISSION
#
# This variable indicates if the Debian policy on control files should be
# strictly followed.
#
# * Mandatory : NO
# * Default : FALSE
#
# Usage::
#
# set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE)
#
# .. note::
#
# This overrides the permissions on the original files, following the rules
# set by Debian policy
# https://www.debian.org/doc/debian-policy/ch-files.html#s-permissions-owners
#
#============================================================================= #=============================================================================
@ -362,11 +390,6 @@ function(cpack_deb_prepare_package_vars)
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF) set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF)
endif() endif()
find_program(FAKEROOT_EXECUTABLE fakeroot)
if(FAKEROOT_EXECUTABLE)
set(CPACK_DEBIAN_FAKEROOT_EXECUTABLE ${FAKEROOT_EXECUTABLE})
endif()
set(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_DEB_PACKAGE_COMPONENT_PART_PATH}") set(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_DEB_PACKAGE_COMPONENT_PART_PATH}")
# per component automatic discover: some of the component might not have # per component automatic discover: some of the component might not have
@ -635,7 +658,7 @@ function(cpack_deb_prepare_package_vars)
# Are we packaging components ? # Are we packaging components ?
if(CPACK_DEB_PACKAGE_COMPONENT) if(CPACK_DEB_PACKAGE_COMPONENT)
# override values with per component version if set # override values with per component version if set
foreach(VAR_NAME_ "PACKAGE_CONTROL_EXTRA") foreach(VAR_NAME_ "PACKAGE_CONTROL_EXTRA" "PACKAGE_CONTROL_STRICT_PERMISSION")
if(CPACK_DEBIAN_${_local_component_name}_${VAR_NAME_}) if(CPACK_DEBIAN_${_local_component_name}_${VAR_NAME_})
set(CPACK_DEBIAN_${VAR_NAME_} "${CPACK_DEBIAN_${_local_component_name}_${VAR_NAME_}}") set(CPACK_DEBIAN_${VAR_NAME_} "${CPACK_DEBIAN_${_local_component_name}_${VAR_NAME_}}")
endif() endif()
@ -657,6 +680,7 @@ function(cpack_deb_prepare_package_vars)
message("CPackDeb:Debug: CPACK_PACKAGE_FILE_NAME = ${CPACK_PACKAGE_FILE_NAME}") message("CPackDeb:Debug: CPACK_PACKAGE_FILE_NAME = ${CPACK_PACKAGE_FILE_NAME}")
message("CPackDeb:Debug: CPACK_PACKAGE_INSTALL_DIRECTORY = ${CPACK_PACKAGE_INSTALL_DIRECTORY}") message("CPackDeb:Debug: CPACK_PACKAGE_INSTALL_DIRECTORY = ${CPACK_PACKAGE_INSTALL_DIRECTORY}")
message("CPackDeb:Debug: CPACK_TEMPORARY_PACKAGE_FILE_NAME = ${CPACK_TEMPORARY_PACKAGE_FILE_NAME}") message("CPackDeb:Debug: CPACK_TEMPORARY_PACKAGE_FILE_NAME = ${CPACK_TEMPORARY_PACKAGE_FILE_NAME}")
message("CPackDeb:Debug: CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION = ${CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION}")
endif() endif()
# For debian source packages: # For debian source packages:
@ -682,7 +706,6 @@ function(cpack_deb_prepare_package_vars)
set(GEN_CPACK_DEBIAN_PACKAGE_MAINTAINER "${CPACK_DEBIAN_PACKAGE_MAINTAINER}" PARENT_SCOPE) set(GEN_CPACK_DEBIAN_PACKAGE_MAINTAINER "${CPACK_DEBIAN_PACKAGE_MAINTAINER}" PARENT_SCOPE)
set(GEN_CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_DEBIAN_PACKAGE_DESCRIPTION}" PARENT_SCOPE) set(GEN_CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_DEBIAN_PACKAGE_DESCRIPTION}" PARENT_SCOPE)
set(GEN_CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS}" PARENT_SCOPE) set(GEN_CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS}" PARENT_SCOPE)
set(GEN_CPACK_DEBIAN_FAKEROOT_EXECUTABLE "${CPACK_DEBIAN_FAKEROOT_EXECUTABLE}" PARENT_SCOPE)
set(GEN_CPACK_DEBIAN_COMPRESSION_TYPE "${CPACK_DEBIAN_COMPRESSION_TYPE}" PARENT_SCOPE) set(GEN_CPACK_DEBIAN_COMPRESSION_TYPE "${CPACK_DEBIAN_COMPRESSION_TYPE}" PARENT_SCOPE)
set(GEN_CPACK_DEBIAN_PACKAGE_RECOMMENDS "${CPACK_DEBIAN_PACKAGE_RECOMMENDS}" PARENT_SCOPE) set(GEN_CPACK_DEBIAN_PACKAGE_RECOMMENDS "${CPACK_DEBIAN_PACKAGE_RECOMMENDS}" PARENT_SCOPE)
set(GEN_CPACK_DEBIAN_PACKAGE_SUGGESTS "${CPACK_DEBIAN_PACKAGE_SUGGESTS}" PARENT_SCOPE) set(GEN_CPACK_DEBIAN_PACKAGE_SUGGESTS "${CPACK_DEBIAN_PACKAGE_SUGGESTS}" PARENT_SCOPE)
@ -694,6 +717,8 @@ function(cpack_deb_prepare_package_vars)
set(GEN_CPACK_DEBIAN_PACKAGE_PROVIDES "${CPACK_DEBIAN_PACKAGE_PROVIDES}" PARENT_SCOPE) set(GEN_CPACK_DEBIAN_PACKAGE_PROVIDES "${CPACK_DEBIAN_PACKAGE_PROVIDES}" PARENT_SCOPE)
set(GEN_CPACK_DEBIAN_PACKAGE_REPLACES "${CPACK_DEBIAN_PACKAGE_REPLACES}" PARENT_SCOPE) set(GEN_CPACK_DEBIAN_PACKAGE_REPLACES "${CPACK_DEBIAN_PACKAGE_REPLACES}" PARENT_SCOPE)
set(GEN_CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA}" PARENT_SCOPE) set(GEN_CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA}" PARENT_SCOPE)
set(GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION
"${CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION}" PARENT_SCOPE)
set(GEN_WDIR "${WDIR}" PARENT_SCOPE) set(GEN_WDIR "${WDIR}" PARENT_SCOPE)
endfunction() endfunction()

View File

@ -15,6 +15,7 @@
#include "cmMakefile.h" #include "cmMakefile.h"
#include "cmGeneratedFileStream.h" #include "cmGeneratedFileStream.h"
#include "cmCPackLog.h" #include "cmCPackLog.h"
#include "cmArchiveWrite.h"
#include <cmsys/SystemTools.hxx> #include <cmsys/SystemTools.hxx>
#include <cmsys/Glob.hxx> #include <cmsys/Glob.hxx>
@ -388,9 +389,9 @@ int cmCPackDebGenerator::createDeb()
{ {
std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY"); std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
dirName += '/'; dirName += '/';
for (std::vector<std::string>::const_iterator fileIt = for (std::vector<std::string>::const_iterator fileIt =
packageFiles.begin(); packageFiles.begin();
fileIt != packageFiles.end(); ++ fileIt ) fileIt != packageFiles.end(); ++ fileIt )
{ {
totalSize += cmSystemTools::FileLength(*fileIt); totalSize += cmSystemTools::FileLength(*fileIt);
} }
@ -401,8 +402,9 @@ int cmCPackDebGenerator::createDeb()
out << std::endl; out << std::endl;
} }
std::string cmd(this->GetOption("GEN_CPACK_DEBIAN_FAKEROOT_EXECUTABLE")); const std::string strGenWDIR(this->GetOption("GEN_WDIR"));
cmArchiveWrite::Compress tar_compression_type = cmArchiveWrite::CompressGZip;
const char* debian_compression_type = const char* debian_compression_type =
this->GetOption("GEN_CPACK_DEBIAN_COMPRESSION_TYPE"); this->GetOption("GEN_CPACK_DEBIAN_COMPRESSION_TYPE");
if(!debian_compression_type) if(!debian_compression_type)
@ -410,102 +412,127 @@ int cmCPackDebGenerator::createDeb()
debian_compression_type = "gzip"; debian_compression_type = "gzip";
} }
std::string cmake_tar = " ", compression_modifier = "a", compression_suffix; std::string compression_suffix;
if(!strcmp(debian_compression_type, "lzma")) { if(!strcmp(debian_compression_type, "lzma")) {
compression_suffix = ".lzma"; compression_suffix = ".lzma";
tar_compression_type = cmArchiveWrite::CompressLZMA;
} else if(!strcmp(debian_compression_type, "xz")) { } else if(!strcmp(debian_compression_type, "xz")) {
compression_suffix = ".xz"; compression_suffix = ".xz";
tar_compression_type = cmArchiveWrite::CompressXZ;
} else if(!strcmp(debian_compression_type, "bzip2")) { } else if(!strcmp(debian_compression_type, "bzip2")) {
compression_suffix = ".bz2"; compression_suffix = ".bz2";
compression_modifier = "j"; tar_compression_type = cmArchiveWrite::CompressBZip2;
cmake_tar += "\"" + cmSystemTools::GetCMakeCommand() + "\" -E ";
} else if(!strcmp(debian_compression_type, "gzip")) { } else if(!strcmp(debian_compression_type, "gzip")) {
compression_suffix = ".gz"; compression_suffix = ".gz";
compression_modifier = "z"; tar_compression_type = cmArchiveWrite::CompressGZip;
cmake_tar += "\"" + cmSystemTools::GetCMakeCommand() + "\" -E ";
} else if(!strcmp(debian_compression_type, "none")) { } else if(!strcmp(debian_compression_type, "none")) {
compression_suffix = ""; compression_suffix = "";
compression_modifier = ""; tar_compression_type = cmArchiveWrite::CompressNone;
cmake_tar += "\"" + cmSystemTools::GetCMakeCommand() + "\" -E ";
} else { } else {
cmCPackLogger(cmCPackLog::LOG_ERROR, cmCPackLogger(cmCPackLog::LOG_ERROR,
"Error unrecognized compression type: " "Error unrecognized compression type: "
<< debian_compression_type << std::endl); << debian_compression_type << std::endl);
} }
cmd += cmake_tar + "tar c" + compression_modifier + "f data.tar"
+ compression_suffix;
// now add all directories which have to be compressed std::string filename_data_tar = strGenWDIR
// collect all top level install dirs for that + "/data.tar" + compression_suffix;
// e.g. /opt/bin/foo, /usr/bin/bar and /usr/bin/baz would give /usr and /opt
size_t topLevelLength = std::string(this->GetOption("GEN_WDIR")).length(); // atomic file generation for data.tar
cmCPackLogger(cmCPackLog::LOG_DEBUG, "WDIR: \"" {
<< this->GetOption("GEN_WDIR") cmGeneratedFileStream fileStream_data_tar;
<< "\", length = " << topLevelLength fileStream_data_tar.Open(filename_data_tar.c_str(), false, true);
<< std::endl); if(!fileStream_data_tar)
std::set<std::string> installDirs;
for (std::vector<std::string>::const_iterator fileIt =
packageFiles.begin();
fileIt != packageFiles.end(); ++ fileIt )
{
cmCPackLogger(cmCPackLog::LOG_DEBUG, "FILEIT: \"" << *fileIt << "\""
<< std::endl);
std::string::size_type slashPos = fileIt->find('/', topLevelLength+1);
std::string relativeDir = fileIt->substr(topLevelLength,
slashPos - topLevelLength);
cmCPackLogger(cmCPackLog::LOG_DEBUG, "RELATIVEDIR: \"" << relativeDir
<< "\"" << std::endl);
if (installDirs.find(relativeDir) == installDirs.end())
{ {
installDirs.insert(relativeDir); cmCPackLogger(cmCPackLog::LOG_ERROR,
cmd += " ."; "Error opening the file \"" << filename_data_tar << "\" for writing"
cmd += relativeDir; << std::endl);
return 0;
} }
} cmArchiveWrite data_tar(fileStream_data_tar, tar_compression_type, "paxr");
std::string output; // uid/gid should be the one of the root user, and this root user has
int retval = -1; // always uid/gid equal to 0.
int res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &output, data_tar.SetUIDAndGID(0u, 0u);
&retval, this->GetOption("GEN_WDIR"), this->GeneratorVerbose, 0); data_tar.SetUNAMEAndGNAME("root", "root");
if ( !res || retval ) // now add all directories which have to be compressed
{ // collect all top level install dirs for that
std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); // e.g. /opt/bin/foo, /usr/bin/bar and /usr/bin/baz would
tmpFile += "/Deb.log"; // give /usr and /opt
cmGeneratedFileStream ofs(tmpFile.c_str()); size_t topLevelLength = strGenWDIR.length();
ofs << "# Run command: " << cmd << std::endl cmCPackLogger(cmCPackLog::LOG_DEBUG, "WDIR: \""
<< "# Working directory: " << toplevel << std::endl << strGenWDIR
<< "# Output:" << std::endl << "\", length = " << topLevelLength
<< output << std::endl; << std::endl);
cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running tar command: " std::set<std::string> orderedFiles;
<< cmd << std::endl
<< "Please check " << tmpFile << " for errors" << std::endl);
return 0;
}
std::string md5filename; // we have to reconstruct the parent folders as well
md5filename = this->GetOption("GEN_WDIR");
md5filename += "/md5sums";
{ // the scope is needed for cmGeneratedFileStream for (std::vector<std::string>::const_iterator fileIt =
packageFiles.begin();
fileIt != packageFiles.end(); ++ fileIt )
{
std::string currentPath = *fileIt;
while(currentPath != strGenWDIR)
{
// the last one IS strGenWDIR, but we do not want this one:
// XXX/application/usr/bin/myprogram with GEN_WDIR=XXX/application
// should not add XXX/application
orderedFiles.insert(currentPath);
currentPath = cmSystemTools::CollapseCombinedPath(currentPath, "..");
}
}
for (std::set<std::string>::const_iterator fileIt =
orderedFiles.begin();
fileIt != orderedFiles.end(); ++ fileIt )
{
cmCPackLogger(cmCPackLog::LOG_DEBUG, "FILEIT: \"" << *fileIt << "\""
<< std::endl);
std::string::size_type slashPos = fileIt->find('/', topLevelLength+1);
std::string relativeDir = fileIt->substr(topLevelLength,
slashPos - topLevelLength);
cmCPackLogger(cmCPackLog::LOG_DEBUG, "RELATIVEDIR: \"" << relativeDir
<< "\"" << std::endl);
// do not recurse because the loop will do it
if(!data_tar.Add(*fileIt, topLevelLength, ".", false))
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Problem adding file to tar:" << std::endl
<< "#top level directory: "
<< strGenWDIR << std::endl
<< "#file: " << *fileIt << std::endl
<< "#error:" << data_tar.GetError() << std::endl);
return 0;
}
}
} // scope for file generation
std::string md5filename = strGenWDIR + "/md5sums";
{
// the scope is needed for cmGeneratedFileStream
cmGeneratedFileStream out(md5filename.c_str()); cmGeneratedFileStream out(md5filename.c_str());
std::vector<std::string>::const_iterator fileIt;
// std::string topLevelWithTrailingSlash = toplevel;
std::string topLevelWithTrailingSlash = std::string topLevelWithTrailingSlash =
this->GetOption("CPACK_TEMPORARY_DIRECTORY"); this->GetOption("CPACK_TEMPORARY_DIRECTORY");
topLevelWithTrailingSlash += '/'; topLevelWithTrailingSlash += '/';
for ( fileIt = packageFiles.begin(); for (std::vector<std::string>::const_iterator fileIt =
fileIt != packageFiles.end(); ++ fileIt ) packageFiles.begin();
fileIt != packageFiles.end(); ++ fileIt )
{ {
cmd = "\""; std::string cmd = "\"";
cmd += cmSystemTools::GetCMakeCommand(); cmd += cmSystemTools::GetCMakeCommand();
cmd += "\" -E md5sum \""; cmd += "\" -E md5sum \"";
cmd += *fileIt; cmd += *fileIt;
cmd += "\""; cmd += "\"";
//std::string output;
//int retVal = -1; std::string output;
res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &output, int retval = -1;
int res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &output,
&retval, toplevel.c_str(), this->GeneratorVerbose, 0); &retval, toplevel.c_str(), this->GeneratorVerbose, 0);
if ( !res || retval ) if ( !res || retval )
{ {
@ -521,70 +548,116 @@ int cmCPackDebGenerator::createDeb()
} }
// each line contains a eol. // each line contains a eol.
// Do not end the md5sum file with yet another (invalid) // Do not end the md5sum file with yet another (invalid)
} }
// set md5sum file permissins to RW-R--R-- so that deb lintian doesn't warn
// about it
cmSystemTools::SetPermissions(md5filename.c_str(),
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
cmd = this->GetOption("GEN_CPACK_DEBIAN_FAKEROOT_EXECUTABLE");
cmd += cmake_tar + "tar czf control.tar.gz ./control ./md5sums"; std::string filename_control_tar = strGenWDIR + "/control.tar.gz";
// atomic file generation for control.tar
{
cmGeneratedFileStream fileStream_control_tar;
fileStream_control_tar.Open(filename_control_tar.c_str(), false, true);
if(!fileStream_control_tar)
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Error opening the file \"" << filename_control_tar
<< "\" for writing" << std::endl);
return 0;
}
cmArchiveWrite control_tar(fileStream_control_tar,
tar_compression_type,
"paxr");
// sets permissions and uid/gid for the files
control_tar.SetUIDAndGID(0u, 0u);
control_tar.SetUNAMEAndGNAME("root", "root");
/* permissions are set according to
https://www.debian.org/doc/debian-policy/ch-files.html#s-permissions-owners
and
https://lintian.debian.org/tags/control-file-has-bad-permissions.html
*/
const mode_t permission644 = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
const mode_t permissionExecute = S_IXUSR | S_IXGRP | S_IXOTH;
const mode_t permission755 = permission644 | permissionExecute;
// for md5sum and control (that we have generated here), we use 644
// (RW-R--R--)
// so that deb lintian doesn't warn about it
control_tar.SetPermissions(permission644);
// adds control and md5sums
if( !control_tar.Add(md5filename, strGenWDIR.length(), ".")
|| !control_tar.Add(strGenWDIR + "/control", strGenWDIR.length(), "."))
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Error adding file to tar:" << std::endl
<< "#top level directory: "
<< strGenWDIR << std::endl
<< "#file: \"control\" or \"md5sums\"" << std::endl
<< "#error:" << control_tar.GetError() << std::endl);
return 0;
}
// for the other files, we use
// -either the original permission on the files
// -either a permission strictly defined by the Debian policies
const char* controlExtra = const char* controlExtra =
this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA"); this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA");
if( controlExtra ) if( controlExtra )
{
std::vector<std::string> controlExtraList;
cmSystemTools::ExpandListArgument(controlExtra, controlExtraList);
for(std::vector<std::string>::iterator i =
controlExtraList.begin(); i != controlExtraList.end(); ++i)
{ {
std::string filenamename = // permissions are now controlled by the original file permissions
cmsys::SystemTools::GetFilenameName(*i);
std::string localcopy = this->GetOption("GEN_WDIR"); const bool permissionStrictPolicy =
localcopy += "/"; this->IsSet("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION");
localcopy += filenamename;
// if we can copy the file, it means it does exist, let's add it: static const char* strictFiles[] = {
if( cmsys::SystemTools::CopyFileIfDifferent( "config", "postinst", "postrm", "preinst", "prerm"
*i, localcopy) ) };
std::set<std::string> setStrictFiles(
strictFiles,
strictFiles + sizeof(strictFiles)/sizeof(strictFiles[0]));
// default
control_tar.ClearPermissions();
std::vector<std::string> controlExtraList;
cmSystemTools::ExpandListArgument(controlExtra, controlExtraList);
for(std::vector<std::string>::iterator i = controlExtraList.begin();
i != controlExtraList.end(); ++i)
{ {
// debian is picky and need relative to ./ path in the tar.* std::string filenamename =
cmd += " ./"; cmsys::SystemTools::GetFilenameName(*i);
cmd += filenamename; std::string localcopy = strGenWDIR + "/" + filenamename;
if(permissionStrictPolicy)
{
control_tar.SetPermissions(setStrictFiles.count(filenamename) ?
permission755 : permission644);
}
// if we can copy the file, it means it does exist, let's add it:
if( cmsys::SystemTools::CopyFileIfDifferent(*i, localcopy) )
{
control_tar.Add(localcopy, strGenWDIR.length(), ".");
}
} }
} }
} }
res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &output,
&retval, this->GetOption("GEN_WDIR"), this->GeneratorVerbose, 0);
if ( !res || retval )
{
std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
tmpFile += "/Deb.log";
cmGeneratedFileStream ofs(tmpFile.c_str());
ofs << "# Run command: " << cmd << std::endl
<< "# Working directory: " << toplevel << std::endl
<< "# Output:" << std::endl
<< output << std::endl;
cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running tar command: "
<< cmd << std::endl
<< "Please check " << tmpFile << " for errors" << std::endl);
return 0;
}
// ar -r your-package-name.deb debian-binary control.tar.* data.tar.* // ar -r your-package-name.deb debian-binary control.tar.* data.tar.*
// since debian packages require BSD ar (most Linux distros and even // since debian packages require BSD ar (most Linux distros and even
// FreeBSD and NetBSD ship GNU ar) we use a copy of OpenBSD ar here. // FreeBSD and NetBSD ship GNU ar) we use a copy of OpenBSD ar here.
std::vector<std::string> arFiles; std::vector<std::string> arFiles;
std::string topLevelString = this->GetOption("GEN_WDIR"); std::string topLevelString = strGenWDIR + "/";
topLevelString += "/";
arFiles.push_back(topLevelString + "debian-binary"); arFiles.push_back(topLevelString + "debian-binary");
arFiles.push_back(topLevelString + "control.tar.gz"); arFiles.push_back(topLevelString + "control.tar.gz");
arFiles.push_back(topLevelString + "data.tar" + compression_suffix); arFiles.push_back(topLevelString + "data.tar" + compression_suffix);
std::string outputFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); std::string outputFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
outputFileName += "/"; outputFileName += "/";
outputFileName += this->GetOption("CPACK_OUTPUT_FILE_NAME"); outputFileName += this->GetOption("CPACK_OUTPUT_FILE_NAME");
res = ar_append(outputFileName.c_str(), arFiles); int res = ar_append(outputFileName.c_str(), arFiles);
if ( res!=0 ) if ( res!=0 )
{ {
std::string tmpFile = this->GetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME"); std::string tmpFile = this->GetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME");

View File

@ -80,6 +80,25 @@ set(CPACK_COMPONENT_HEADERS_DESCRIPTION
# depend on the libraries component. # depend on the libraries component.
set(CPACK_COMPONENT_HEADERS_DEPENDS libraries) set(CPACK_COMPONENT_HEADERS_DEPENDS libraries)
# creates preinst/prerm scripts with specific permissions. Those permissions
# (especially executable) should be in the final archive
find_program(CHMOD_PROG chmod)
if(CHMOD_PROG)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/preinst "echo default_preinst")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/prerm "echo default_prerm")
# Those should have 755 permission normally. We mess it up to see if
# CPACK_DEBIAN_APPLICATIONS_PACKAGE_CONTROL_STRICT_PERMISSION is able to fix
# it.
execute_process(COMMAND ${CHMOD_PROG} 640 ${CMAKE_CURRENT_BINARY_DIR}/preinst)
execute_process(COMMAND ${CHMOD_PROG} 640 ${CMAKE_CURRENT_BINARY_DIR}/prerm)
set(CPACK_DEBIAN_APPLICATIONS_PACKAGE_CONTROL_EXTRA
"${CMAKE_CURRENT_BINARY_DIR}/preinst;${CMAKE_CURRENT_BINARY_DIR}/prerm")
set(CPACK_DEBIAN_APPLICATIONS_PACKAGE_CONTROL_STRICT_PERMISSION TRUE)
endif()
# We may use the CPack specific config file in order # We may use the CPack specific config file in order
# to tailor CPack behavior on a CPack generator specific way # to tailor CPack behavior on a CPack generator specific way
# (Behavior would be different for RPM or TGZ or DEB ...) # (Behavior would be different for RPM or TGZ or DEB ...)