CMake速記


title: CMake速記
date: 2019/11/18 19:17:40
toc: true
---linux

CMake速記

個人demo

#頂層
cmake_minimum_required(VERSION 3.16)
PROJECT(DCU)

SET(PLAT_FORM_THIS linux)

SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
if(PLAT_FORM_THIS STREQUAL "linux") 
    SET(PLAT_FORM linux)  
else()
    SET(PLAT_FORM arm)
    SET(CMAKE_SYSTEM_NAME Linux)
    SET(CMAKE_C_COMPILER "arm-linux-gcc")
    SET(CMAKE_CXX_COMPILER "arm-linux-g++")
endif() 


#SET(CMAKE_SYSTEM_NAME Linux)
#SET(CMAKE_C_COMPILER "arm-linux-gcc")
#SET(CMAKE_CXX_COMPILER "arm-linux-g++")


SET(INCLUDE_DIR /home/layty/work/pan/dcu-cmake/dcu_ubuntu/dc/include)
SET(PROJECT_BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/${PLAT_FORM}/)

# 有兩個子目錄
ADD_SUBDIRECTORY(third_party)
ADD_SUBDIRECTORY(dc)

#-------------------------------------------------------------------
# 子層若是仍是目錄的話
ADD_SUBDIRECTORY(task)
ADD_SUBDIRECTORY(thread)
#-----------------------------------------------------------------
# 子層是源文件,生成lib
INCLUDE_DIRECTORIES(${INCLUDE_DIR})
# 搜索全部源文件
AUX_SOURCE_DIRECTORY(. SRC)
# 這個是生成lib的路徑
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
# 生成lib
ADD_LIBRARY(base SHARED ${SRC})
#---------------------------------------------------------------
# 子層是源文件,生成lib
INCLUDE_DIRECTORIES(${INCLUDE_DIR})
AUX_SOURCE_DIRECTORY(. SRC)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/)

ADD_EXECUTABLE(xxxexexxx  ${SRC})
#連接
# 添加非標準的共享庫搜索路徑
LINK_DIRECTORIES(${PROJECT_BINARY_DIR}/${PLAT_FORM}/ ${PROJECT_BINARY_DIR}/${PLAT_FORM}/lib )
#爲 target 添加須要連接的共享庫
TARGET_LINK_LIBRARIES(xxxexexxx  pthread  sqlite3  zlog crypto)

外部構建

1. mkdir build && cd build
2. cmake ..
3. make

內部變量sql

PROJECT_BINARY_DIR    構建目錄,這裏若是是外部構建這裏是build
PROJECT_SOURCE_DIR    仍是工程目錄,也就是 cmake 後面的 .. 也就是這裏是父目錄
 
<projectname>_BINARY_DIR 
<projectname>_SOURCE_DIR

基礎語法

  1. 變量使用${}方式取值,可是在 IF 控制語句中是直接使用變量名
  2. 指令(參數 1 參數 2...)
  3. 指令是大小寫無關的,參數和變量是大小寫相關的
  4. 工程名(projectname)和可執行的文件名沒有什麼關係

經常使用指令

https://cmake.org/cmake/help/v3.16/manual/cmake-commands.7.htmlubuntu

PROJECT(projectname [CXX] [C] [Java])

SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])

MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display"...)

ADD_EXECUTABLE (<name> [WIN32] [MACOSX_BUNDLE]
               [EXCLUDE_FROM_ALL]
               [source1] [source2 ...])

#添加子目錄, binary_dir爲在build的重命名的生成目錄
#EXCLUDE_FROM_ALL 參數的含義是將這個目錄從編譯過程當中排除,好比,工程的example,可能就須要工程構建完成後,再進入 example 目錄單獨進行構建
add_subdirectory(source_dir [ binary_dir] [EXCLUDE_FROM_ALL])

#指定最終的目標二進制的位置,不包含編譯生成的中間文件
# 使用add_subdirectory 的bin指定的生產的目錄下有臨時文件 很差看
# 在哪裏 ADD_EXECUTABLE 或 ADD_LIBRARY,若是須要改變目標存放路徑,就在哪裏加入上述的定義
# 這樣就能夠指定多個 exe lib的路徑
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)


install(TARGETS <target>... [...])
install({FILES | PROGRAMS} <file>... [...])
install(DIRECTORY <dir>... [...])
install(SCRIPT <file> [...])
install(CODE <code> [...])
install(EXPORT <export-name> [...])

#例子

