MantisBT - CMake
View Issue Details
0012997CMakeCPackpublic2012-02-25 18:022016-06-10 14:31
Eric NOULARD 
Kitware Robot 
normalfeatureN/A
closedmoved 
CMake 2.8.8 
CMake 2.8.12 
0012997: Provide a more flexible way to name package produced by CPack
Currently the name the package files produced by CPack generator
is "only" driven by the CPACK_PACKAGE_FILE_NAME variable.

CPack.cmake modules provides a default value, which is:
${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME}
etc...
This is not flexible enough and has already generated related bugs.

We may design a more flexible way to name the package which:
 1) Could be built at CPack time
 2) May generate different names for different generators
 3) May generate different names depending on the host system
    (Fedora RPM may not be named like OpenSuSE RPM)
 4) May take into the name mangling produced by component packaging
    producing multiple package files

More ideas in forthcoming notes.
No tags attached.
related to 0012574closed Kitware Robot package name for the nameless component in DEB should not include the "-unspecified" extension 
parent of 0011050closed Domen Vrankar CPack DEB: default to standard Debian package file names 
related to 0013015closed Domen Vrankar cpack deb generator components specify output names 
related to 0012351closed Kitware Robot CPack fails to find package baked by NSIS if CPACK_OUTPUT_FILE_NAME is used 
Issue History
2012-02-25 18:02Eric NOULARDNew Issue
2012-02-25 18:03Eric NOULARDRelationship addedrelated to 0012574
2012-02-25 18:03Eric NOULARDRelationship addedrelated to 0011050
2012-02-25 18:04Eric NOULARDAssigned To => Eric NOULARD
2012-02-25 18:04Eric NOULARDStatusnew => assigned
2012-02-25 18:25Eric NOULARDDescription Updatedbug_revision_view_page.php?rev_id=551#r551
2012-03-04 10:06Eric NOULARDRelationship addedrelated to 0013015
2012-03-08 11:16Philip SchwartzNote Added: 0028864
2012-03-08 11:44Eric NOULARDNote Added: 0028865
2012-03-08 11:54Philip SchwartzNote Added: 0028866
2012-03-08 12:02Eric NOULARDNote Added: 0028867
2012-03-08 13:36Philip SchwartzNote Added: 0028869
2012-03-08 13:56Eric NOULARDNote Added: 0028870
2012-03-08 14:38Philip SchwartzNote Added: 0028871
2012-03-08 14:53Philip SchwartzNote Added: 0028872
2012-03-12 14:04Philip SchwartzNote Added: 0028894
2012-03-12 14:36Eric NOULARDNote Added: 0028895
2012-03-12 14:51Philip SchwartzNote Added: 0028896
2012-03-13 07:37Philip SchwartzNote Added: 0028900
2012-03-13 07:57Eric NOULARDNote Added: 0028901
2012-03-13 08:26Philip SchwartzNote Added: 0028902
2012-03-13 09:22Philip SchwartzNote Added: 0028903
2012-03-13 10:46Eric NOULARDNote Added: 0028904
2012-03-13 10:49Eric NOULARDNote Added: 0028905
2012-03-13 11:03Philip SchwartzNote Added: 0028906
2012-03-13 11:12Eric NOULARDNote Added: 0028907
2012-03-13 11:29Philip SchwartzNote Added: 0028908
2012-03-13 11:51Eric NOULARDNote Added: 0028909
2012-06-15 02:28Eric NOULARDRelationship addedrelated to 0012351
2012-08-14 14:28Eric NOULARDTarget Version => CMake 2.8.10
2012-08-14 17:30Eric NOULARDRelationship replacedparent of 0011050
2012-09-19 16:48Chip ChristianNote Added: 0031066
2012-10-02 14:57Eric NOULARDTarget VersionCMake 2.8.10 => CMake 2.8.11
2013-05-17 09:33Robert MaynardTarget VersionCMake 2.8.11 => CMake 2.8.12
2013-10-24 18:15Jeff WicksNote Added: 0034236
2015-09-28 10:49Benoît BleuzéNote Added: 0039487
2015-09-28 11:20Eric NOULARDAssigned ToEric NOULARD =>
2015-09-28 11:21Eric NOULARDNote Added: 0039489
2015-09-29 03:07Benoît BleuzéNote Added: 0039492
2016-06-10 14:28Kitware RobotNote Added: 0041990
2016-06-10 14:28Kitware RobotStatusassigned => resolved
2016-06-10 14:28Kitware RobotResolutionopen => moved
2016-06-10 14:28Kitware RobotAssigned To => Kitware Robot
2016-06-10 14:31Kitware RobotStatusresolved => closed

