我想从ZIP文件中提取静态库并链接到它。
具有以下设置:
add_library(COMSDK_LIB STATIC IMPORTED GLOBAL)
set_property(TARGET COMSDK_LIB PROPERTY IMPORTED_LOCATION "/tmp/lib/libRTSClientSdk.a")
导入的库在另一个CMakeLists.txt
中使用:
target_link_libraries(mylib COMSDK_LIB)
导入的库是否可能由其他add_custom_command
或add_custom_target
生成?
我尝试了以下操作,但确实不工作:
add_custom_command(
OUTPUT "/tmp/lib/libRTSClientSdk.a"
COMMAND unzip -x client_sdk.zip -o /tmp
DEPENDS client_sdk.zip
)
给出的错误消息是:
$ ninja
ninja: error: '/tmp/lib/libRTSClientSdk.a', needed by 'mylib.dll', missing and no known rule to make it
答案 0 :(得分:1)
问题在于您的自定义命令正在make
步骤中执行,并且它期望在cmake
执行期间更早地提取依赖关系。所以,基本上,你需要从SDK 获取静态库你在CMake规则中或在连接过程中使用它。
CMake mailing list中列出了两种可能的解决方案。
解决方案#1 :(在CMake端执行)
重新编写其中一个代码段,在CMake执行期间正在进行下载和解压缩:
set(CLIENTSDK_ZIP "cliendsdk.zip")
set(CLIENTSDK_URL "http://example.com/${CLIENTSDK_ZIP}")
set(CLIENTSDK_LIB "libRTSClientSdk.a")
set(CLIENTSDK_OUTPUT_DIR "/tmp/sdk/dir")
# Basically just downloading zip file:
message(STATUS "Downloading ${CLIENTSDK_URL}")
execute_process(COMMAND wget ${CLIENTSDK_URL}
WORKING_DIRECTORY ${CLIENTSDK_OUTPUT_DIR}
RESULT_VARIABLE errno
ERROR_VARIABLE err)
if (NOT ${errno} EQUAL 0)
message(ERROR "Failed downloading ${CLIENTSDK_URL}. Code: ${err}")
endif()
# Extracting downloaded zip file:
message(STATUS "Extracting ${CLIENTSDK_ZIP})
execute_process(COMMAND unzip ${CLIENTSDK_ZIP}
WORKING_DIRECTORY ${CLIENTSDK_OUTPUT_DIR}
RESULT_VARIABLE errno
ERROR_VARIABLE err)
if (NOT ${errno} EQUAL 0)
message(ERROR "Failed extracting ${CLIENTSDK_ZIP}. Code: ${err}")
endif()
# Importing into CMake scope one library from extracted zip:
add_library(specific_sdk_lib STATIC IMPORTED)
set_target_properties(specific_sdk_lib
PROPERTIES IMPORTED_LOCATION ${CLIENTSDK_OUTPUT_DIR}/lib/${CLIENTSDK_LIB})
# Adding rule for linking to specific static library from extracted zip:
target_link_libraries(mylib specific_sdk_lib)
解决方案#2 (在制作方执行):
# We must include ExternalProject CMake module first!
include("ExternalProject")
set(CLIENTSDK_URL "http://example.com/clientsdk.zip")
set(CLIENTSDK_LIB "libRTSClientSdk.a")
set(CLIENTSDK_PREFIX "3rd_party")
set(CLIENTSDK_EXTRACTED_DIR
"${CMAKE_CURRENT_BINARY_DIR}/${CLIENTSDK_PREFIX}/src/DownloadClientSDK/")
ExternalProject_Add("DownloadClientSDK"
PREFIX ${CLIENTSDK_PREFIX}
URL "${CLIENTSDK_URL}"
# Suppress ExternalProject configure/build/install targets:
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")
add_library(COMSDK_LIB STATIC IMPORTED)
set_target_properties(COMSDK_LIB PROPERTIES IMPORTED_LOCATION
${CLIENTSDK_EXTRACTED_DIR}/${CLIENTSDK_LIB})
# Require all that download/unzip mumbojumbo only for COMSDK_LIB:
add_dependencies(COMSDK_LIB DownloadClientSDK)
target_link_libraries(my_library COMSDK_LIB)
基本上,CMake
及其ExternalProject
模块负责(生成适当的make
目标)识别归档格式,解压缩,如果需要 - 配置,构建和安装。