1、說明
最近用cmake開發東西,編譯vs時候,發現debug和release版本的lib庫的依賴項問題,故此小結一下。如有不對之處,還請看官多多指教。 ios
使用的工程有本身編寫的工程,也有借用第三方庫的工程,還有沒有辦法找到源碼的,只有dll和lib庫,沒有區分debug和release 版本的。 windows
因此仍是分開說,一種本身工程庫,一種是第三方庫。在寫完cmake代碼,生成vs後,均可以自動的添加連接庫,debug和release版本涇渭分明。post
2、本身工程之間的引用
先說,本身編寫的工程,工程直接的相互調用,這個就不用多說了。Cmake仍是要調用target_link_libraries來連接本身的想要連接的動態庫。ui
可是需用作些設置,就能夠自動的區分debug和release版本了。spa
首先,需實現cmake定義以下:.net
#這個就是定義各個版本對應的後綴,例如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()debug
以上代碼咱們是在外層的CMakeLists.txt中實現的。blog
接着下來cmake代碼是在內層的cMakeLists.txt中實現。主要是使用外層定義的東西。 開發
Cmake代碼以下:get
# 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是咱們工程相關的名稱,大家能夠本身設置。在工程屬性的出現,以下所示:
3、第三方庫
關於第三方庫,狀況比較複雜。有源碼的,沒有源碼的,靜態的,動態的,只有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也是邊作邊學,如有不足之處,還請多多包含。
其中,也有實現了功能,而不知因此的地方。
如有問題,請不吝指正。