Notes
(0028864)
Philip Schwartz   
2012-03-08 11:16   
I have been talking with Eric via email's about this issue. I have reached a need in my current work for the use of multiple packages generated from install components.

When looking at the standards followed in package naming for RPM and DEB based systems, you see the following:

<Name>-<subName>-<version>-<arch>.<ext>

This can have different separators and formats depending on package naming conventions.

I am proposing an idea based on the conversations with Eric to create a cpack variable of CPACK_PACKAGE_FILE_NAME_TEMPLATE.

This would use a formated string that would be parsed at cpack run time to generate the package name to be used.

I would purpose that there are a set list of values you can use in the template to stop any possible coruption of the naming that could have adverse affects.

The values that can be in the template would include at minmum the following.

CPACK_PACKAGE_NAME
CPACK_COMPONENT_NAME
CPACK_PACKAGE_VERSION
CPACK_SYSTEM_NAME
CPACK_NAME_SEPARATOR or a string value. (defaults to -, but can now be set)

The template if not set would default to:

<CPACK_PACKAGE_NAME><CPACK_NAME_SEPARATOR><CPACK_PACKAGE_VERSION><CPACK_NAME_SEPARATOR><CPACK_SYSTEM_NAME>[<CPACK_NAME_SEPARATOR><CPACK_COMPONENT_NAME>]

this would translate to:

<CPACK_PACKAGE_NAME>-<CPACK_PACKAGE_VERSION>-<CPACK_SYSTEM_NAME>[-<CPACK_COMPONENT_NAME>]

Which is the current standard naming schema used when creating packages with single package or component packaging.

One addition to this is the abbility to specify a special case component that when encountered would not change the naming rule to not display the component name. This would have the rule that only 1 component can be listed as a base component per cpack instance. (definable with CPACK_BASE_COMPONENT_NAME)
    
Using this schema change to how we generate names an example project could be generated as follows:


Project Name: GenTest
Package_Version: 0.0.1
System_Name: oneiric.amd64
COMPONENT_ALL: Runtime, Dev, Docs
CPACK_BASE_COMPONENT_NAME: Runtime
DEV_DISPLAY_NAME: dev
DOCS_DISPLAY_NAME: docs
CPACK_PACKAGE_FILE_NAME_TEMPLATE: <CPACK_PACKAGE_NAME>-<CPACK_COMPONENT_NAME>-<CPACK_PACKAGE_VERSION>-<CPACK_SYSTEM_NAME>

This would result in the following packages:
GenTest-0.0.1-oneiric.amd64.deb
GenTest-dev-0.0.1-oneiric.amd64.deb
GenTest-docs-0.0.1-oneiric.amd64.deb
(0028865)
Eric NOULARD   
2012-03-08 11:44   
I agree with all this with some further precisions:

 - For backward compatibility reason the "TEMPLATE" machinery
   will not be used if CPACK_PACKAGE_FILE_NAME is defined.
   This implies that CPack.cmake will be modified in order
   to check whether if CPACK_PACKAGE_FILE_NAME_TEMPLATE
   has been defined before providing the default definition
   of "CPACK_PACKAGE_FILE_NAME".
   The motivation is: user currently using
   CPACK_PACKAGE_FILE_NAME should not be bothered by the new
   template feature.

 - We off course need at least 2 test cases for this.
   One for the component case and one for the non-component case.
   It could be added to Tests/CPackComponentsForAll
   and add a new test for the non-component case.

 - The code for processing the template should be easily
   extendible for new CPACK_xxxx variable addition.
   see cpack --help-variable-list for existing ones.
   (this only works for cpack in git master)

I'm not sure I like the "CPACK_BASE_COMPONENT_NAME" wording...
May be CPACK_COMPONENT_NAMELESS or
CPACK_COMPONENT_NONAME_FOR ...would be more explicit?

This no-name thing could be treated separately and correspond
to bug 0012574.
(0028866)
Philip Schwartz   
2012-03-08 11:54   
Agreed. I will work out the code and full test cases. I am thinking that the template format would be better as a ; separated string to allow for fast vector expansion and iteration.

