在导入/导出CMake包时,我遇到了一些我无法理解的东西。我有两个库,lib1和lib2以及下面的文件夹结构
project/
├─ lib1/
│ ├─ CMakeLists.txt
│ ├─ include/
│ │ ├─ lib1/
│ │ │ ├─ lib1.hpp
│ ├─ src/
│ │ ├─ lib1.cpp
├─ lib2/
│ ├─ CMakeLists.txt
│ ├─ include/
│ │ ├─ lib2/
│ │ │ ├─ lib2.hpp
│ ├─ src/
│ │ ├─ lib2.cpp我有以下CMakeLists.txt文件
###################################################################################################
# LIBRARY CREATION
###################################################################################################
cmake_minimum_required(VERSION 3.11)
project(lib1 VERSION 0.0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_DEBUG_POSTFIX d)
include(GNUInstallDirs)
# collect private library headers and implementation files
file(GLOB LIBRARY_SOURCES CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/src/*)
# add library
add_library(${PROJECT_NAME} ${LIBRARY_SOURCES})
# public header file usage for library
target_include_directories(${PROJECT_NAME} PRIVATE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}>)
target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
# specify compile requirements
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_11)
###################################################################################################
###################################################################################################
# LIBRARY INSTALLATION
###################################################################################################
include(CMakePackageConfigHelpers)
# install library and create export form specifying build artifact installation locations
install(TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}_Targets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
# install public headers
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
# install cmake file specifying installation targets
install(EXPORT ${PROJECT_NAME}_Targets
FILE ${PROJECT_NAME}Targets.cmake
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
# create version file for cmake project
write_basic_package_version_file(${PROJECT_NAME}ConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion)
# create config file for cmake project
configure_package_config_file(${PROJECT_SOURCE_DIR}/cmake/${PROJECT_NAME}Config.cmake.in
${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
# install cmake project config files
install(FILES ${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}/)
######################################################################################################################################################################################################
# LIBRARY CREATION
###################################################################################################
cmake_minimum_required(VERSION 3.11)
project(lib2 VERSION 0.0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_DEBUG_POSTFIX d)
include(GNUInstallDirs)
# collect private library headers and implementation files
file(GLOB LIBRARY_SOURCES CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/src/*)
# add library
add_library(${PROJECT_NAME} ${LIBRARY_SOURCES})
# public header file usage for library
target_include_directories(${PROJECT_NAME} PRIVATE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}>)
target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
# specify compile requirements
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_11)
# link library 1
find_package(lib1 CONFIG REQUIRED
COMPONENTS lib1)
target_link_libraries(${PROJECT_NAME} lib1::lib1)
###################################################################################################
###################################################################################################
# LIBRARY INSTALLATION
###################################################################################################
include(CMakePackageConfigHelpers)
# install library and create export form specifying build artifact installation locations
install(TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}_Targets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
# install public headers
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
# install cmake file specifying installation targets
install(EXPORT ${PROJECT_NAME}_Targets
FILE ${PROJECT_NAME}Targets.cmake
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
# create version file for cmake project
write_basic_package_version_file(${PROJECT_NAME}ConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion)
# create config file for cmake project
configure_package_config_file(${PROJECT_SOURCE_DIR}/cmake/${PROJECT_NAME}Config.cmake.in
${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
# install cmake project config files
install(FILES ${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}/)
###################################################################################################然后运行以下bash脚本
#!/bin/bash
INSTALL_DIR=$PWD/install
mkdir -p ${INSTALL_DIR}
pushd lib1
mkdir -p build
pushd build
cmake .. -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}/lib1 -DCMAKE_BUILD_TYPE=Release
make install
popd
popd
pushd lib2
mkdir -p build
pushd build
cmake .. -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}/lib2 -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=${INSTALL_DIR}
make install
popd
popd我注意到,如果在find_package调用CMakeLists.txt for lib2中使用“CMakeLists.txt”,则会得到以下错误
在CMakeLists.txt:29 (find_package)::CMakeLists.txt:29中出错,但是它将lib1_FOUND设置为FALSE,因此包"lib1“被认为找不到。
同时使用"LIB1“可以成功编译。有人知道这是为什么吗?
更新04/21/2022
lib1Config.cmake.in含量
@PACKAGE_INIT@
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
check_required_components("@PROJECT_NAME@")lib1Config.cmake含量
####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
####### Any changes to this file will be overwritten by the next CMake run ####
####### The input file was lib1Config.cmake.in ########
get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
macro(set_and_check _var _file)
set(${_var} "${_file}")
if(NOT EXISTS "${_file}")
message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
endif()
endmacro()
macro(check_required_components _NAME)
foreach(comp ${${_NAME}_FIND_COMPONENTS})
if(NOT ${_NAME}_${comp}_FOUND)
if(${_NAME}_FIND_REQUIRED_${comp})
set(${_NAME}_FOUND FALSE)
endif()
endif()
endforeach()
endmacro()
####################################################################################
include("${CMAKE_CURRENT_LIST_DIR}/lib1Targets.cmake")
check_required_components("lib1")lib1Targets.cmake含量
# Generated by CMake
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.5)
message(FATAL_ERROR "CMake >= 2.6.0 required")
endif()
cmake_policy(PUSH)
cmake_policy(VERSION 2.6...3.19)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Protect against multiple inclusion, which would fail when already imported targets are added once more.
set(_targetsDefined)
set(_targetsNotDefined)
set(_expectedTargets)
foreach(_expectedTarget lib1::lib1_static lib1::lib1_shared)
list(APPEND _expectedTargets ${_expectedTarget})
if(NOT TARGET ${_expectedTarget})
list(APPEND _targetsNotDefined ${_expectedTarget})
endif()
if(TARGET ${_expectedTarget})
list(APPEND _targetsDefined ${_expectedTarget})
endif()
endforeach()
if("${_targetsDefined}" STREQUAL "${_expectedTargets}")
unset(_targetsDefined)
unset(_targetsNotDefined)
unset(_expectedTargets)
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
return()
endif()
if(NOT "${_targetsDefined}" STREQUAL "")
message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n")
endif()
unset(_targetsDefined)
unset(_targetsNotDefined)
unset(_expectedTargets)
# 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)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
if(_IMPORT_PREFIX STREQUAL "/")
set(_IMPORT_PREFIX "")
endif()
# Create imported target lib1::lib1_static
add_library(lib1::lib1_static STATIC IMPORTED)
set_target_properties(lib1::lib1_static PROPERTIES
INTERFACE_COMPILE_FEATURES "cxx_std_11"
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include;${_IMPORT_PREFIX}/include"
)
# Create imported target lib1::lib1_shared
add_library(lib1::lib1_shared SHARED IMPORTED)
set_target_properties(lib1::lib1_shared PROPERTIES
INTERFACE_COMPILE_FEATURES "cxx_std_11"
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include;${_IMPORT_PREFIX}/include"
)
# Load information for each installed configuration.
get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
file(GLOB CONFIG_FILES "${_DIR}/lib1Targets-*.cmake")
foreach(f ${CONFIG_FILES})
include(${f})
endforeach()
# Cleanup temporary variables.
set(_IMPORT_PREFIX)
# Loop over all imported files and verify that they actually exist
foreach(target ${_IMPORT_CHECK_TARGETS} )
foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )
if(NOT EXISTS "${file}" )
message(FATAL_ERROR "The imported target \"${target}\" references the file
\"${file}\"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
\"${CMAKE_CURRENT_LIST_FILE}\"
but not all the files it references.
")
endif()
endforeach()
unset(_IMPORT_CHECK_FILES_FOR_${target})
endforeach()
unset(_IMPORT_CHECK_TARGETS)
# This file does not depend on other imported targets which have
# been exported from the same project but in a separate export set.
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)Lib1TargetRelase.cmake的含量
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Release".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Import target "lib1::lib1_static" for configuration "Release"
set_property(TARGET lib1::lib1_static APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(lib1::lib1_static PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/liblib1_static.a"
)
list(APPEND _IMPORT_CHECK_TARGETS lib1::lib1_static )
list(APPEND _IMPORT_CHECK_FILES_FOR_lib1::lib1_static "${_IMPORT_PREFIX}/lib/liblib1_static.a" )
# Import target "lib1::lib1_shared" for configuration "Release"
set_property(TARGET lib1::lib1_shared APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(lib1::lib1_shared PROPERTIES
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/liblib1_shared.dylib"
IMPORTED_SONAME_RELEASE "@rpath/liblib1_shared.dylib"
)
list(APPEND _IMPORT_CHECK_TARGETS lib1::lib1_shared )
list(APPEND _IMPORT_CHECK_FILES_FOR_lib1::lib1_shared "${_IMPORT_PREFIX}/lib/liblib1_shared.dylib" )
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)发布于 2022-04-21 14:13:03
发出错误消息是因为尚未找到所有组件。查看一下find_package调用:
find_package(lib1 CONFIG REQUIRED
COMPONENTS lib1)它请求lib1 component,但是您的配置脚本(lib1Config.cmake)不处理它。宏调用
check_required_components("@PROJECT_NAME@")检测到此情况,并报告未找到整个包。
您的包可以通过调用成功地找到。
find_package(lib1 CONFIG REQUIRED)注意,包组件的支持是可选的。如果你想这样做,那么遵循相应的指南。例如与CMake一起提供的。
https://stackoverflow.com/questions/71932523
复制相似问题