CMake:导入的库作为另一个自定义命令或目标的输出或副产品
CMake: Imported libraries as OUTPUT or BYPRODUCTS of another custom command or target
我想从 ZIP 文件中提取静态库并link 反对它。
具有以下设置:
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
问题是您的自定义命令正在 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(在 make 端执行):
# 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
目标)识别存档格式、解压缩,如果需要 - 配置、构建和安装。
我想从 ZIP 文件中提取静态库并link 反对它。
具有以下设置:
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
问题是您的自定义命令正在 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(在 make 端执行):
# 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
目标)识别存档格式、解压缩,如果需要 - 配置、构建和安装。