CPACK_PACKAGE_NAME;CPACK_NAME_SEPARATOR;CPACK_PACKAGE_VERSION;CPACK_NAME_SEPARATOR;CPACK_SYSTEM_NAME[;CPACK_NAME_SEPARATOR;CPACK_COMPONENT_NAME]

I think CPACK_COMPONENT_NONAME_FOR would be a better explicit name for a nameless component.

Currently how are install lines with no component directly handled? I have not tried having install's mixed between component and non-component to know if it would cause an issue.
(0028867)
Eric NOULARD   
2012-03-08 12:02   
Objects installed without COMPONENT are automagically put in a trap-them-all component named "Undefined".

After that,
the "Undefined" component is treated as others thus the 0012574 bug report.
(0028869)
Philip Schwartz   
2012-03-08 13:36   
If CPACK_COMPONENT_NONAME_FOR is set, would we want the items caught in the Undefined component added to the set for the CPACK_COMPONENT_NONAME_FOR?

Ie

set(CPACK_COMPONENT_NONAME_FOR runtime) would cause the runtime component + all from Undefined to be packaged together?
(0028870)
Eric NOULARD   
2012-03-08 13:56   
No don't think so.

Left over from COMPONENT install rule, should either be treated a a default
on their own or ignored.

I mean,

1) either you consider the "Undefined" component to be your "main"
   component and then
   set(CPACK_COMPONENT_NONAME_FOR Undefined).

2) or you consider that "Undefined" is not part of the packaging and
   set(CPACK_COMPONENTS_ALL "Runtime;Dev;Doc")
   since "Undefined" is not packaged at all

3) or you add COMPONENT spec install rule for the elements belonging
   to undefined.

4) or you define component "GROUP" and get a group-based packaging
   You may then put the "Undefined" componet in a group.

4) makes me thinks that if

CPACK_COMPONENTS_GROUPING==ONE_PER_GROUP

CPACK_COMPONENT_NONAME_FOR may hold the name of a component group
and not only the name of a bare component.
(0028871)
Philip Schwartz   
2012-03-08 14:38   
Easy enough to follow. An all or nothing if CPACK_COMPONENT_NONAME_FOR is not set, allow Undefined to generate as it, if it is set, only allow components that are defined to generate.
(0028872)
Philip Schwartz   
2012-03-08 14:53   
Also after further looking at the name generation. I don't think there should be any distinction between group or component when generating the name as it will be handled the same.

Allow the idea of it being a component or a group stay in the specific generator while the addition to the name would not matter.
(0028894)
Philip Schwartz   
2012-03-12 14:04   
I have been going back and forth on this and I am not sure of the solution for the initial patch that I will submit once I have final approval from legal.

For now I would like to discuss how we obtain a name for a package. For this lets keep the idea of just the Deb and RPM packages in sight and how this can be applied to the other generators.

Using a template for the name generation is ideal, defaulted to CPACK_PACKAGE_NAME;CPACK_PACKAGE_VERSION;CPACK_SYSTEM_NAME;

It is also ideal to store in the cpack config a configurable separator that will be used to separate parts of the name. The default for this should be a '-' as it is the generic for most of the generators.

All generators should use the logic for naming with the template if possible. This leads to a backwards compatibility issue unless we add logic that if the CPACK_PACKAGE_FILE_NAME is set, to use the new method.

By this I propose that all package generation should use a function to obtain a valid name from a template instead of a direct variable unless the variable has been set directly in a config file overriding CPack.cmake.


So the naming flow will be as done via a function with the following logic:

if CPACK_PACKAGE_FILE_NAME
  if component install
    Use name with post-pended component as currently done.
  else
    Use name as currently done.
else
  Use template based name.

The template based name will return a name the same as the current schema with the default template. If a component variable is specified in the template, it will be replaced with the name of the component or group instead of being post-pended to the end of the name.
(0028895)
Eric NOULARD   
2012-03-12 14:36   
We definitely NEED backward compatible behavior this is a major concern
of CMake/CPack developers and users.

So I am basically ok with your workflow.

> If a component variable is specified in the template, it will be replaced with the name of the component or group instead of being post-pended to the end of the name.

Yes "unless" we are not doing component install so in this case I suggest
either we have two templates --> one for the MONOLITHIC case and
--> one for the COMPONENT case or find a **simple** way to drop the component
name part when doing non-component packaging.

