通常,类型为PATH
的相对参数,如"lib"或"source/include",在CMake中使用变量的当前值解析为绝对路径,例如:${CMAKE_INSTALL_PREFIX}
在命令INSTALL
的情况下。但是,如果我想使用空的相对路径(或根本不设置它(,则这不起作用,因此生成的绝对路径等于${CMAKE_INSTALL_PREFIX}
- CMake 生成器会抱怨不存在DESTINATION
,尽管没有理由无法解决。
我知道这个问题有两种解决方法,但这两种方法都有其缺陷,阻止我实现目标:
- 使用
${CMAKE_INSTALL_PREFIX}
作为DESTINATION
值。这正确地解析了路径,但在INSTALL(EXPORT)
的情况下,生成的Target.cmake
中的路径是绝对的,这使得包不可重定位。 -
使用
.
作为DESTINATION
。这至少在Target.cmake
内部生成相对路径,但路径不正确。.
显然被视为常规文件夹,并且在Target.cmake
生成过程中,当确定_IMPORT_PREFIX
时,CMake 过多地剥离了一个文件夹组件:# 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)
还有其他解决方法吗?您认为缺少空的相对路径可以被视为错误吗?
我想我为此找到了一些黑客解决方案。这将强制 cmake 生成导出文件,其中_IMPORT_PREFIX
设置为导出 cmake 的当前位置。 在安装和导出序列之前,修改CMAKE_INSTALL_PREFIX如下所示:
set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_LIST_FILE}/..")
${CMAKE_CURRENT_LIST_FILE}
前面的符号阻止计算变量引用
${CMAKE_CURRENT_LIST_FILE}
此时,它只是作为字符串传递。 之后,在导出的cmake中,您将获得:
set(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}/..")
您需要在末尾添加/..
set
因为该函数会将_IMPORT_PREFIX
设置为导出 cmake 的整个路径,以及 cmake 文件名(例如。C:/Works/project/ext/library/Library.cmake
(,所以/..
会掉/Library.cmake
.完美的结果是强制cmake在导出文件中使用get_filename_component
,例如:
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
但正如我在评论中提到的,关于 cmake 实现可能是不可能的。
我不知道修改CMAKE_INSTALL_PREFIX
是否没有任何负面副作用。在UNIX平台上,您可以尝试使用DESTDIR
而不是CMAKE_INSTALL_PREFIX
作为make
的参数,但我还没有尝试过。
CMAKE_CURRENT_LIST_DIR
对我有用。无需添加/..
.
@[Marek Kijo] - 感谢您的解决方案:set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_LIST_FILE}/..")