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:
${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.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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With