CMAKE编译时如何自动下载第三方库并解压、安装到指定目录

2022-04-18 16:10:00 浏览数 (2)

导语

在日常开发过程中难免会使用到第三方库或者需要将部分库分离另外存储,如果将库与代码放在一起难免会造成工程庞大,此时就可以采用将库与源码分离的方式,在编译时根据情况来判断是否需要下载。

步骤

下面来解析下具体操作步骤,以下以 oracle oci 库下载为例。

UNSET命令初始化本次编译用到的参数变量

代码语言:javascript复制
   #初始化oci库压缩包路径参数LOCAL_OCI_LIB_ZIP

   UNSET(LOCAL_OCI_LIB_ZIP CACHE)

   #初始化oci库解压路径参数LOCAL_OCI_LIB_DIR

​    UNSET(LOCAL_OCI_LIB_DIR CACHE)

​    #初始化oci库压缩包下载路径参数LOCAL_OCI_LIB_ZIP_DL_DIR

​    UNSET(LOCAL_OCI_LIB_ZIP_DL_DIR CACHE)

SET命令设置参数初始路径或名称

代码语言:javascript复制
   #设置oci库存放文件夹名称

   SET(OCI_LIB_NAME "oci_x86_lib")

​    # 设置oci库压缩包解压文件夹名称

​    SET(OCI_LIB_UNZIP_DIR_NAME ${OCI_LIB_NAME})

​    #设置oci库头文件存放文件夹名称

​    SET(LOCAL_OCI_INCLUDE_DIR_NAME "oci_include")

​    #设置oci库压缩包名称

​    SET(OCI_LIB_ZIP_NAME "oci_lib.tar.gz")

​    #设置oci库远程下载地址URL

​    SET(OCI_LIB_DOWNLOAD_URL "http://xxxxxx/oci_lib.tar.gz")

​    #设置oci库远程下载超时时间

​    SET(DOWNLOAD_OCI_LIB_TIMEOUT 600 CACHE STRING "Timeout in seconds when downloading oci_lib.")

FIND_FILE命令在路径下查找对应名称文件或文件夹是否存在,判断库是否已经下载或解压

代码语言:javascript复制
​    #判断压缩包在文件夹ora_oci_lib下是否已经存在

​         FIND_FILE(LOCAL_OCI_LIB_ZIP

​              NAMES ${OCI_LIB_ZIP_NAME}

​              PATHS "ora_oci_lib"

​              NO_DEFAULT_PATH

​            )

​       #判断压缩包在文件夹ora_oci_lib下是否已经解压

​        FIND_FILE(LOCAL_OCI_LIB_DIR

​              NAMES ${OCI_LIB_NAME}

​              PATHS "ora_oci_lib"

​              NO_DEFAULT_PATH

​            )

​       #判断压缩包下载路径

​       FIND_FILE(LOCAL_OCI_LIB_ZIP_DL_DIR

​              NAMES ""

​              PATHS "ora_oci_lib"

​              NO_DEFAULT_PATH

​            )

MESSAGE命令输出相应步骤的提示信息

代码语言:javascript复制
​     #输出当前正进行的操作步骤信息

​     MESSAGE(STATUS "Checking dblink ${OCI_LIB_UNZIP_DIR_NAME}   ${LOCAL_OCI_LIB_ZIP} .....")

判断当前压缩包是否存在,如果不存在则开始根据设定的URL地址进行下载

代码语言:javascript复制
​     #判断压缩包是否已经存在

​      IF(NOT LOCAL_OCI_LIB_ZIP)

​           #不存在则进行下载操作,输出操作提示信息

​            MESSAGE(STATUS "Downloading ${OCI_LIB_ZIP_NAME} to ${LOCAL_OCI_LIB_ZIP_DL_DIR}")

​           #从设定URL地址下载相应的压缩包

​            FILE(DOWNLOAD ${OCI_LIB_DOWNLOAD_URL}

​            ${LOCAL_OCI_LIB_ZIP_DL_DIR}/${OCI_LIB_ZIP_NAME}

​            TIMEOUT ${DOWNLOAD_OCI_LIB_TIMEOUT}

​            STATUS ERR

​            SHOW_PROGRESS 

​             )

​       #判断下载是否存在错误

​       IF(ERR EQUAL 0)

​          #如果下载无错误则设置压缩包名称标记下载成功

