我正在尝试按照给定的答案 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
按照建议运行 ranlib,无论是 stock one 还是 x86_64-w64-mingw32-gcc-ranlib 都没有区别。
我花了 15 分钟用 MSVC 和 lib.exe 来完成这项工作,并在 MinGW 上苦苦挣扎了 8 个小时。任何建议将不胜感激。
[编辑]:原来这个问题并不是 MinGW 特有的,它也以非常相似的方式发生在 Linux 上。
最佳答案
事实证明,使用 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()
关于c++ - 合并静态库时 ar 命令不产生索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54249128/