CMakeUserUseRPMTools: Difference between revisions

From KitwarePublic
Jump to navigationJump to search
(Add explicit preformat markup)
(Remove leading space rectangles from preformatted blocks)
Line 15: Line 15:


<pre>
<pre>
  INCLUDE(CPack)
INCLUDE(CPack)
  INCLUDE(UseRPMTools)
INCLUDE(UseRPMTools)
  IF(RPMTools_FOUND)
IF(RPMTools_FOUND)
      RPMTools_ADD_RPM_TARGETS(packagename)
  RPMTools_ADD_RPM_TARGETS(packagename)
  ENDIF(RPMTools_FOUND)
ENDIF(RPMTools_FOUND)
</pre>
</pre>


Line 32: Line 32:


<pre>
<pre>
  RPMTools_ADD_RPM_TARGETS(packagename ${CMAKE_SOURCE_DIR}/package.spec)
RPMTools_ADD_RPM_TARGETS(packagename ${CMAKE_SOURCE_DIR}/package.spec)
</pre>
</pre>


Line 40: Line 40:


<pre>
<pre>
  RPMTools_ADD_RPM_TARGETS(packagename ${CMAKE_SOURCE_DIR}/package.spec.in)
RPMTools_ADD_RPM_TARGETS(packagename ${CMAKE_SOURCE_DIR}/package.spec.in)
</pre>
</pre>


Line 79: Line 79:
#      -->Set up some more names
#      -->Set up some more names
<pre>
<pre>
          const char* tempPackageFileName = this->GetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME");
const char* tempPackageFileName = this->GetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME");
          const char* packageFileName = this->GetOption("CPACK_OUTPUT_FILE_PATH");
const char* packageFileName = this->GetOption("CPACK_OUTPUT_FILE_PATH");
          const char* tempDirectory  = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
const char* tempDirectory  = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
</pre>
</pre>
#      -->Collect files in the package tree in order to build the file list to be passed to compressFiles
#      -->Collect files in the package tree in order to build the file list to be passed to compressFiles
Line 88: Line 88:


<pre>
<pre>
        HERE cmCPackGenericGenerator fixes the name to be used by the specialized generator  
HERE cmCPackGenericGenerator fixes the name to be used by the specialized generator  
        this is ''tempPackageFileName'' the value of tempPackageFileName comes from step 5.
this is ''tempPackageFileName'' the value of tempPackageFileName comes from step 5.
</pre>
</pre>


Line 100: Line 100:
:: cmake-2.5.0-Linux-i686.rpm is not because it does not follow standard RPM naming scheme which should be something like ''cmake-<version>-<rpmrelease>.<arch>.rpm'' e.g. ''cmake-2.5.0-2fc6.i686.rpm''
:: cmake-2.5.0-Linux-i686.rpm is not because it does not follow standard RPM naming scheme which should be something like ''cmake-<version>-<rpmrelease>.<arch>.rpm'' e.g. ''cmake-2.5.0-2fc6.i686.rpm''
<pre>
<pre>
 
 
</pre>
</pre>
I think the naming scheme problem comes from the fact that we are trying to share the cpack config files generated by ''CPack.cmake'' which may not be suitable for all generators.
I think the naming scheme problem comes from the fact that we are trying to share the cpack config files generated by ''CPack.cmake'' which may not be suitable for all generators.
Line 107: Line 107:


<pre>
<pre>
    const char* packageFileName = this->GetOption("CPACK_OUTPUT_FILE_PATH");
const char* packageFileName = this->GetOption("CPACK_OUTPUT_FILE_PATH");
</pre>
</pre>


Line 114: Line 114:


<pre>
<pre>
    this->SetOption("CPACK_OUTPUT_FILE_NAME",rpmFileName);
this->SetOption("CPACK_OUTPUT_FILE_NAME",rpmFileName);
    (see commented code in cmCPackRPMGenerator.cxx)
(see commented code in cmCPackRPMGenerator.cxx)
</pre>
</pre>


Line 121: Line 121:


<pre>
<pre>
    this->ReadListFile("CPackRPM.cmake");
this->ReadListFile("CPackRPM.cmake");
</pre>
</pre>



Revision as of 18:33, 24 April 2018

Back

Description

The UseRPMTools CMake module simplifies the RPM package generation using both CPack and CMake. It has been done because CPack does not have an RPM generator. This CMake macro is only useful for Linux systems using RPM packages (RedHat/Fedora, Mandriva, ...)

A CPack RPM generator is now built-in CMake 2.6.x CMake:CPackPackageGenerators#RPM_.28Unix_Only.29

Usage

The usage is simple:

  • put the macro file "UseRPMTools.cmake" in your CMAKE_MODULE_PATH
  • Then add something like this to your CMakeLists.txt
INCLUDE(CPack)
INCLUDE(UseRPMTools)
IF(RPMTools_FOUND)
   RPMTools_ADD_RPM_TARGETS(packagename)
ENDIF(RPMTools_FOUND)