​           SET(LOCAL_OCI_LIB_ZIP "${LOCAL_OCI_LIB_ZIP_DL_DIR}/${OCI_LIB_ZIP_NAME}")

​        ELSE()

​            #下载错误输出相关的提示信息

​            MESSAGE(STATUS "Download failed, error: ${ERR}")

​            MESSAGE(FATAL_ERROR

​              "You can try downloading ${OCI_LIB_DOWNLOAD_URL} manually"

​                " using curl/wget or a similar tool"

​            )

​           ENDIF()

​        ENDIF()

根据设定标记判断是否下载成功,如果下载成功则对压缩包文件进行初步的校验,无问题则进行解压缩操作

代码语言:javascript复制
​        IF(LOCAL_OCI_LIB_ZIP )

​            #输出相应的提示信息校验解压路径等

​             MESSAGE(STATUS "Checking dblink ${OCI_LIB_UNZIP_DIR_NAME}   ${LOCAL_OCI_INCLUDE_DIR_NAME}   ${LOCAL_OTL_INCLUDE_DIR_NAME} ")

​             IF(NOT EXISTS "${LOCAL_OCI_LIB_ZIP_DL_DIR}/${OCI_LIB_UNZIP_DIR_NAME}" OR NOT EXISTS               "${LOCAL_OCI_LIB_ZIP_DL_DIR}/${LOCAL_OCI_INCLUDE_DIR_NAME}" OR NOT EXISTS       "${LOCAL_OCI_LIB_ZIP_DL_DIR}/${LOCAL_OTL_INCLUDE_DIR_NAME}" )

​            #输出提示信息准备进行解压缩

​            MESSAGE(STATUS "cd ${LOCAL_OCI_LIB_ZIP_DL_DIR}; tar xfz ${LOCAL_OCI_LIB_ZIP}")

​            #获取已下载的压缩包大小做基本的判断

​            GET_FILE_SIZE(${LOCAL_OCI_LIB_ZIP} LOCAL_ZIP_SIZE)

​            #如果压缩包大小为0则输出对应的错误信息

​            IF(LOCAL_ZIP_SIZE EQUAL 0)

​                  #移除损坏压缩包,重置相应的参数

​                FILE(REMOVE ${LOCAL_OCI_LIB_ZIP})

​                 UNSET(LOCAL_OCI_LIB_ZIP)

​                UNSET(LOCAL_OCI_LIB_ZIP CACHE)

​                MESSAGE(FATAL_ERROR  "${OCI_LIB_ZIP_NAME} is zero length. Deleting it.")

​              ELSE()

​               #下载文件基本无问题,进入解压路径开始解压压缩包

​                 EXECUTE_PROCESS(

​                  COMMAND ${CMAKE_COMMAND} -E tar xfz "${LOCAL_OCI_LIB_ZIP}"

​                   WORKING_DIRECTORY "${LOCAL_OCI_LIB_ZIP_DL_DIR}"

​                  RESULT_VARIABLE tar_result

​                   )

​               #判断解压是否成功

​             IF (tar_result MATCHES 0)

​                 #解压成功设置成功标记参数

​                  SET(OCI_LIB_FOUND 1 CACHE INTERNAL "")

​             ELSE()

​                 #解压失败输出相应错误提示信息

​                MESSAGE(STATUS "Failed to extract files.n"

​                  "   Please try downloading and extracting yourself.n"

​                 "   The url is: ${OCI_LIB_DOWNLOAD_URL}")

​             ENDIF()

​        ENDIF()

​       ENDIF()

​      ENDIF()        

至此第三方库已经下载解压完成,后续可以根据自己源码,设置对应的链接路径进行编译

代码语言:javascript复制
​      INCLUDE_DIRECTORIES 命令可以设置引用头文件包括路径

​     LINK_DIRECTORIES 命令可以设置引用第三方库文件所在路径

编译完成后可以使用INSTALL命令将后续应用运行时需要使用的库,拷贝到指定的安装目录

代码语言:javascript复制
   CMAKE_INSTALL_PREFIX 为设置的安装路径

   OCI_LIB_NAME为库放置文件夹

​     # copy  lib 

​     INSTALL(

​       FILES ${allCopyFiles}  DESTINATION ${CMAKE_INSTALL_PREFIX}/${OCI_LIB_NAME}

​     )

0 人点赞