• Cmake 实现debug和release lib依赖项处理


    一、说明

      最近用cmake开发东西,编译vs时候,发现debugrelease版本的lib库的依赖项问题,故此小结一下。若有不对之处,还请看官多多指教。 

    使用的工程有自己编写的工程,也有借用第三方库的工程,还有没有办法找到源码的,只有dlllib库,没有区分debugrelease 版本的。 

      所以还是分开说,一种自己工程库,一种是第三方库。在写完cmake代码,生成vs后,都可以自动的添加链接库,debugrelease版本泾渭分明。

    二、自己工程之间的引用

    先说,自己编写的工程,工程直接的相互调用,这个就不用多说了。Cmake还是要调用target_link_libraries来链接自己的想要链接的动态库。

    但是需用做些设置,就可以自动的区分debugrelease版本了。

    首先,需实现cmake定义如下:

    #这个就是定义各个版本对应的后缀,例如d,debug版本后缀,当然你想定义为其他,	#自己修改这块就可以了。
    SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "add a postfix, usually d on windows")
    SET(CMAKE_RELEASE_POSTFIX "" CACHE STRING "add a postfix, usually empty on windows")
    SET(CMAKE_RELWITHDEBINFO_POSTFIX "rd" CACHE STRING "add a postfix, usually empty on windows")
    SET(CMAKE_MINSIZEREL_POSTFIX "s" CACHE STRING "add a postfix, usually empty on windows")
     
    # Set the build postfix extension according to what configuration is being built.
    IF (CMAKE_BUILD_TYPE MATCHES "Release")
        SET(CMAKE_BUILD_POSTFIX "${CMAKE_RELEASE_POSTFIX}")
    ELSEIF (CMAKE_BUILD_TYPE MATCHES "MinSizeRel")
        SET(CMAKE_BUILD_POSTFIX "${CMAKE_MINSIZEREL_POSTFIX}")
    ELSEIF(CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo")
        SET(CMAKE_BUILD_POSTFIX "${CMAKE_RELWITHDEBINFO_POSTFIX}")
    ELSEIF(CMAKE_BUILD_TYPE MATCHES "Debug")
        SET(CMAKE_BUILD_POSTFIX "${CMAKE_DEBUG_POSTFIX}")
    ELSE()
        SET(CMAKE_BUILD_POSTFIX "")
    ENDIF()

    以上代码我们是在外层的CMakeLists.txt中实现的。

    接着下来cmake代码是在内层的cMakeLists.txt中实现。主要是使用外层定义的东西。 

    Cmake代码如下:

     # Set the library extension according to what configuration is being built.
    IF(CMAKE_DEBUG_POSTFIX)
        SET(CMAKE_CXX_FLAGS_DEBUG
           "${CMAKE_CXX_FLAGS_DEBUG} -DRW_LIBRARY_POSTFIX=${CMAKE_DEBUG_POSTFIX}")
    ENDIF()
    IF(CMAKE_RELEASE_POSTFIX)
    SET(CMAKE_CXX_FLAGS_RELEASE
           "${CMAKE_CXX_FLAGS_RELEASE} -DRW_LIBRARY_POSTFIX=${CMAKE_RELEASE_POSTFIX}")
    ENDIF()
    IF(CMAKE_RELWITHDEBINFO_POSTFIX)
        SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO
           "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DRW_LIBRARY_POSTFIX=${CMAKE_RELWITHDEBINFO_POSTFIX}")
    ENDIF()
    IF(CMAKE_MINSIZEREL_POSTFIX)
        SET(CMAKE_CXX_FLAGS_MINSIZEREL
           "${CMAKE_CXX_FLAGS_MINSIZEREL} -DRW_LIBRARY_POSTFIX=${CMAKE_MINSIZEREL_POSTFIX}")
    ENDIF()

    其中的RW_LIBRARY_POSTFIX是我们工程相关的名称,你们可以自己设置。在工程属性的出现,如下所示:

     

    三、第三方库

    关于第三方库,情况比较复杂。有源码的,没有源码的,静态的,动态的,只有release,没有debug的。我们现在做的是要求,至少有release版本的的lib库。如没有就不会添加到所需的工程的依赖项中。 

    因为第三方库,在项目组中,各自的工程各自知道需用什么第三方库,所以就写了一个cmake的宏定义来实现。

    下面是cmake原文代码:

    #link library for debug and release by yourself.
    MACRO(RW_LINK_LIBRARY BASE_LIBRARY_NAME DEBUGSUFFIX EXSUFFIX)
         set(DEBUG_LIB ${PROJECT_SOURCE_DIR}/${BASE_LIBRARY_NAME}${DEBUGSUFFIX})
         set(RELEASE_LIB ${PROJECT_SOURCE_DIR}/${BASE_LIBRARY_NAME}${EXSUFFIX})
         IF(EXISTS ${RELEASE_LIB})
    <span style="white-space:pre">	</span>target_link_libraries(${PROJECT_NAME} optimized  ${RELEASE_LIB})
    <span style="white-space:pre">	</span>IF(EXISTS ${DEBUG_LIB})
    <span style="white-space:pre">	</span>   target_link_libraries(${PROJECT_NAME}  debug ${DEBUG_LIB})
    <span style="white-space:pre">	</span>ELSE()
    <span style="white-space:pre">	</span>    target_link_libraries(${PROJECT_NAME}  debug ${RELEASE_LIB})
    <span style="white-space:pre">	</span>ENDIF(EXISTS ${DEBUG_LIB})
          ENDIF(EXISTS ${RELEASE_LIB})
    ENDMACRO()
     
    MACRO(RW_LINK_3RD_PART_LIBRARY FULL_LIBRARY_DEBUGNAME FULL_LIBRARY_RELEASENAME)
        IF(EXISTS ${FULL_LIBRARY_RELEASENAME})
            target_link_libraries(${PROJECT_NAME} optimized  ${FULL_LIBRARY_RELEASENAME})
            IF(NOT EXISTS ${FULL_LIBRARY_DEBUGNAME})
                target_link_libraries(${PROJECT_NAME} debug  ${FULL_LIBRARY_RELEASENAME})
            ELSE()
                 target_link_libraries(${PROJECT_NAME}  debug ${FULL_LIBRARY_DEBUGNAME})
            ENDIF(NOT EXISTS ${FULL_LIBRARY_DEBUGNAME})
        ENDIF(EXISTS ${FULL_LIBRARY_RELEASENAME})
    ENDMACRO()

    宏的使用方式为:

    第一个宏的使用在对应的工程下,lib库可以写相对路径。 

    RW_LINK_LIBRARY(free_image/FreeImage "d.lib" ".lib")

    第一个参数为含路径名称的lib库名称,后面分别为debugrelease版本的区分。

    此定义还不是很完善,以后可能修改为只添加不同的部分,比如:

          RW_LINK_LIBRARY(free_image/FreeImage "d" "") 内部自动来识别andriod iosmsvc等。

     

    第二个宏的用法为:

    RW_LINK_3RD_PART_LIBRARY(${GDAL_LIBRARY_DEBUG} ${GDAL_LIBRARY})

    其中里面写的是两个lib库的路径变量。

     

    两个宏定义的原则均为,当没有debug版本的lib库时候,使用release版本的lib库。

    ps:

    Cmake也是边做边学,若有不足之处,还请多多包含。

    其中,也有实现了功能,而不知所以的地方。 

    若有问题,请不吝指正。

  • 相关阅读:
    CodeForces 450
    CodeForces 400
    CodeForces 1
    [HDU POJ] 逆序数
    [HDU 1166] 敌兵布阵
    [转] 树状数组学习
    关于1月4日到1月7日
    [HDU 1565+1569] 方格取数
    [POJ 1459] Power Network
    [转] 网络流算法--Ford-Fulkerson方法及其多种实现
  • 原文地址:https://www.cnblogs.com/qitian1/p/6461979.html
Copyright © 2020-2023  润新知