cmake - CMake:正确安装多个构建工件
问题描述
我ADD_CUSTOM_TARGET
用来构建生成数十个静态库的 make 项目。然后我想install
正确地让其他项目能够使用这些构建结果。我到底应该怎么做?
据我了解,我必须为每个库创建目标,然后创建mylib-config.cmake
引用这些目标。在看了这里和那里之后,我想出了这样的东西
#... here comes ADD_CUSTOM_TARGET to build my Makefile project...
FILE(WRITE "share/dpdk-config.cmake" "include(CMakeFindDependencyMacro)\n")
FILE(GLOB LIBS ${CMAKE_SOURCE_DIR}/build/lib/*.a)
FOREACH (LIB_FILE_NAME ${LIBS})
GET_FILENAME_COMPONENT(LIB_NAME ${LIB_FILE_NAME} NAME_WE)
SET(TARGET_NAME ${LIB_NAME}_target)
ADD_CUSTOM_TARGET(${TARGET_NAME} DEPENDS ${LIB})
ADD_LIBRARY(${LIB_NAME} STATIC IMPORTED GLOBAL)
ADD_DEPENDENCIES(${LIB_NAME} ${TARGET_NAME})
SET_TARGET_PROPERTIES(${LIB_NAME}
PROPERTIES
IMPORTED_LOCATION ${LIB_FILE_NAME}
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/${CMAKE_BUILD_TYPE}/include
)
INSTALL(TARGETS ${LIB_NAME}
EXPORT ${TARGET_NAME}
ARCHIVE DESTINATION ${CMAKE_SOURCE_DIR}/build/lib
)
INSTALL(
EXPORT ${TARGET_NAME}
DESTINATION share/dpdk
)
FILE(APPEND "share/dpdk-config.cmake" "include(share/dpdk/${TARGET_NAME}.cmake)\n")
# MESSAGE(STATUS "Library file: ${LIB_FILE_NAME}")
# MESSAGE(STATUS "Library: ${LIB_NAME}")
# MESSAGE(STATUS "Library target: ${TARGET_NAME}")
ENDFOREACH ()
INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/build/lib
DESTINATION ${CMAKE_SOURCE_DIR}/${CMAKE_BUILD_TYPE}/)
INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/build/include
DESTINATION ${CMAKE_SOURCE_DIR}/${CMAKE_BUILD_TYPE}/)
首先,我不确定这是正确的方法,其次,它不起作用。任何帮助将不胜感激
编辑:好的,这种方法不起作用,因为无法导出导入的库。请参阅CMake 问题 #14311
解决方案
好吧,实际上我的赌注已经足够接近了。INSTALL
将不起作用,但您可以使用它ConfigXXX.cmake
来收集所有必要的信息、创建导出的库、添加必要的属性和瞧。例如,可以拿起英特尔的 TBB,它有类似的问题,他们通过上述方法解决了。我只是根据他们的脚本创建了一个函数
FUNCTION(SET_LIBRARY_TARGET LIB_FILE_NAME INCLUDE_DIR ISDEBUG)
SET(POSTFIX "_release")
IF (${ISDEBUG})
SET(POSTFIX "_debug")
ENDIF ()
GET_FILENAME_COMPONENT(LIB_NAME ${LIB_FILE_NAME} NAME_WE)
STRING(REPLACE "librte_" "" LIB_NAME "${LIB_NAME}")
STRING(REPLACE "libdpdk" "dpdk" LIB_NAME "${LIB_NAME}")
STRING(APPEND LIB_NAME "${POSTFIX}")
ADD_LIBRARY(DPDK::${LIB_NAME} STATIC IMPORTED)
SET_TARGET_PROPERTIES(DPDK::${LIB_NAME} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${INCLUDE_DIR}")
IF (${ISDEBUG})
SET_PROPERTY(TARGET DPDK::${LIB_NAME} APPEND PROPERTY IMPORTED_LOCATION_DEBUG "${LIB_FILE_NAME}")
SET_PROPERTY(TARGET DPDK::${LIB_NAME} APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
ELSE ()
SET_PROPERTY(TARGET DPDK::${LIB_NAME} APPEND PROPERTY IMPORTED_LOCATION_RELEASE "${LIB_FILE_NAME}")
SET_PROPERTY(TARGET DPDK::${LIB_NAME} APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
ENDIF ()
SET(DPDK_${LIB_NAME}_FOUND 1)
ENDFUNCTION()
我想它可以比这更优雅,做我的客人来改进它
EDIT001:更干净紧凑的版本
FUNCTION(SET_LIBRARY_TARGET NAMESPACE LIB_NAME DEBUG_LIB_FILE_NAME RELEASE_LIB_FILE_NAME INCLUDE_DIR)
ADD_LIBRARY(${NAMESPACE}::${LIB_NAME} STATIC IMPORTED)
SET_TARGET_PROPERTIES(${NAMESPACE}::${LIB_NAME} PROPERTIES
IMPORTED_CONFIGURATIONS "RELEASE;DEBUG"
IMPORTED_LOCATION_RELEASE "${RELEASE_LIB_FILE_NAME}"
IMPORTED_LOCATION_DEBUG "${DEBUG_LIB_FILE_NAME}"
INTERFACE_INCLUDE_DIRECTORIES "${INCLUDE_DIR}"
)
SET(${NAMESPACE}_${LIB_NAME}_FOUND 1)
ENDFUNCTION()
推荐阅读
- node.js - 如何在快递上使用passport-jwt策略来保护邮政路线
- ios - 如何在 TableView 中的 textView 上调用 didChange
- unity3d - 2d 像素艺术游戏的分辨率
- angular - 独立一次性 Angular 应用程序的持久存储选项
- ruby-on-rails - Rails - 设计 - 禁用重置密码令牌到期时间
- python - x[:1] 和 x[0] 之间的区别
- r - knitr 在 /static/ 文件夹中找不到 img 文件
- github - 如何在 github 的 CODEOWNER 中包含一个 github 应用程序
- css - 我怎样才能居中
在 Angular 9 的屏幕中间 - google-chrome - 在 chrome 版本 > 80 中关闭相同站点强制