I’m having trouble with CPack, specifically its behavior of -D variables on the CLI not overriding those found in CPackSourceConfig.cmake. The documentation says:
Set a CPack variable. This will override any value set for <var> in the input file read by cpack.
But this doesn’t happen. Am I doing something wrong?
I wonder if this is fallout from local variables always winning over cache variables. Are -D parameters implemented as cache variables internally? Try this:
# somewhere you suspect it should be overridden
message("before: ${cpack_var}")
message("cache: $CACHE{cpack_var}")
unset(cpack_var)
message("after: ${cpack_var}")
With cpack_var replaced by the variable name of interest.
Sometimes the problem is specific to the variable you’re trying to set. See the recent issue 25248 for one example, which highlights a problem where some variables can’t be set on the cpack command line with -D options, because they are used to determine defaults of a different CPack variable, and that logic occurs at configure time, not when cpack is run.
Perhaps if you gave examples of the CPack variables you’re trying to set, we would have an idea whether this is the same situation you are in, or something different.
@craig.scott@ben.boeckel I’ve pushed my code to GitHub, it is intended to be a showcase of how to package the simplest of libraries using CPack witih using components.
I’ve confirmed that some of the variables in CPack are CACHE variables and can’t be overriden simply, they have to be unset first, otherwise nothing has meaningful effect. However even if I unset them, set them to the value I want (print the whole process using message commands), when the packages get generated, the change has no effect.
What I want to do is create binary packages for all the components, and create source packages using both the TGZ and the DEB generators. The TGZ tarball should have just the source tree in it, while the DEB source package should have a name format like the binary packages (libuserful-src_0.1.deb) and the packaged install root should be /usr/src/libuseful, but I can’t seem to make it so that I can build both source packages from the same configuration. I’d need cpack-time control over CPACK_PACKAGING_INSTALL_PREFIX and CPACK_SOURCE_INSTALLED_DIRECTORIES, with potentially these having defaults set in the configuration script, but I could let go of that.
I’ve had a similar issue a while ago, and even then I found no real solution beside setting variables in the configure script before include(CPack) and doing multiple configurations.
Ah. Yes, CPack kind of assumes that a single generator is in use at a time. One trick I’ve used is to configure different tests with each CPack generator of interest. Of course, the CPack configuration is now outside of the main project, but it does at least compartmentalize the assumptions CPack has in the area. This is particularly interesting on platforms like macOS where install rules differ between packages due to different layouts (e.g., Unix-style vs. a .app bundle). While I have tended to just replace the install rules, you could probably coax it to include() the install scripts for the main project from the CPack projects.
Did you try to use CPACK_PROJECT_CONFIG_FILE which gets included when CPack runs?
From the doc:
CPACK_PROJECT_CONFIG_FILE
CPack-time project CPack configuration file. This file is included at cpack time, once per generator after CPack has set CPACK_GENERATOR to the actual generator being used. It allows per-generator setting of CPACK_* variables at cpack time.
In this file you can decide to set varying CPACK_XXX variable depending on the value of
CPACK_GENERATOR.
In your particular case you should be able to set the value of CPACK_PACKAGING_INSTALL_PREFIX and CPACK_SOURCE_INSTALLED_DIRECTORIES depending on the running CPACK_GENERATOR.
@ben.boeckel I managed to solve my issue. The repo with this commit functions properly. The binary DEB, the source DEB and the source TGZ all have the intended package prefix, all which differ from install prefix. (One can create all the packages without being root.)
Quite frankly CPack is a terrible experience. Not necessarily because of the (sometimes overlapping) abstractions it introduces, but because of all the implicit behavior baked in. Documentation is lacking, at points it’s simply outdated/untrue. The end result is that CPack scripts that are in the wild are littered with comments about how everything is a workaround and generally brittle. For eg. my solution too only works because CPACK_INSTALLED_DIRECTORIES and CPACK_SOURCE_INSTALLED_DIRECTORIES are set to coincide while packaging the source package. The prior should have no effect when creating source packages. I may have missed some crucial detail in the docs, but this is fairly counterintuitive. (My colleague found similar coupling in binary pacakges between CMAKE_INSTALL_PREFIX and CPACK_PACKAGING_INSTALL_PREFIX, that the latter only affects project layout if the prior is set to coincide with it.)
It is hard to advocate for a project to adopt CPack as the primary/only source of packaging.