#cmake -DCMAKE_INSTALL_PREFIX=/usr .
#CMAKE_INSTALL_PREFIX 的默認定義是/usr/local
# ${CMAKE_INSTALL_PREFIX}/<DESTINATION 定義的路徑>
INSTALL(TARGETS targets...
    [[ARCHIVE|LIBRARY|RUNTIME]  # .a,.so,.o
        [DESTINATION <dir>]     # 安裝的路徑,/開頭爲絕對路徑,若是要使用CMAKE_INSTALL_PREFIX 指定則要用相對路徑
        [PERMISSIONS permissions...]
        [CONFIGURATIONS
    [Debug|Release|...]]
        [COMPONENT <component>]
        [OPTIONAL]
    ] [...])
# 例子
INSTALL(TARGETS myrun mylib mystaticlib
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION libstatic
)
# 可執行二進制 myrun 安裝到${CMAKE_INSTALL_PREFIX}/bin 目錄
# 動態庫 libmylib 安裝到${CMAKE_INSTALL_PREFIX}/lib 目錄
# 靜態庫 libmystaticlib 安裝到${CMAKE_INSTALL_PREFIX}/libstatic 目錄


# EXCLUDE_FROM_ALL 參數的意思是這個庫不會被默認構建,除非有其餘的組件依賴或者手工構建。
add_library(<name> [STATIC | SHARED | MODULE]
            [EXCLUDE_FROM_ALL]
            [source1] [source2 ...])
            
# 設置輸出目標的屬性            
SET_TARGET_PROPERTIES(target1 target2 ...PROPERTIES prop1 value1 prop2 value2 ...)    
#例子 將hello_static 的名字改成hello
ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
# cmake 在構建一個新的 target 時,會嘗試清理掉其餘使用這個名字的庫,由於,在構建 libhello.a 時,就會清理掉 libhello.so.
# 爲了不清理,須要再設置 CLEAN_DIRECT_OUTPUT 屬性
SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT1)


# 得到目標屬性,變量存在VAR 若是沒有這個屬性定義,則返回 NOTFOUND
GET_TARGET_PROPERTY(VAR target property)

# 設置版本號
SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)

#頭文件,默認追加在後面
#1,CMAKE_INCLUDE_DIRECTORIES_BEFORE,經過 SET 這個 cmake 變量爲 on,能夠將添加的頭文件搜索路徑放在已有路徑的前面。
#2,經過 AFTER 或者 BEFORE 參數,也能夠控制是追加仍是置前。
INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)


#連接
# 添加非標準的共享庫搜索路徑
LINK_DIRECTORIES(directory1 directory2 ...)
#爲 target 添加須要連接的共享庫
TARGET_LINK_LIBRARIES(target library1 <debug | optimized> library2...)

# ldd src/main 查看結果

#連接到靜態庫 加入.a
TARGET_LINK_LIBRARIES(main libhello.a)

# 當前目錄的全部文件
AUX_SOURCE_DIRECTORY(dir VARIABLE)

環境變量

CMAKE_INCLUDE_PATH 
CMAKE_LIBRARY_PATH

export 使用或者
CMAKE_INCLUDE_PATH=/home/include cmake ..


內部這麼使用 hello.h 
# FIND_PATH 用來在指定路徑中搜索文件名
# #FIND_PATH(myHeader NAMES hello.h PATHS /usr/include/usr/include/hello)
FIND_PATH(myHeader hello.h)
IF(myHeader)
INCLUDE_DIRECTORIES(${myHeader})
ENDIF(myHeader)

一樣的 CMAKE_LIBRARY_PATH 能夠用在 FIND_LIBRARY 中

一些變量

CMAKE_CURRENT_SOURCE_DIR  #指的是當前處理的 CMakeLists.txt 所在的路徑
CMAKE_CURRRENT_BINARY_DIR #target 編譯目錄,ADD_SUBDIRECTORY(src bin)能夠更改這個變量的值
CMAKE_CURRENT_LIST_FILE  #輸出調用這個變量的 CMakeLists.txt 的完整路徑
CMAKE_CURRENT_LIST_LINE  #輸出這個變量所在的行
EXECUTABLE_OUTPUT_PATH 和 LIBRARY_OUTPUT_PATH #分別用來從新定義最終結果的存放目錄,前面咱們已經提到了這兩個變量。
PROJECT_NAME  #返回經過 PROJECT 指令定義的項目名稱

參考文檔

相關文章
相關標籤/搜索