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. |
|