I would rather go for 2 templates it will be simpler to handle and probably
simpler to use as well.
(0028896)
Philip Schwartz   
2012-03-12 14:51   
2 templates are easy enough to manage.

I will code around that. I have changed some of the functions in the cmCPackGenerator class as I want them to be part of the base of all generators and will continue from there.

The first patch submission should be sometime this week.
(0028900)
Philip Schwartz   
2012-03-13 07:37   
I think I am lost, but in the packaging process, when is doPackage ever called as I see it being the only call to PrepareNames(). I ask this as I am tracking down all changes needed to convert from the old style usage of CPACK_PACKAGE_FILE_NAME to the template based naming.
(0028901)
Eric NOULARD   
2012-03-13 07:57   
For this kind of issue:

$ git grep -n DoPackage
may help.

The initial call to DoPackage is cpack.cxx:497
This in the CPack executable main.
In there you are in the loop over all generators,
for which a specific generator (a subclasss of cmCPackGenerator)
is created (by name)
cpack.cxx:440
   cpackGenerator = generators.NewGenerator(gen);

Then for each specific generator the cpack steps are done:

Initialize(...)
get/check some CPACK_xxx variable definition
DoPackage(...)

--> go to cmCPackGenerator::DoPackage() (cmCPackGenerator.cxx:951)
then
   --> PrepareNames()
   --> PrepareGroupingKind()
etc....

and you are right this is the only call to PrepareNames()
however CPACK_PACKAGE_FILE_NAME is used at several other places "directly".

Again you may try:
$ git grep -n CPACK_PACKAGE_FILE_NAME

It would be easier to remove those "direct accesses" using some accessor
method like GetPackageFileName in the same spirit as
GetComponentPackageFileName.

Or replace current call to
 this->GetOption("CPACK_PACKAGE_FILE_NAME")
with appropriate
 GetComponentPackageFileName(...)
(0028902)
Philip Schwartz   
2012-03-13 08:26   
That is what I thought call wise to PrepareNames.

I added the following to PrepareNames.

cmCPackLogger(cmCPackLog::LOG_WARNING,
      "IN PrepareNames" << std::endl);

And for at least Deb and RPM generation, the output from the logger is never displayed which confused me because looking at the code, should run.


As to the calls to GetOption("CPACK_PACKAGE_FILE_NAME"), the plans are to replace them with a call to a new function GetPackageFileName(template, component) which generates the file name based on the template.

The function will replace GetComponentPackageFileName() with a cleaner method of generating a file name that is generic. It will have 2 versions:

GetPackageFileName(template)
GetPackageFileName(template, component)
(0028903)
Philip Schwartz   
2012-03-13 09:22   
Here is the source of the 2 GetPackageFileName functions for you to look at while I prepare the patch.

http://pastebin.com/Z1fvkktV [^]

I am not sure if the name I am using for the component in the template is good or if I should define it as something else. I am defining it as CPACK_COMPONENT_NAME, but this is never evaluated but instead used as the replace element for the groupOrComponentName passed to the function.
(0028904)
Eric NOULARD   
2012-03-13 10:46   
I'll look into the no-trace pb even the best way to understand that
issue is certainly to debug into with the debugger.

Concerning the code snippet:

You shoud avoid:
std::string sep = std::string(GetOption("CPACK_SEPARATOR"));

do never trust the content of a CMake script variable
(unless you can "by design").

In this case if "CPACK_SEPARATOR" is undefined you'll get an
uncaught exception for building an std::string with null argument.
In such case you should check if GetOption is returning NULL and
either provide a builtin default value for sep or throw a
CPack fatal error with an explanation message.

Same remark for:
 tempPackageName += std::string(GetOption((*it).c_str()));
(0028905)
Eric NOULARD   
2012-03-13 10:49   
By the way CPACK_COMPONENT_NAME is fine.
As soon as CPack C++ knows it you can define it for potential
CPack script as well:

this->SetOptionIfNotSet("CPACK_COMPONENT_NAME",...)
(0028906)
Philip Schwartz   
2012-03-13 11:03   
Currently I am using a addition to CPack.cmake to verify that CPACK_SEPARATOR is always set to at least a default.

But in those cases, what would you suggest as the best way to handle if the option is not set.

const char* val = GetOption(X);
if ( !val )
  ERR
(0028907)
Eric NOULARD   
2012-03-13 11:12   
You should know that CPack (the application) may be used *without* CPack.cmake.
In fact some project even use CPack without CMake.

Those project may craft their own CPackConfig.cmake file and you have no
control on what they do. So some sanity check MUST be done in CPack C++ code.

Yes or:
char* val = GetOption(X);
if ( !val )
   val = "-";
(0028908)
Philip Schwartz   
2012-03-13 11:29   
> You should know that CPack (the application) may be used *without* CPack.cmake.
> In fact some project even use CPack without CMake.

Ok, That is good to know. I will work in what is needed to verify that a value is set as needed along with setting what is needed to work to defaults in PrepareNames.


Is there a reason why a lot of these are set in the cmake file with cpack_set_if_not_set instead of in PrepareNames as others are? I would think that if CPack.cmake is not required, that these would be wanted in PrepareNames in order to create basic settings.

Or in these circumstances is the cmake standard to error out and inform the user that it must be set in their CPackConfig.cmake?
(0028909)
Eric NOULARD   
2012-03-13 11:51   
I don't know the whole CPack history so I may be wrong.
The basic idea of CPack.cmake is to ease the creation
of a CPackConfig.cmake file.

The generated CPackConfig.cmake give the user an idea of the
variables that may be defined in order to influence CPack work.

In the beginning (the one I knw) not much CPACK_xxxx variable were set
in C++ part and most of the time those vars were RW from C++ and RO
from CPack script.


The cmCPackGenerator::PrepareNames() was introduced (by me) for the support
of component packaging of ArchiveGenerator, RPM and DEB
(then used by DMG as well).

The fact that a lot of var were SetOptionIfNotSet in there was a balance
to follow existing code practice and the necessary need for FULL backward
compatibility.

Usually:
  CPACK_xxx variable which are settable by the user should appear in
  CPack.cmake with a possible default value.

  CPACK_xxx variables which are not meant to be user settable
  are usually set in C++ and sometimes (depending on the generator)
  read in CPack script.
   e.g. : CPACK_TEMPORARY_DIRECTORY

You should usually error out in CPack C++ code if a CPACK_xxx variable
is not set as it should.
(0031066)
Chip Christian   
2012-09-19 16:48   
As a workaround I put the following in my build script:

PACKAGES="*rpm"
for i in ${PACKAGES}
do
    j=$(echo $i | sed 's/\([^-]*\)\(-\)\(.*\)\(-[^-]*\)\(\..*\)/\1\4\2\3\5/')
    mv $i $j
done

works with:
    SET(CPACK_PACKAGE_FILE_NAME ${PROJECT_NAME}-${CPACK_PACKAGE_VERSION}-${ARCHITECTURE})

if you use different values modify to suit
(0034236)
Jeff Wicks   
2013-10-24 18:15   
Dear Eric Noulard,

We have a temporary workaround but wanted to let you know that we are pulling for you to get this fixed.

It can certinaly be impossible to get extra development time these days. Nevertheless, we are grateful to you for your efforts. Please keep up the outstanding work!!

Jeff Wicks
jeffx.a.wicks at intel.com
(0039487)
Benoît Bleuzé   
2015-09-28 10:49   
Hi Eric,

Has there been any work on this issue for the past two years? I am in need of exactly this kind of user-defined naming template, which also works for components.

If Philip Schwartz is still around, do you still have some code around I could look at and maybe take over if you dropped the matter?
Or maybe Eric you do have some hidden branch somewhere with some code stub?

Short of having such a feature I would need to rely on a fix of issue 0008438 (add_dependencies() for "build-in cmake targets"), which seems much harder to solve.

Ben.
(0039489)
Eric NOULARD   
2015-09-28 11:21   
Hi Benoit,

Unfortunately the time I can spent on CMake/CPack is now too short for doing such work. I just forgot to unassign the ticket.

May be you can raise your concern on the CMake mailing list and/or propose some patch that may be reviewed by other "active" CMake developer.
(0039492)
Benoît Bleuzé   
2015-09-29 03:07   
Thanks for the heads up Eric, I raised my concerns to the mailing list already, albeit not only on this precise formatting and was redirected here by Nils Gladitz, but I will try again but with a message focused on this issue.

A patch does not look to hard to do with regards to the required c++ code, I am just a bit put off by the interaction between Cpack the program and cpack.cmake. Do you think it is possible with only c++ modification, or would I need to also tinker with cpack.cmake?
(0041990)
Kitware Robot   
2016-06-10 14:28   
Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.