CMake:正确安装多个构建工件

时间:2019-02-16 18:35:35

标签: 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 issue #14311

1 个答案:

答案 0 :(得分:0)

好吧,实际上我的赌注已经足够接近了。 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()