【问题标题】:ar command does not produce index when combining static libraries合并静态库时 ar 命令不生成索引
【发布时间】:2019-01-18 07:02:14
【问题描述】:

我正在尝试按照here 给出的答案将多个静态库合并到 MinGW64 下的单个存档中。具体来说,我使用 CMake 并指定以下命令:

    add_custom_command(
        OUTPUT ${COMBINED_CORE_LIB_NAME}
        COMMAND ${AR} -crs ${COMBINED_CORE_LIB_NAME} ${CORE_LIB_TARGET_FILES}
        DEPENDS ${DILIGENT_CORE_INSTALL_LIBS_LIST}
        COMMENT "Combining core libraries..."
    )

另外,根据here的推荐,我不使用stock ar,而是cross ar:

find_program(AR NAMES x86_64-w64-mingw32-gcc-ar)

但是,无论我做什么,ar 都拒绝生成索引,并且每次我尝试链接生成的库时,都会收到此错误:

error adding symbols: Archive has no index; run ranlib to add one

按照 stock one 或 x86_64-w64-mingw32-gcc-ranlib 的建议运行 ranlib 没有区别。

我花了 15 分钟来使用 MSVC 和 lib.exe 完成这项工作,并且已经在 MinGW 上苦苦挣扎了 8 个小时。任何建议将不胜感激。

[编辑]:事实证明,这个问题并不是 MinGW 所特有的,而且在 Linux 上也以非常相似的方式发生。

【问题讨论】:

  • 合并档案后,您必须运行ranlib 来创建索引。您应该在自定义命令中有另一个步骤,例如 COMMAND ${RANLIB} ${COMBINED_CORE_LIB_NAME}。 (我遇到过similar problem on Android)。
  • 正如我在问题中提到的,运行 ranlib 无论是 stock one 还是 x86_64-w64-mingw32-gcc-ranlib 都没有区别。还有 s 选项应该使 ar 生成索引。
  • 好吧,我通常使用ranlib 作为单独的步骤。也许您需要构建存档COMMAND ${AR} cr ${COMBINED_CORE_LIB_NAME},然后使用COMMAND ${AR} s ${COMBINED_CORE_LIB_NAME} 作为单独的步骤构建索引。
  • MinGW 声音坏了。提交错误报告并要求解决。 (我像瘟疫一样避免 MinGW。这不过是问题)。
  • @jww 不能再同意了,但出于某种原因,我图书馆的很多用户更喜欢 MinGW,所以我正在努力支持它。

标签: c++ c cmake static-libraries unix-ar


【解决方案1】:

事实证明,使用 ar 实用程序无法将多个 .a 文件合并到一个 .a 库中:它拒绝生成索引。一个可行的解决方案是从所有静态库中解压缩所有目标文件,然后将它们重新打包到一个组合库中。

以下是我最终得到的 CMake 说明:

set(COMBINED_CORE_LIB_NAME "${CMAKE_STATIC_LIBRARY_PREFIX}DiligentCore${CMAKE_STATIC_LIBRARY_SUFFIX}")

foreach(CORE_LIB ${DILIGENT_CORE_INSTALL_LIBS_LIST})
    list(APPEND CORE_LIB_TARGET_FILES $<TARGET_FILE:${CORE_LIB}>)
endforeach(CORE_LIB)

if(MSVC)
    add_custom_command(
        OUTPUT ${COMBINED_CORE_LIB_NAME}
        COMMAND ${LIB_EXE} /OUT:${COMBINED_CORE_LIB_NAME} ${CORE_LIB_TARGET_FILES}
        DEPENDS ${DILIGENT_CORE_INSTALL_LIBS_LIST}
        COMMENT "Combining core libraries..."
    )
    add_custom_target(DiligentCore-static ALL DEPENDS ${COMBINED_CORE_LIB_NAME})
else()

    if(PLATFORM_WIN32)
        # do NOT use stock ar on MinGW
        find_program(AR NAMES x86_64-w64-mingw32-gcc-ar)
    else()
        set(AR ${CMAKE_AR})
    endif()

    if(AR)
        add_custom_command(
            OUTPUT ${COMBINED_CORE_LIB_NAME}
            # Delete all object files from current directory
            COMMAND ${CMAKE_COMMAND} -E remove "*${CMAKE_C_OUTPUT_EXTENSION}"
            DEPENDS ${DILIGENT_CORE_INSTALL_LIBS_LIST}
            COMMENT "Combining core libraries..."
        )

        # Unpack all object files from all targets to current directory
        foreach(CORE_LIB_TARGET ${CORE_LIB_TARGET_FILES})
            add_custom_command(
                OUTPUT ${COMBINED_CORE_LIB_NAME}
                COMMAND ${AR} -x ${CORE_LIB_TARGET}
                APPEND
            )
        endforeach()

        # Pack object files to a combined library and delete them
        add_custom_command(
            OUTPUT ${COMBINED_CORE_LIB_NAME}
            COMMAND ${AR} -crs ${COMBINED_CORE_LIB_NAME} "*${CMAKE_C_OUTPUT_EXTENSION}"
            COMMAND ${CMAKE_COMMAND} -E remove "*${CMAKE_C_OUTPUT_EXTENSION}"
            APPEND
        )

        add_custom_target(DiligentCore-static ALL DEPENDS ${COMBINED_CORE_LIB_NAME})
    else()
        message("ar command is not found")
    endif()
endif()

if(TARGET DiligentCore-static)
    install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${COMBINED_CORE_LIB_NAME}"
            DESTINATION "${DILIGENT_CORE_INSTALL_DIR}/lib/"
    )
    set_target_properties(DiligentCore-static PROPERTIES
        FOLDER Core
    )
else()
    message("Unable to find librarian tool. Combined DiligentCore static library will not be produced.")
endif()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-27
    • 2016-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-18
    • 2012-07-24
    相关资源
    最近更新 更多