install(EXPORT) does not properly take into account of paths containing '..'

The command install(EXPORT) in its current state is vastly incompatible with making packages with non-standard install directories (for example /lib instead of /usr/lib) resulting in extra get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) being generated for every ‘..’ used instead of correctly calculating the appropriate path.

For example: If its installed to /lib/cmake//.cmake and the install prefix is /usr, it will generate an extra get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) for the ‘..’ inside of CMAKE_INSTALL_LIBDIR.

Why does this matter to me? Well I’m trying my hand of making my own Linux OS that uses a seperated /lib and /usr/lib instead of the standard symlink of /lib → /usr/lib.

I can’t understand what you try to do?

You may always install to any prefix independent of the default settings:

bash-5.2$ cmake --install . --prefix /tmp
-- Install configuration: "RelWithDebInfo"
-- Installing: /tmp/lib/libbeman.exemplar.a
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: /tmp/lib/libbeman.exemplar.a(identity.cpp.o) has no symbols
warning: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: archive library: /tmp/lib/libbeman.exemplar.a the table of contents is empty (no object file members in the library define global symbols)
-- Installing: /tmp/include/beman/exemplar/identity.hpp
-- Installing: /tmp/lib/cmake/beman.exemplar/beman.exemplar-config.cmake
-- Installing: /tmp/lib/cmake/beman.exemplar/beman.exemplar-config-version.cmake
-- Installing: /tmp/lib/cmake/beman.exemplar/beman.exemplar-targets.cmake
-- Installing: /tmp/lib/cmake/beman.exemplar/beman.exemplar-targets-relwithdebinfo.cmake
bash-5.2$ cmake --install . 
-- Install configuration: "RelWithDebInfo"
-- Installing: /Users/clausklein/Workspace/cpp/beman-project/exemplar/stagedir/lib/libbeman.exemplar.a
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: /Users/clausklein/Workspace/cpp/beman-project/exemplar/stagedir/lib/libbeman.exemplar.a(identity.cpp.o) has no symbols
warning: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: archive library: /Users/clausklein/Workspace/cpp/beman-project/exemplar/stagedir/lib/libbeman.exemplar.a the table of contents is empty (no object file members in the library define global symbols)
-- Up-to-date: /Users/clausklein/Workspace/cpp/beman-project/exemplar/stagedir/include/beman/exemplar/identity.hpp
-- Up-to-date: /Users/clausklein/Workspace/cpp/beman-project/exemplar/stagedir/lib/cmake/beman.exemplar/beman.exemplar-config.cmake
-- Up-to-date: /Users/clausklein/Workspace/cpp/beman-project/exemplar/stagedir/lib/cmake/beman.exemplar/beman.exemplar-config-version.cmake
-- Up-to-date: /Users/clausklein/Workspace/cpp/beman-project/exemplar/stagedir/lib/cmake/beman.exemplar/beman.exemplar-targets.cmake
-- Up-to-date: /Users/clausklein/Workspace/cpp/beman-project/exemplar/stagedir/lib/cmake/beman.exemplar/beman.exemplar-targets-relwithdebinfo.cmake
bash-5.2$ 

GNUInstallDirs normalizes the variable CMAKE_INSTALL_LIBDIR to be under /usr/, I have to force it to go to / by using ../ which results in an extra get_filename_componet() call for _IMPORT_PREFIX resulting in the final import prefix being outside of where “root” is.

This also results in /usr being dropped from the final auto determined import prefix as well.

This is the real bug, and the documentation added in CMake 3.4 to justify it is wrong:

  /

  For <dir> other than the SYSCONFDIR, LOCALSTATEDIR and
  RUNSTATEDIR, the value of CMAKE_INSTALL_<dir> is prefixed
  with usr/ if it is not user-specified as an absolute path.

It justifies this with:

  This is required by the GNU Coding Standards, which state:

    When building the complete GNU system, the prefix will be empty
    and /usr will be a symbolic link to /.

But that’s just, not what that sentence says at all? It’s saying if the prefix is empty (not "/"), then everything should be installed to /, and anything that is installed to /usr should instead end up in /.

I would open up an issue. CMake should absolutely support the old-school usage of root as the “essentials” install tree.