【发布时间】:2022-05-12 17:46:59
【问题描述】:
我希望能够从已安装的库中导入目标,但是 使用时:
install(TARGETS
foobar
EXPORT foobarLibTargets
LIBRARY DESTINATION lib)
cmake 生成一个包含绝对路径的 foobarLibTargets.cmake:
set_target_properties(foobar PROPERTIES
IMPORTED_LOCATION_NOCONFIG "/where/I/happened/to/build/libfoobar.so"
IMPORTED_SONAME_NOCONFIG "libfoobar.so"
)
这样使用安装中导入的目标的构建将失败,因为路径不存在。
Q 我怎样才能让它使用正确的相对位置呢?
这相当于:
set_target_properties(foobar PROPERTIES
IMPORTED_LOCATION_NOCONFIG "@PACKAGE_LIBRARY_INSTALL_DIR@/libfoobar.so")
如果我查看另一个做类似事情但有效的项目:
set_target_properties(foobar PROPERTIES
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/libfoobar.so"
IMPORTED_SONAME_RELEASE "libfoobar.so"
)
以下是一些重现该问题的示例文件:
CMakeLists.txt:
cmake_minimum_required(VERSION 3.7)
project(FOOBAR VERSION 1.2.3)
set(VERSION 1.2.3)
set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib:$ORIGIN/")
set(CMAKE_INSTALL_PREFIX "/opt/foobar" CACHE PATH "Install path prefix" FORCE)
add_library(foobar SHARED
foobar.cpp
)
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0)
set(CPACK_PACKAGE_NAME "foobar")
set(CPACK_PACKAGE_VERSION ${VERSION})
set(CPACK_PACKAGING_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
include(CPack)
# Indicate the content of the distribution pakcages
install(FILES
${CMAKE_SOURCE_DIR}/foobar.h
DESTINATION include
)
install(TARGETS
foobar
EXPORT foobarLibTargets
LIBRARY DESTINATION lib)
include(CMakePackageConfigHelpers)
set(ConfigFileInstallDir lib/cmake/foobar)
set(INCLUDE_INSTALL_DIR include)
set(LIBRARY_INSTALL_DIR lib)
message(STATUS "CMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}")
configure_package_config_file(foobarConfig.cmake.in
"${CMAKE_BINARY_DIR}/foobarConfig.cmake"
INSTALL_DESTINATION "${ConfigFileInstallDir}"
PATH_VARS INCLUDE_INSTALL_DIR LIBRARY_INSTALL_DIR)
write_basic_package_version_file(
"${CMAKE_BINARY_DIR}/foobarConfigVersion.cmake"
VERSION "${VERSION}"
COMPATIBILITY ExactVersion)
export(EXPORT foobarLibTargets
FILE "${CMAKE_CURRENT_BINARY_DIR}/foobarLibTargets.cmake")
install(EXPORT foobarLibTargets
FILE foobarTargets.cmake
DESTINATION lib/cmake)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/foobarConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/foobarConfigVersion.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/foobarLibTargets.cmake"
DESTINATION "${ConfigFileInstallDir}")
foobarConfig.cmake.in:
set(FOOBAR_VERSION @VERSION@)
@PACKAGE_INIT@
set_and_check(FOOBAR_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
set_and_check(FOOBAR_LIBRARY "@PACKAGE_LIBRARY_INSTALL_DIR@/libfoobar.so")
set_and_check(FOOBAR_LIBRARY_DIR "@PACKAGE_LIBRARY_INSTALL_DIR@")
include("${CMAKE_CURRENT_LIST_DIR}/foobarLibTargets.cmake")
# workaround - correct absolute path in the above
# this shouldn't be necessary (hence this question)
#set_target_properties(foobar PROPERTIES
# IMPORTED_LOCATION_NOCONFIG "@PACKAGE_LIBRARY_INSTALL_DIR@/libfoobar.so"
#)
foobar.h:
void hello();
foobar.cpp:
#include <iostream>
void hello() {
std::cerr << "hello world\n";
}
useFoo.cmake(使用已安装库的示例项目的 CMakeLists.txt):
cmake_minimum_required(VERSION 3.7)
project(useFoo VERSION 1.2.3)
set(VERSION 1.2.3)
find_package(foobar)
file(GENERATE OUTPUT foobar-gen CONTENT "<TARGET_FILE:foobar>=$<TARGET_FILE:foobar>\n")
message(STATUS "FOOBAR_LIBRARY_DIR=${FOOBAR_LIBRARY_DIR}")
message(STATUS "FOOBAR_INCLUDE_DIR=${FOOBAR_INCLUDE_DIR}")
build.sh(构建并使用安装包):
#!/bin/sh
rm -rf target
mkdir target
cd target
cmake .. &&
make &&
cpack -G TGZ
if [ $? -ne 0 ]; then
echo "doh!"
exit 1
fi
cd ..
rm -rf install
mkdir install
cd install
tar -xvzf ../target/foobar-1.2.3.tar.gz
cp ../useFoo.cmake CMakeLists.txt
export CMAKE_PREFIX_PATH=`pwd`/opt/foobar/lib/cmake:`pwd`/opt/foobar/lib/cmake/foobar
cmake .
if [ $? -ne 0 ]; then
echo "doh!"
exit 1
fi
cat foobar-gen
cat foobar-gen 的输出是:
<TARGET_FILE:foobar>=/where/I/happened/to/build/libfoobar.so
我希望它是:
<TARGET_FILE:foobar>=/where/I/actually/installed/libfoobar.so
如果我取消注释解决方法,它会变成什么。 有没有办法避免变通办法?
相关问题 - Strange issue with variables in a config-file cmake package - 具有类似的代码,既重现了此问题,又在顶部添加了另一个问题。
【问题讨论】:
标签: cmake