Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can parameter DESTINATION for INSTALL be empty?

Tags:

cmake

In general, relative parameters of type PATH, like "lib" or "source/include" are resolved in CMake to an absolute path using current value of variables, like for instance: ${CMAKE_INSTALL_PREFIX} in case of command INSTALL. This, however, does not work if I would like to use empty relative path (or not set it at all), so that the resulting absolute path was equal to ${CMAKE_INSTALL_PREFIX} - CMake generator would complain about non existing DESTINATION, although there is no reason why it couldn't be resolved.

I know two workarounds to this issue, but the both have their flaws which prevent me from achieving my goal:

  1. Use ${CMAKE_INSTALL_PREFIX} as the DESTINATION value. This correctly resolved the path, but in case of INSTALL(EXPORT), paths in generated Target.cmake are absolute, which makes the package not relocatable.
  2. Use . as the DESTINATION. This at least generates relative paths inside Target.cmake, but the paths are incorrect. . is apparently considered as a regular folder, and in the process of Target.cmake generation, when _IMPORT_PREFIX is determined, CMake strips one folder component too much:

    # Compute the installation prefix relative to this file.
    get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
    get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
    

Is there any other workaround? Do you think that lack of empty relative paths could be considered a bug?

like image 875
Piotr G Avatar asked Apr 11 '26 20:04

Piotr G


1 Answers

I think I found some hacky solution for that. This will force cmake to generate the export file where _IMPORT_PREFIX is set to current location of the exported cmake. Right before the install and export sequence modify CMAKE_INSTALL_PREFIX like this:

set(CMAKE_INSTALL_PREFIX "\${CMAKE_CURRENT_LIST_FILE}/..")

The \ sign before ${CMAKE_CURRENT_LIST_FILE} prevents from evaluating variable reference ${CMAKE_CURRENT_LIST_FILE} at this point, it is just passed as a string. After that in exported cmake you will get:

set(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}/..")

You need to add /.. at the end because set function will set the _IMPORT_PREFIX as a whole path to exported cmake, together with the cmake file name (eg. C:/Works/project/ext/library/Library.cmake) so the /.. will drop /Library.cmake. Perfect result would be to just force cmake to use get_filename_component in exported file, like:

get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)

But as I mentioned in a comment it is probably impossible regarding cmake implementation.

I don't know if modifying CMAKE_INSTALL_PREFIX has no any negative side effects. On UNIX platform you can try to use DESTDIR instead of CMAKE_INSTALL_PREFIX as an argument for make, but I haven't tried that.

like image 61
Marek Kijo Avatar answered Apr 18 '26 06:04

Marek Kijo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!