1. 程式人生 > >Cmake 實現debug和release lib依賴項處理

Cmake 實現debug和release lib依賴項處理

一、說明
  最近用cmake開發東西,編譯vs時候,發現debug和release版本的lib庫的依賴項問題,故此小結一下。若有不對之處,還請看官多多指教。 

使用的工程有自己編寫的工程,也有借用第三方庫的工程,還有沒有辦法找到原始碼的,只有dll和lib庫,沒有區分debug和release 版本的。 

  所以還是分開說,一種自己工程庫,一種是第三方庫。在寫完cmake程式碼,生成vs後,都可以自動的新增連結庫,debug和release版本涇渭分明。

 

二、自己工程之間的引用
先說,自己編寫的工程,工程直接的相互呼叫,這個就不用多說了。Cmake還是要呼叫target_link_libraries來連結自己的想要連結的動態庫。

但是需用做些設定,就可以自動的區分debug和release版本了。

首先,需實現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庫名稱,後面分別為debug和release版本的區分。

此定義還不是很完善,以後可能修改為只新增不同的部分,比如:

      RW_LINK_LIBRARY(free_image/FreeImage "d" "") 內部自動來識別andriod 或ios或msvc等。

 

第二個巨集的用法為:

RW_LINK_3RD_PART_LIBRARY(${GDAL_LIBRARY_DEBUG} ${GDAL_LIBRARY})

其中裡面寫的是兩個lib庫的路徑變數。

 

兩個巨集定義的原則均為,當沒有debug版本的lib庫時候,使用release版本的lib庫。

 

ps:
Cmake也是邊做邊學,若有不足之處,還請多多包含。

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

若有問題,請不吝指正。
--------------------- 
作者:cartzhang 
來源:CSDN 
原文:https://blog.csdn.net/cartzhang/article/details/29193091 
版權宣告:本文為博主原創文章,轉載請