then if the necessary RPM building tools are found you inherit 2 new top-level (custom) targets named

  • packagename_rpm
  • packagename_srpm

you may call them to build binary or source RPM.

The macro generates a MINIMAL spec file, but if you want to tailor your handcrafted spec file you may provide one to the macro as a second argument:

RPMTools_ADD_RPM_TARGETS(packagename ${CMAKE_SOURCE_DIR}/package.spec)

You will get the same targets but using your custom spec files.

If your custom spec file need to be CONFIGUREd then name it with .in extension and the macro will process the file accordingly.

RPMTools_ADD_RPM_TARGETS(packagename ${CMAKE_SOURCE_DIR}/package.spec.in)

CPack Built-in RPM support design issues

The builtin support of RPM generator has been added to CMake/CPack cvs during the end of August 2007. As stated [[1]] the builtin support is not as powerful as the macro module. Beside the lack of time to do it I'll give here some ideas concerning the current limitation of the built-in support. I put it here in order to enable future work on this for anybody wanting to volunteer (including me if I have more time).

Macro-based CPack generator

Heres comes some ideas and question regarding a possibly 100% CMake Macro cpack generator.

I think it would be nice if we could implement most (if not all) CPack generators as almost "pure" CMake scripts. This is what I wanted to do when writing the CPack RPM generator, and this may be seen in the

CMake/Source/CPack/cmCPackRPMGenerator.cxx::cmCPackRPMGenerator::CompressFiles which mostly does: this->ReadListFile("CPackRPM.cmake");

The fact is I did face some design issues in the CPack generic generator which prevents me for doing what I wanted to.

The main issue are the implicit functional hypothesis built-in the CMake/Sources/CPack/cmCPackGenericGenerator.cxx from which all generator are derived from.

The way Generic Generator is implemented enforces a particular SEQUENTIAL definition and usage of CPACK_xxx var names.

Typically when a Generator is run you end-up in:

  1. cmCPackGenericGenerator::ProcessGenerator
  2. -->cmCPackGenericGenerator::PrepareNames
  3. -->conditionnaly remove the directory defined by CPACK_TOPLEVEL_DIRECTORY
  4. -->cmCPackGenericGenerator::InstallProject
  5. -->Set up some more names
const char* tempPackageFileName = this->GetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME");
const char* packageFileName = this->GetOption("CPACK_OUTPUT_FILE_PATH");
const char* tempDirectory   = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
  1. -->Collect files in the package tree in order to build the file list to be passed to compressFiles
  2. -->Eventually remove old (previously generated) package file
  3. -->cmCPackGenericGenerator::compressFiles(const char* outFileName, const char* toplevel,const std::vector<std::string>& files)
HERE cmCPackGenericGenerator fixes the name to be used by the specialized generator 
this is ''tempPackageFileName'' the value of tempPackageFileName comes from step 5.
  1. --> copy the tempPackageFileName to packageFileName packageFileName comes from step 5.


I think almost all of this is OK but:

The compressFile step should be given a chance to overload some of the CPACK_xxxx variables previously defined because for example the naming scheme indicated by: CPACK_OUTPUT_FILE_NAME may not be followed by ALL generators.
cmake-2.5.0-Linux-i686.tar.gz is OK for TGZ generator
cmake-2.5.0-Linux-i686.rpm is not because it does not follow standard RPM naming scheme which should be something like cmake-<version>-<rpmrelease>.<arch>.rpm e.g. cmake-2.5.0-2fc6.i686.rpm

I think the naming scheme problem comes from the fact that we are trying to share the cpack config files generated by CPack.cmake which may not be suitable for all generators.

The overloading scheme should be done by simply avoiding to use

const char* packageFileName = this->GetOption("CPACK_OUTPUT_FILE_PATH");

before calling compressFile but just after. That way inside the derived-class compress file we may:

this->SetOption("CPACK_OUTPUT_FILE_NAME",rpmFileName);
(see commented code in cmCPackRPMGenerator.cxx)

or the

this->ReadListFile("CPackRPM.cmake");

may simply do it.


Moreover in order to achieve a "true" user-extensible 100% macros CPack Generator I think we may split the current CPackRPM.cmake into at least 3 files.

  • CPackRPM.cmake which contains RPM specific var definitions this may be this->ReadListFile before calling compressFile (ideally this may be done by CPackGenericGenerator if "Macro" generator case is detected)
  • CPackRPM_BinaryRun.cmake this will be this->ReadListFile in case we require a Binary package
  • CPackRPM_SourceRun.cmake this will be this->ReadListFile in case we require a Source package

Using this scheme the CPackGenericGenerator may look for CPack<GenName>*.cmake files in the CMAKE_MODULE_PATH and we may write a single CPackMacroGenerator class which will be more or less like CPackRPMGenerator + the source vs binary handling and authorized varname overload.

I don't know how/if CPack is told to build a SOURCE or a BINARY package? Is it known to cpack or cpack only knows the name of its config file?

Back



CMake: [Welcome | Site Map]