Overriding CPack variables

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.

e.g.:
https://cvs.savannah.gnu.org/viewvc/certi/certi/CERTICPackOptions.cmake.in?view=markup

in this example the CPack Project file is configured too:
https://cvs.savannah.gnu.org/viewvc/certi/certi/CMakeLists.txt?view=markup#l475

1 Like

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

Anyhow, the desired output is as follows:

PS /home/mate/Source/Test-Packaging [main]> /opt/Kitware/CMake/3.27.4/bin/cmake --workflow --preset ninja-mc-ci-linux | sls "Step"

Executing workflow step 1 of 9: configure preset "ninja-mc-ci-linux"
Executing workflow step 2 of 9: build preset "ninja-mc-ci-linux-release"
Executing workflow step 3 of 9: build preset "ninja-mc-ci-linux-debug"
Executing workflow step 4 of 9: test preset "ninja-mc-ci-linux-release"
Executing workflow step 5 of 9: test preset "ninja-mc-ci-linux-debug"
Executing workflow step 6 of 9: build preset "ninja-mc-ci-linux-release-install"
Executing workflow step 7 of 9: package preset "ninja-mc-ci-linux-binary-deb"
Executing workflow step 8 of 9: package preset "ninja-mc-ci-linux-source-deb"
Executing workflow step 9 of 9: package preset "ninja-mc-ci-linux-source-tgz"

PS /home/mate/Source/Test-Packaging [main]> dpkg --contents ./package/libuseful-dev_0.1-1_amd64.deb                               
drwxr-xr-x root/root         0 2023-09-27 16:46 ./usr/
drwxr-xr-x root/root         0 2023-09-27 16:46 ./usr/include/
-rw-r--r-- root/root       116 2023-09-22 11:40 ./usr/include/Useful.hpp
-rw-r--r-- root/root       862 2023-09-27 16:46 ./usr/include/Useful_Export.hpp
drwxr-xr-x root/root         0 2023-09-27 16:46 ./usr/share/
drwxr-xr-x root/root         0 2023-09-27 16:46 ./usr/share/cmake/
drwxr-xr-x root/root         0 2023-09-27 16:46 ./usr/share/cmake/Useful/
-rw-r--r-- root/root       833 2023-09-27 16:46 ./usr/share/cmake/Useful/UsefulConfig-release.cmake
-rw-r--r-- root/root      4319 2023-09-27 16:46 ./usr/share/cmake/Useful/UsefulConfig.cmake
-rw-r--r-- root/root      1859 2023-09-27 16:46 ./usr/share/cmake/Useful/UsefulConfigVersion.cmake
PS /home/mate/Source/Test-Packaging [main]> dpkg --contents ./package/libuseful-src_0.1-1.deb                                                                            
drwxr-xr-x root/root         0 2023-09-27 16:46 ./usr/
drwxr-xr-x root/root         0 2023-09-27 16:46 ./usr/src/
drwxr-xr-x root/root         0 2023-09-27 16:46 ./usr/src/libuseful/
-rw-r--r-- root/root      1201 2023-09-26 10:00 ./usr/src/libuseful/CMakeLists.txt
-rw-r--r-- root/root      4795 2023-09-27 16:46 ./usr/src/libuseful/CMakePresets.json
-rw-r--r-- root/root      6423 2023-09-22 16:38 ./usr/src/libuseful/LICENSE
-rw-r--r-- root/root         9 2023-09-22 16:39 ./usr/src/libuseful/README.md
drwxr-xr-x root/root         0 2023-09-27 16:46 ./usr/src/libuseful/cmake/
-rw-r--r-- root/root       546 2023-09-27 16:24 ./usr/src/libuseful/cmake/ProjectOwnerPackageConfig.cmake
-rw-r--r-- root/root      4360 2023-09-27 15:29 ./usr/src/libuseful/cmake/ProjectOwnerPackaging.cmake
-rw-r--r-- root/root       109 2023-09-22 10:23 ./usr/src/libuseful/cmake/SphinxInDisguise.cmake
drwxr-xr-x root/root         0 2023-09-27 16:46 ./usr/src/libuseful/docs/
-rw-r--r-- root/root       582 2023-09-22 10:43 ./usr/src/libuseful/docs/CMakeLists.txt
-rw-r--r-- root/root        63 2023-09-22 11:44 ./usr/src/libuseful/docs/index.md.in
drwxr-xr-x root/root         0 2023-09-27 16:46 ./usr/src/libuseful/include/
-rw-r--r-- root/root       116 2023-09-22 11:40 ./usr/src/libuseful/include/Useful.hpp
drwxr-xr-x root/root         0 2023-09-27 16:46 ./usr/src/libuseful/src/
-rw-r--r-- root/root      2886 2023-09-26 10:07 ./usr/src/libuseful/src/CMakeLists.txt
-rw-r--r-- root/root       187 2023-09-26 09:50 ./usr/src/libuseful/src/Capitalizer.cpp
-rw-r--r-- root/root        67 2023-09-22 11:44 ./usr/src/libuseful/src/DefaultLocale.hpp
-rw-r--r-- root/root       260 2023-09-22 11:43 ./usr/src/libuseful/src/Useful.cpp
drwxr-xr-x root/root         0 2023-09-27 16:46 ./usr/src/libuseful/tests/
-rw-r--r-- root/root       339 2023-09-25 16:03 ./usr/src/libuseful/tests/CMakeLists.txt
PS /home/mate/Source/Test-Packaging [main]> tar --list -f ./package/Useful-0.1-Source.tar.gz                                      
Useful-0.1-Source/src/
Useful-0.1-Source/src/Useful.cpp
Useful-0.1-Source/src/DefaultLocale.hpp
Useful-0.1-Source/src/CMakeLists.txt
Useful-0.1-Source/src/Capitalizer.cpp
Useful-0.1-Source/include/
Useful-0.1-Source/include/Useful.hpp
Useful-0.1-Source/tests/
Useful-0.1-Source/tests/CMakeLists.txt
Useful-0.1-Source/LICENSE
Useful-0.1-Source/README.md
Useful-0.1-Source/CMakeLists.txt
Useful-0.1-Source/cmake/
Useful-0.1-Source/cmake/ProjectOwnerPackageConfig.cmake
Useful-0.1-Source/cmake/SphinxInDisguise.cmake
Useful-0.1-Source/cmake/ProjectOwnerPackaging.cmake
Useful-0.1-Source/docs/
Useful-0.1-Source/docs/CMakeLists.txt
Useful-0.1-Source/docs/index.md.in
Useful-0.1-Source/CMakePresets.json