install(EXPORT ... ) calculates incorrect _IMPORT_PREFIX if DESTINATION is set to a relative parent directory
Note: See repository for reproducing this issue here.
install(EXPORT ... )
calculates incorrect _IMPORT_PREFIX
if DESTINATION
set to relative parent directory
To Reproduce
Clone this repository and run its ./reproduce.sh
bash script.
Targets
ExportedLib
Imagine this is some external library that you want to use as a prebuilt dependency.
It's a shared library that's well-behaved except it installs some data we're not interested in keeping around.
DependsOnExportedLib
Depends on ExportedLib
and uses find_package
to pull it in.
Reproduction Steps
- First,
reproduce.sh
builds and installsExportedLib
in a pretty common way: - Generated with-DCMAKE_INSTALL_PREFIX=../install
- Install winds up inExportedLib/install
- Everything works like you'd expect, but we get an install of the data we didn't want. - Next,
reproduce.sh
builds and installsExportedLib
in a way that tries to avoid putting the undesired data next to everything else: - Generated with:-DCMAKE_INSTALL_PREFIX=install
-DCMAKE_INSTALL_LIBDIR=../../install/lib
-DCMAKE_INSTALL_BINDIR=../../install/bin
-DCMAKE_INSTALL_INCLUDEDIR=../../install/include
-
-DINSTALL_CONFIGDIR:PATH=../../install/cmake
- Install again winds up inExportedLib/install
except for data, which winds up inExportedLib/build/install
-DependsOnExportedLib
fails to importExportedLib
!
The Problem
In the second generated ExportedLibConfigInternal.cmake
, _IMPORT_PREFIX
gets set to <repo>/DependsOnExportedLib/
instead of <repo>/DependsOnExportedLib/build/_deps/exportedlib-src/
.
In an attempt to get back to CMAKE_INSTALL_PREFIX
from INSTALL_CONFIGDIR
, the _IMPORT_PREFIX
calculation goes "up" from the generated config file's location by one directory per separated path component that exists in INSTALL_CONFIGDIR
.
It doesn't realize that the INSTALL_CONFIGDIR
is already going up two directories, so the _IMPORT_PREFIX
goes "up" way too far, which is further exacerbated when ${_IMPORT_PREFIX}/../../install/lib
is evaluated.
Potential Solution
The _IMPORT_PREFIX
calculation should handle at least 3 cases per directory component. E.g.:
if(CONFIGDIR_COMPONENT STREQUAL "..")
# Down one directory
set(_IMPORT_PREFIX "${_IMPORT_PREFIX}/fake-subdirectory")
elseif(NOT (CONFIGDIR_COMPONENT STREQUAL "."))
# Up one directory
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
#else()
# ".", do nothing
endif()