CMake嵌套库安装后外部项目链接失败及INTERFACE用法咨询
CROSP库外部引用链接错误及INTERFACE命名空间配置需求
我开发了名为CROSP的项目,包含StrainParameterisation、RodProperties、PolynomialRepresentation三个内部库,这些库均链接至基础库CROSP并安装到/usr/local/目录。但在外部项目中引用CROSP时,编译器提示找不到内部库的.so文件,出现未定义引用等链接错误。
项目结构
. ├── cmake │ ├── cmake_uninstall.cmake.in │ ├── Config.cmake.in │ └── installation_module.cmake ├── CMakeLists.txt └── src ├── CMakeLists.txt ├── CROSP │ └── cosserat_rod.cpp ├── include │ └── CROSP │ ├── CROSP │ │ └── cosserat_rod.hpp │ ├── polynomial_representation │ │ └── polynomial_representation.hpp │ ├── rod_properties │ │ └── rod_properties.hpp │ └── strain_parameterisation │ └── strain_parameterisation.hpp ├── polynomial_representation │ └── polynomial_representation.cpp ├── rod_properties │ └── rod_properties.cpp └── strain_parameterisation └── strain_parameterisation.cpp
顶层CMakeLists.txt
cmake_minimum_required(VERSION 3.22 FATAL_ERROR) project(CROSP LANGUAGES CXX VERSION 2.0) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED True) find_package(Eigen3 3.4 NO_MODULE REQUIRED) # External utilities to configure the package include(GNUInstallDirs) set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}) set(LIB_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}) # Give different names for debug and Release set(CMAKE_RELEASE_POSTFIX "") set(CMAKE_DEBUG_POSTFIX "-debug") add_subdirectory(src) # Install the library using the default routine include(cmake/installation_module.cmake)
installation_module.cmake
# Generates ${PROJECT_NAME}Config.cmake file to use our package in other projects include(CMakePackageConfigHelpers) configure_package_config_file( cmake/Config.cmake.in # input template ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake # output config file INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake # where to put the config file during install PATH_VARS INCLUDE_INSTALL_DIR LIB_INSTALL_DIR # paths to be used NO_CHECK_REQUIRED_COMPONENTS_MACRO ) # Generates a config file to ensure that URL's version is checked when importing it write_basic_package_version_file( ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion ) # When running make install, config files should be copied as well install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake ) # Add the possibility tu run 'make uninstall' to remove files added via 'make install' configure_file( cmake/cmake_uninstall.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake IMMEDIATE @ONLY ) add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
Config.cmake.in
@PACKAGE_INIT@ set(@PROJECT_NAME@_VERSION @PROJECT_VERSION@) set_and_check(@PROJECT_NAME@_INCLUDE_DIRS @PACKAGE_INCLUDE_INSTALL_DIR@/@PROJECT_NAME@) set_and_check(@PROJECT_NAME@_LIBRARY_DIR @PACKAGE_LIB_INSTALL_DIR@) find_library(@PROJECT_NAME@_LIBRARIES NAMES @PROJECT_NAME@ PATHS ${@PROJECT_NAME@_LIBRARY_DIR} NO_DEFAULT_PATH) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(@PROJECT_NAME@ DEFAULT_MSG @PROJECT_NAME@_INCLUDE_DIRS @PROJECT_NAME@_LIBRARIES)
src目录下CMakeLists.txt
include_directories(include) add_library(PolynomialRepresentation SHARED include/${PROJECT_NAME}/polynomial_representation/polynomial_representation.hpp polynomial_representation/polynomial_representation.cpp ) target_link_libraries(PolynomialRepresentation PRIVATE Eigen3::Eigen ) target_compile_options(PolynomialRepresentation PRIVATE -Wall -Wextra ) add_library(RodProperties SHARED include/${PROJECT_NAME}/rod_properties/rod_properties.hpp rod_properties/rod_properties.cpp ) target_link_libraries(RodProperties PRIVATE Eigen3::Eigen PolynomialRepresentation ) target_compile_options(RodProperties PRIVATE -Wall -Wextra ) add_library(StrainParameterisation SHARED include/${PROJECT_NAME}/strain_parameterisation/strain_parameterisation.hpp strain_parameterisation/strain_parameterisation.cpp ) target_link_libraries(StrainParameterisation PRIVATE Eigen3::Eigen PolynomialRepresentation ) target_compile_options(RodProperties PRIVATE -Wall -Wextra ) add_library(${PROJECT_NAME} SHARED include/${PROJECT_NAME}/${PROJECT_NAME}/cosserat_rod.hpp ${PROJECT_NAME}/cosserat_rod.cpp ) target_link_libraries(${PROJECT_NAME} PRIVATE Eigen3::Eigen PUBLIC StrainParameterisation RodProperties PolynomialRepresentation ) target_compile_options(RodProperties PRIVATE -Werror -Wall -Wextra ) add_executable(main main.cpp) target_link_libraries(main ${PROJECT_NAME} Eigen3::Eigen) install( TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} ) install(DIRECTORY include/${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} )
外部项目配置示例
CMakeLists.txt
cmake_minimum_required(VERSION 3.5) project(test_crosp_library LANGUAGES CXX) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(CROSP REQUIRED) find_package(Eigen3 3.4 NO_MODULE REQUIRED) add_executable(test_crosp_library main.cpp) target_link_libraries(test_crosp_library PUBLIC CROSP Eigen3::Eigen )
main.cpp
#include "CROSP/CROSP/cosserat_rod.hpp" int main() { ::CROSP::CosseratRod rod; // errors return 0; }
错误信息
[ 50%] Linking CXX executable test_crosp_library /usr/bin/ld: warning: libStrainParameterisation.so, needed by /usr/local/lib/libCROSP.so, not found (try using -rpath or -rpath-link) /usr/bin/ld: warning: libRodProperties.so, needed by /usr/local/lib/libCROSP.so, not found (try using -rpath or -rpath-link) /usr/bin/ld: /usr/local/lib/libCROSP.so: undefined reference to `LieAlgebra::SE3Pose::getRotationMatrix() const' /usr/bin/ld: /usr/local/lib/libCROSP.so: undefined reference to `CROSP::strain_parameterisation::StrainParameterisation::StrainParameterisation(CROSP::polynomial_representation::PolynomialRepresentation, unsigned int)' /usr/bin/ld: /usr/local/lib/libCROSP.so: undefined reference to `CROSP::strain_parameterisation::StrainParameterisation::StrainParameterisation(CROSP::polynomial_representation::PolynomialRepresentation, Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, unsigned int)' /usr/bin/ld: /usr/local/lib/libCROSP.so: undefined reference to `CROSP::rod_properties::RodProperties::RodProperties(CROSP::polynomial_representation::PolynomialRepresentation)' /usr/bin/ld: /usr/local/lib/libCROSP.so: undefined reference to `CROSP::strain_parameterisation::StrainParameterisation::updateStacks(Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, Eigen::Matrix<double, -1, 1, 0, -1, 1> const&)' collect2: error: ld returned 1 exit status make[2]: *** [CMakeFiles/test_crosp_library.dir/build.make:97: test_crosp_library] Error 1 make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/test_crosp_library.dir/all] Error 2 make: *** [Makefile:91: test_crosp_library] Error 2
额外咨询
能否通过INTERFACE功能将内部库以命名空间形式安装,使外部项目可按如下方式引用内部库:
find_package(CROSP REQUIRED) add_executable(main main.cpp) target_link_libraries(main CROSP::MaterialProperties CROSP::StrainParameterisation )
内容的提问来源于stack exchange,提问作者Andrea Gotelli
相关产品推荐
相关产品推荐

