1

I'm using CMake v3.21.0 to invoke Qt's windeployqt during the install stage by the means of the install(CODE) command as follows:

install(
    CODE "
    execute_process(
      COMMAND \"${CMAKE_COMMAND}\" -E
        env PATH=\"${windeployqt_ROOT_DIR}\"
        \"${windeployqt_EXECUTABLE}\"
        # TODO(2021-08-25 by wolters): This is a different path when CPack is`
        # used. How to check for this case and obtain the correct output path?
        --dir \"${CMAKE_INSTALL_PREFIX}/${args_INSTALL_SUFFIX}\"
        --no-quick-import
        --no-system-d3d-compiler
        --no-virtualkeyboard
        --no-compiler-runtime
        --no-webkit2
        --no-angle
        --no-opengl-sw
        --verbose 0
        \"\$<TARGET_FILE:${args_TARGET}>\"
    )
    "
    COMPONENT runtime
  )

This works fine if installing the project:

cmake --build . --config RelWithDebInfo --target install

But when creating a CPack package the files created by windeployqt are not part of the package (ZIP in this case):

cpack -G ZIP -C RelWithDebInfo -D CPACK_COMPONENTS_ALL="runtime"

I know that the issue is the usage of ${CMAKE_INSTALL_PREFIX} in the CODE.

  1. For the install target this is correct.
  2. For the package target this is not correct. Instead the build directory for the current CPack generator should be used, e.g. ${CMAKE_CURRENT_BINARY_DIR}/_CPack_Packages/win64/ZIP/${CPACK_PACKAGE_FILE_NAME}.

My questions are:

  1. Is there a way to differentiate between install and package target in the CODE section? (pseudo-code: if(CMAKE_IS_PACKAGING))
  2. If there is a way: Is it possible to obtain or dynamically build the directory path to the actual CPack temporary "install" directory?

If both problems can be solved the files generated by windeployqt should be part of the packages generated by CPack.

Florian Wolters
  • 3,820
  • 5
  • 35
  • 55

1 Answers1

1

The variable CMAKE_INSTALL_PREFIX should not be expanded in the CMakeLists.txt, as you are doing. Its actual value at invocation time is available inside the install(CODE) fragments.

Consider the following snippet:

cmake_minimum_required(VERSION 3.21)
project(test NONE)

install(CODE [[message(STATUS "HERE: ${CMAKE_INSTALL_PREFIX}")]])

Note that [[ ... ]] escapes variable expansions (you could also use backslashes). Now if you configure this project with -DCMAKE_INSTALL_PREFIX=/tmp/install, you'll see the message print as you expect.

$ cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/tmp/install
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/test/build
$ cmake --build build/ --target install
[0/1] Install the project...
-- Install configuration: ""
-- HERE: /tmp/install

If you now run the install script again without reconfiguring or rebuilding, it will still work:

$ cmake --install build/ --prefix /tmp/other-prefix
-- Install configuration: ""
-- HERE: /tmp/other-prefix

This is how CPack runs your install rules. It does not use the configuration-time value of CMAKE_INSTALL_PREFIX. It expects your project to be relocatable (i.e. bug-free).

Alex Reinking
  • 16,724
  • 5
  • 52
  • 86
  • I'm not sure if I correctly understand your point here. I understand the behavior described by you regarding the "install" step. But my issue isn't the install step, but the "package" step. CPack doesn't rely on the installation directory but creates a separate (temporary) directory in the build directory that is used for the packaging (`${CMAKE_CURRENT_BINARY_DIR}/_CPack_Packages`). I've **assumed** that CPack modifies `${CMAKE_INSTALL_PREFIX}` in a way that you described but that isn't the case as described in my OP. `${CMAKE_INSTALL_PREFIX}` != the directory CPack uses for packaging. – Florian Wolters Aug 26 '21 at 12:01
  • 1
    In the mean time I found https://stackoverflow.com/q/48477588/891439. i think this is what you are refererring to as "variable expansion"? I wasn't aware of this future until now. One backslash makes a **huge** difference: The package is properly created when using `\${CMAKE_INSTALL_PREFIX}` in the `install(CODE)` command. Thank you for pointing to the right direction! – Florian Wolters Aug 26 '21 at 12:41
  • @FlorianWolters - happy to help! Is there an adjustment I could make to my answer to improve it / have it accepted? – Alex Reinking Aug 26 '21 at 16:17