Команда ar не создает индекс при объединении статических библиотек - PullRequest
0 голосов
/ 18 января 2019

Я пытаюсь следовать ответу, данному здесь , чтобы объединить несколько статических библиотек в один архив под 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..."
    )

Также, следуя рекомендациям здесь , я не использую фондовую ар, а скорее перекрестную ар:

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

Однако, что бы я ни делал, ar отказывается генерировать индекс, и каждый раз, когда я пытаюсь скомпоновать созданную библиотеку, я получаю эту ошибку:

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

Запуск ranlib в соответствии с рекомендациями: либо один из них, либо x86_64-w64-mingw32-gcc-ranlib не имеет значения.

Я потратил 15 минут, чтобы заставить это работать с MSVC и lib.exe, и 8 часов боролся с MinGW. Любое предложение будет высоко оценено.

[Редактировать]: Оказалось, что эта проблема на самом деле не специфична для MinGW и также очень похожа на Linux.

1 Ответ

0 голосов
/ 19 января 2019

Как оказалось, невозможно объединить несколько файлов .a в одну библиотеку .a с помощью утилиты ar: она отказывается генерировать индекс. Рабочее решение - распаковать все объектные файлы из всех статических библиотек и затем упаковать их в объединенную библиотеку.

Ниже приведены инструкции 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()
...