一、靜態庫與動態庫構建
1.編譯共享庫:
ADD_LIBRARY(hello SHARED ${SHARED_LIBRARY})
ADD_LIBRARY(hello STATIC ${STATIC_LIBRARY})
因為默認規則是不能有相同名字的共享庫與靜態庫,所以當生成靜態庫的時候,共享庫會被刪除,所以需要通過SET_TARGET_PROPERTIES()來解決這個問題,例子:
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
cmake在構建一個target的時候,會刪除之前生成的target,一樣是通過設置SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)來達到目的。
SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)
二、靜態庫與動態庫構建常用變量和常用環境變量
1.變量的引用
使用“${}”,在IF中,不需要使用這種方式,直接使用變量名即可。
2.自定義變量
使用SET(OBJ_NAME xxxx),使用時${OBJ_NAME}
3.cmake的常用變量:
CMAKE_BINARY_DIR,PROJECT_BINARY_DIR,_BINARY_DIR
這三個變量內容一致,如果是內部編譯,就指的是工程的頂級目錄,如果是外部編譯,指的就是工程編譯發生的目錄。
CMAKE_SOURCE_DIR,PROJECT_SOURCE_DIR,_SOURCE_DIR
這三個變量內容一致,都指的是工程的頂級目錄。
CMAKE_CURRENT_BINARY_DIR:外部編譯時,指的是target目錄,內部編譯時,指的是頂級目錄
CMAKE_CURRENT_SOURCE_DIR:CMakeList.txt所在的目錄
CMAKE_CURRENT_LIST_DIR:CMakeList.txt的完整路徑
CMAKE_CURRENT_LIST_LINE:當前所在的行
CMAKE_MODULE_PATH:如果工程復雜,可能需要編寫一些cmake模塊,這里通過SET指定這個變量
LIBRARY_OUTPUT_DIR,BINARY_OUTPUT_DIR:庫和可執行的最終存放目錄
PROJECT_NAME:工程名字
4.cmake中調用環境變量
(1)使用 $ENV{NAME} : 調用系統環境變量,同樣可以用 SET(ENV{NAME} value) 設置環境變量,注意 "ENV" 不帶 "$"。
(2)CMAKE_INCLUDE_CURRENT_DIR 等於 INCLUDE_DIRECTORY(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
5.其他的內置變量
(1)BUILD_SHARED_LIBS : 使用ADD_LIBRARY()時設置默認值
(2)CMAKE_C_FLAGS : 為c編譯器設置編譯參數
(3)CMAKE_CXX_FLAGS : 為c++編譯器設置編譯參數
6.區分debug和release
通過 ${CMAKE_BUILD_TYPE} 變量判斷當前是"Release" 還是 "Debug" 版本編譯。
7.指定編譯32bit或64bit程序
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
三、常用指令
1.基本指令
INCLUDE_DIRECTORIES(${includedir}) #-I。 LINK_DIRECTORIES(${libdir}) #-L TARGET_LINK_LIBRARIES(helloworld ${linkflags}) #-l ADD_DEFINITIONS(${cflags}) #-D
2.FILE指令
FILE(WRITE file_name "content") FILE(APPEND file_name "content") FILE(READ file_name varible) FILE(WRITE file_name "content")
# 查找當前目錄下的所有源文件
set(CURR_DIR ${CMAKE_CURRENT_LIST_DIR}/)
file(GLOB_RECURSE SOURCE_FILES ${CURR_DIR} ${CURR_DIR}/*.cpp ${CURR_DIR}/*.c)
3.FIND_系列指令
LIBRARY( name path): FIND_LIBRARY(Xorg X11 /usr/lib64) IF(not Xorg) MESSAGE(STATUS "no Xorg") ENDIF(not Xorg) FILE( name path) PATH( name path) PROGRAM( name path) PACKAGE( [major.minor][QUIET][NO MODULE][[REQUIRED][COMPONTS][componts....]]) 最后一條,用來調用放在CMAKE_MODULE_PATH下的Find.cmake模塊,也可以自定義Find模塊 首先通過SET(CMAKE_MODULE_PATH /home/...)來指定位置
4.控制指令
IF(expression),ELSE(expression),ENDIF(expression) express舉例: 否定:空,0,N,NO,OFF,FALSE,NOTFOUND或_NOTFOUND 肯定:COMMAND cmd,EXISTS dir/file,variable MARCHES regex等等
示例:
IF (${CMAKE_BUILD_TYPE} STREQUAL "Debug")
message(WARNING "++++++ Debug ++++++++")
ENDIF(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
5.循環指令
(1) 循環添加依賴的靜態庫
set(LIB_BASE mpkernel mputility mpstream) foreach(lib ${LIB_BASE}) add_library(${lib} STATIC IMPORTED) set_property(TARGET ${lib} PROPERTY IMPORTED_LOCATION ${LIB_BASE_DIR}/lib${lib}.a) endforeach()
(2)循環拷貝動態庫到工程目錄,打包到APK。
set(BOKEHPP_SHARED_LIBS dualcam_bokeh bokehplus_image )
foreach(lib ${BOKEHPP_SHARED_LIBS}) set(THE_LIBRARY ${BOKEHPP_SHARED_LIBS}/lib${lib}.so) add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD # Adds a post-build event to ${PROJECT_NAME} COMMAND ${CMAKE_COMMAND} -E copy_if_different # which executes "cmake - E copy_if_different..." ${THE_LIBRARY} # <--this is in-file $<TARGET_FILE_DIR:${PROJECT_NAME}> # <--this is out-file path ) endforeach()
四、模塊的使用和自定義模塊
FIND_PACKAGE
_FOUND
_INCLUDE_DIR
_LIBRARY or _LIBRARIES
如果_FOUND為真,把_INCLUDE_DIR加入到INCLUDE_DIRECTORIES中,_LIBRARY加入到TARGET_LINK_LIBRARIES中。
1.FIND_PATH(HELLO_INCLUDE_DIR hello.h /usr/include/hello /usr/local/include/hello) 2.FIND_LIBRARY(HELLO_LIBRARY_DIR NAMES hello PATH /usr/lib /usr/local/lib) IF(HELLO_INCLUDE_DIR AND HELLO_LIBRARY) SET(HELLO_FOUND TRUE) ENDIF(HELLO_INCLUDE_DIR) 3.FIND_PACKAGE([major.minor][QUIET][NO_MODULE] [[REQUIRED|COMPONENTS][componets...]]) QUIET參數:去掉輸出信息 REQUIRED參數:共享庫是否是工程必須的,如果是必須的,那么找不到 如果在src中想調用hello模塊中的內容 FIND_PACKAGE(HELLO) 為了可以讓工程找到FindHELLO.cmake 在主工程的CMakeList.txt中,SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_PATH}/cmake) 通過設置FIND_PACKAGE(HELLO QUIET)可以去掉輸出信息
五、系統默認變量和內置變量
1.在不同的平台編譯的時候,會用到一些系統內置的變量,比如操作系統名稱,版本號之類:CMAKE_SYSTEM:系統全名,如 "Linux-2.4.22","FreeBSD-5.4-RELEASE" 或 "Windows 5.1" CMAKE_SYSTEM_NAME:系統名稱,如 "Linux", "FreeBSD" or "Windows",注意大小寫 CMAKE_SYSTEM_VERSION:只顯示系統全名中的版本部分 CMAKE_SYSTEM_PROCESSOR:CPU名稱
UNIX WIN32 for MINGW,CYGWIN,MSYS APPLE BORLAND WATCOM MSVC,MSVC_IDE,CMAKE_COMPILER_2005,MSVC60/70/71/80/90/10,針對不同的Visual C++ CMAKE_COMPILER_IS_GUNCXX/CMAKE_COMPILER_IS_GUNCC
BUIlD_SHARED_LIBS:將所有程序庫的target設置成共享庫 CMAKE_BUIlD_TYPE:控制構建類型,以下為可選參數 None:default;Debug:生成調試信息;Release:發布版本,進行最佳化,需要注意這個值不會在configure的時候自動初始化,需要手動指定 CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE