Conditionally install file depending on CPack generator

I am seeking to generate Linux packages (DEB;RPM) with integration into distribution specific locations via custom file installation. I would prefer to only include the integration file for certain CPack generator types, and the system integration files need to be installed outside of the install prefix to distribution defined locations.

Since several external libraries are vendored/bundled, our package uses CPACK_PACKAGING_INSTALL_PREFIX=/opt/MyPackage, and assume the required integration file destination as:

RPM: /etc/FooBar/conf.d/mypackage.conf
DEB: /etc/foobar/config.d/mypackage.conf

The best alternative I have been able to come up with is to universally install() a share/doc/examples/mypackage.conf file and copy it into the desired location using a post-install and pre-uninstall script. That seems quite clumsy to maintain, and doesn’t result in the integration file being reported as part of package contents when listing package files.

Is there a better way to accomplish this?

Unfortunately, there’s nothing I know of that allows this. Note that it is harder than that because sometimes the layout is different based on the generator (e.g., macOS .app bundles versus a Unix-like installation) which can change your rpath needs as well).

Would a feature request for something like this be considered? As an initial design stab an initial design option may be an additional condition option on install() similar to CONFIGURATIONS, resulting in something like below.

configure_file("${PROJECT_SOURCE_DIR}/mypackage.conf.in" "${PROJECT_BINARY_DIR}/mypackage.conf)

# Use RPM specific integration location
install(FILES "${PROJECT_BINARY_DIR}/mypackage.conf"
        CONFIGURATION Release
        CPACK_DESTINATION "/etc/FooBar/conf.d"
        CPACK_GENERATOR RPM)

# Use DEB specific integration location
install(FILES "${PROJECT_BINARY_DIR}/mypackage.conf"
        CONFIGURATION Release
        CPACK_DESTINATION "/etc/foobar/config.d"
        CPACK_GENERATOR DEB)

# Include example for manual reference select other packages
install(FILES "${PROJECT_BINARY_DIR}/mypackage.conf"
        CONFIGURATION Release
        DESTINATION "usr/share/MyPackage/examples"
        CPACK_GENERATOR "ZIP;TGZ;TZST")

Note the different usage of DESTINATION vs. the hypothetical CPACK_DESTINATION. I presume something like that would be required since running the actual install phase during CPack execution shouldn’t try to write to the actual full path, but be independent from install prefix when installing to _CPACK_PACKAGES/X/Y scratch directories. It would seem to be needed to have some mechanism to specify an absolute path-in-resulting-package. That may become overly messy however, so perhaps there’s a cleaner approach. On the other hand, being a bit more verbose and tedious for such cases may help continue usage of prefix variables instead of specifying absolute locations?

Given how other things work with install(), something like this might work better:

install(FILES "${PROJECT_BINARY_DIR}/mypackage.conf"
  DESTINATION "share/MyPackage/examples" # default
  CPACK # if any match, ignore other `DESTINATION` bits
    RPM_DESTINATION "/etc/FooBar/conf.d"
    DEB_DESTINATION "/etc/foobar/config.d")

This should also work with things like (just an example as CMAKE_INSTALL_LIBDIR handles this specific case anyways):

install(TARGET somelibrary
  ARCHIVE
    DESTINATION "lib" # default
    CPACK # if any match, ignore other `DESTINATION` bits
      RPM_DESTINATION "lib64"
      DEB_DESTINATION "lib/${triple}")

But it sounds like it could be useful, so a feature request would be fine with me.

1 Like