1. 程式人生 > >CMake入門筆記

CMake入門筆記

什麼是CMake

CMake

CMake是一個跨平臺的安裝(編譯)工具,可以用簡單的語句來描述所有平臺的安裝(編譯過程)。他能夠輸出各種各樣的makefile或者project檔案,能測試編譯器所支援的C++特性,類似UNIX下的automake。只是 CMake 的組態檔取名為 CMakeLists.txt。Cmake 並不直接建構出最終的軟體,而是產生標準的建構檔(如 Unix 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然後再依一般的建構方式使用。這使得熟悉某個整合開發環境(IDE)的開發者可以用標準的方式建構他的軟體,這種可以使用各平臺的原生建構系統的能力是 CMake 和 SCons 等其他類似系統的區別之處。

Make

make工具是一個簡化編譯工作程式,有了它我們可以進行所謂的“自動化編譯”,極大地提高了軟體開發的效率。make工具相當於一個Shell,通過解釋Makefile的中的命令進行工作。大多數IDE都有這個工具,比如:Visual C++的nmake,Linux下GNU的make。
make工具最主要也是最基本的功能就是通過makefile檔案來描述源程式之間的相互關係並自動維護編譯工作。而makefile 檔案需要按照某種語法進行編寫,檔案中需要說明如何編譯各個原始檔並連線生成可執行檔案,並要求定義原始檔之間的依賴關係。

直白點說就是,CMake用來生成makefile或者是工程檔案,make是用來解釋makefile的。
以Linux平臺下使用gcc編譯為例,我們想要編譯原始檔可以直接在命令列中執行gcc test.c -o test

之類的命令,可是檔案多了,工程複雜,而且檔案不時的還會變,每次這樣輸多麻煩。
這個時候make就有了用武之地,寫個makefile,以後編譯就直接make解釋下makefile,根據makefile來執行編譯命令。這樣在linux上是很好,在windows上或者其他平臺上怎麼辦呢?
這時候就到cmake出馬了,構建工程的時候,不在寫makefile,而寫CMakeLists.txt。需要編譯的時候,先用Cmake解釋CMakeLists.txt。如果在Windows平臺上,設定編譯器是VS,CMake就生成一個VS的工程,然後用VS來執行編譯專案。如果是在Linux平臺上,編譯器是gcc,CMake就生成makefile,然後用make來解釋makefile編譯專案。
如圖,分別為原始目錄、在Linux下選擇gcc為編譯工具生成的工程檔案和在WIndows下選用Visual Studio為編譯器生成的工程檔案:
這裡寫圖片描述
這裡寫圖片描述這裡寫圖片描述

cmake執行後會在cmake執行時所在的目錄生成許多檔案,根據cmake執行目錄是否與原始檔同目錄,將構建方式分為兩種:

  • out-of-source build,構建輸出檔案與原始檔放到不同目錄中;
  • in-source build :構建輸出檔案與原始檔放到相同目錄中。

一般選擇out-of-source方式,可以在專案目錄下建立一個build檔案,然後進入build下,執行cmake ../,使生成的檔案都在build資料夾下,以便後期清理。

示例

為了編譯與演示方便,示例全部在Linux下進行。

Hello, CMake!

CMake最簡單的例項,目錄結構如下:
這裡寫圖片描述
main.c檔案:

 #include <stdio.h>

int main(int argc, char *argv[])
{
    printf("Hello, CMake!\r\n");

    return 0;
}

CMakeLists.txt檔案

 # 版本限定
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)                      
# 專案名稱
PROJECT(Test1)
# 新增原始檔列表變數
SET(SRC_LIST main.cpp)
# 列印編譯目錄和專案目錄路徑
MESSAGE(STATUS "This is SOURCE dir " ${PROJECT_SOURCE_DIR})
# 生成可執行檔案
ADD_EXECUTABLE(HelloCMake ${SRC_LIST})

然後進入專案目錄,依次執行(需要確保linux下安裝了gcc、make等):

mkdir build
cd build
cmake ../

此時,build資料夾內容如下:
這裡寫圖片描述
。然後鍵入make命令,即解析了Makefile檔案,build目錄下的內容變為:
這裡寫圖片描述
可以看到,生成了一個HelloCMake的可執行檔案,鍵入./HelloCMake可以執行HelloCMake檔案。
bash執行輸出過程如下:
這裡寫圖片描述

同一目錄多個原始檔

在實際使用中,很少會出現這麼簡單的情況,往往在一個資料夾中會存在多個原始檔要求編譯,目錄如下,這時候只需要在SET後面加上需要編譯的原始檔就可以了。
這裡寫圖片描述
CMakeLists.txt檔案:

# 版本限定
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)                      
# 專案名稱
PROJECT(Test2)
# 新增原始檔列表變數
SET(SRC_LIST Stupid.cpp main.cpp)
# 列印編譯目錄和專案目錄路徑
MESSAGE(STATUS "This is BINARY dir " ${PROJECT_BINARY_DIR})
MESSAGE(STATUS "This is SOURCE dir " ${PROJECT_SOURCE_DIR})
# 生成可執行檔案
ADD_EXECUTABLE(Test2 ${SRC_LIST})

上述方式雖然可行,但是如果原始檔過多,CMakeLists.txt檔案編寫起來也是一件很吃力的事情,這時候,可以用aux_source_directory來解決這個問題。aux_source_directory可以遍歷指定資料夾的下原始檔,將它們統一複製給一個變數,然後進行編譯。

CMakeLists.txt檔案2:

# 版本限定
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)                      
# 專案名稱
project(Test3)

# 遍歷當前目錄所有的原始檔,賦值給test3src
aux_source_directory(. test3src)
message(STATUS "src file : " ${test3src})
# 生成可執行檔案
add_executable(Test3 ${test3src})

不同目錄下的多個原始檔

為了使原始碼更為清晰,原始碼往往會根據不同的功能,將程式碼放在不同的資料夾下,結構如圖:
這裡寫圖片描述這裡寫圖片描述
這時候CmakeLists.txt檔案又該如何編寫呢?答案如下:

# 版本限定
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)                      
# 專案名稱
project(Test3)

# 遍歷當前目錄所有的原始檔,賦值給test3src
aux_source_directory(. main)
aux_source_directory(./stupid stupid)
set(test4src ${main} ${stupid})
message(STATUS "src file : " ${test4src})

# 生成可執行檔案
add_executable(Test4 ${test4src})

編譯動態庫與靜態庫

在前面的示例中,我們都是直接生成了可執行檔案,而更多的時候,我們需要生成的不是可執行檔案,而是一個可以讓複用的庫檔案,這時候只需要將add_executable(Name ${srcTemp})修改為add_library(Name ${srcTemp})就可以了。add_library可以在中間增加一個引數表示動態庫或靜態庫,預設無引數為靜態庫。

# 版本限定
cmake_minimum_required(VERSION 2.8)

# 遍歷當前目錄所有的原始檔,賦值給STUPID_SRC
aux_source_directory(. STUPID_SRC)
# 編譯STUPID_SRC為靜態庫
add_library(stupid STATIC ${STUPID_SRC})
# 編譯STUPID_SRC為動態庫
# add_library(stupid SHARED ${STUPID_SRC})

庫檔案和標頭檔案匯出到指定位置

編譯出的庫檔案是要使用的,而庫檔案的使用一般需要庫檔案和標頭檔案。雖然可以編譯出庫後自己整理庫檔案和標頭檔案,但是終歸是一件麻煩事,尤其是工程比較龐大的時候。這時候,我們可以使用INSTALL來將庫檔案和標頭檔案匯出到指定位置。

# 版本限定
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(OUTPUT ${CMAKE_CURRENT_BINARY_DIR})
AUX_SOURCE_DIRECTORY(. STUPID_SRC)
# 設定庫檔案輸出目錄
# SET(LIBRARY_OUTPUT_PATH ${LIB_DIRS})
# 建立動態庫
ADD_LIBRARY(stupid SHARED ${STUPID_SRC})
# 匯出動態庫
INSTALL(TARGETS stupid DESTINATION ${OUTPUT}/libs)
# 匯出標頭檔案
INSTALL(DIRECTORY . DESTINATION ${OUTPUT}/include/stupid 
    FILES_MATCHING PATTERN "*.h")

然後進入專案目錄/build/ 目錄下,依次執行:

cmake ../
make 
make install

即可在build下生成以下結構:
這裡寫圖片描述
include為標頭檔案目錄,其中包含了stupid/stupid.h檔案。libs為庫檔案目錄,其中包含了libstupid.so檔案。

使用動態庫/靜態庫

在上一個示例中,我們生成並匯出了動態庫,現在來使用它。複製出上個示例匯出的libs及include資料夾,形成以下結構:
這裡寫圖片描述
CMakeLists.txt檔案內容如下:

# 版本限定
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)                      
# 專案名稱
PROJECT(Test8)
# 遍歷當前目錄所有的原始檔,賦值給test3src
AUX_SOURCE_DIRECTORY(. main)
MESSAGE(STATUS "src file : " ${main})
# 指定庫檔案搜尋目錄,必須為絕對路徑
LINK_DIRECTORIES(${PROJECT_SOURCE_DIR}/libs)
# 生成可執行檔案
ADD_EXECUTABLE(Test8 ${main})
# 指定標頭檔案目錄
INCLUDE_DIRECTORIES(./include)
# 指定目標需要連線的庫
TARGET_LINK_LIBRARIES(Test8 stupid)

相關推薦

CMake入門筆記

什麼是CMake CMake CMake是一個跨平臺的安裝(編譯)工具,可以用簡單的語句來描述所有平臺的安裝(編譯過程)。他能夠輸出各種各樣的makefile或者project檔案,能測試編譯器所支援的C++特性,類似UNIX下的automake。只是

HTTP 協議入門-筆記

維護 動向 nbsp ima vid 指定 編碼 數據壓縮 aud 原文參考http://mp.weixin.qq.com/s/czx0AHaItrJ-c49XDboIUg HTTP是基於TCP/IP協議的應用層協議,規定了客戶端和服務端之間的通信格式,默認使用80端口1

mongodb入門筆記

查詢 類型 ted 語法 json數據 con 軟件 創建文件 關系 mongodb作為nosql中排名第一的數據庫,近年來使用的人數越來越多,作為開發人員,非常有必要了解下mongodb數據庫。下面就給大家介紹下mongodb數據庫的基本知識,有不對的地方歡迎指正,QQ:

SPARK 入門筆記

bin combine 核心 pre 細節 part api 而且 pri 1、Spark基於內存進行運算 2、Spark核心是SprintContext,是程序的入口 3、RDDs是提供抽象的數據集,通過RDDS可以方便對分布在各個節點的數據進行計算,而且忽略細節 4、R

OpenCV入門筆記(二) 圖片的文件操作

strong asc nump str destroy type convert 代碼 creat 以下介紹一下重要的幾個,設計基本 圖片處理 的函數,依次來了解OpenCV的入門知識。具體的具體使用方法還是以官方的API【Official Tutori

D3 入門筆記

一個點 最大 長度 連接 全部 示意圖 == 改變 失真 一、第一個程序 選擇集: 使用d3.select()或者 d3.selectAll()選擇元素後返回的對象,就是選擇集 d3能夠連續不斷地調用函數,形如:d3.select().selctAll().text()這稱

php 入門筆記

lamp 吃飯 常用 -c 九九乘法表 borde 輸出結果 數值 邏輯運算符 一、web服務器原理 瀏覽器:不算開發技術,但是是開發者工具,能幫助我們到服務器去找腳本並進行解析 了解瀏覽器的差異 開發時需要安裝多個瀏覽器測試兼容效果 大致可分為兩大類: IE 和 其他 可

Python3入門筆記(1) —— windows安裝與運行

python安裝 color 聲明 返回值 down 如果 ++ 這一 ges Python的設計哲學是“優雅”、“明確”、“簡單”。這也是我喜歡Python的理由之一 Python的安裝: 1.進入Python官方網站下載安裝包 點擊導航欄的 Downloads 會自動

爬蟲入門筆記

collect head 有一個 cnblogs ted col https 指定 爬蟲 爬蟲,在網絡中爬行的一只蜘蛛,如遇到資源,就會按指定的規則抓取下來 爬蟲爬取HTML代碼後,通過分析和過濾這些HTML代碼,實現對圖片,文字等資源的獲取 URL的格式由三部分組成:  

hadoop入門筆記MapReduce Shuffle簡介(五)

單位 海量數據 並行處理 詳細 但是 信息 不能 utf 適合 1. MapReduce 定義   Hadoop 中的 MapReduce是一個使用簡單的軟件框架,基於它寫出來的應用程序能夠運行在由上千個商用機器組成的大型集群上,並以一種可靠容錯式並行處理TB級別的數據集

hadoop入門筆記MapReduce簡介(三)

today 信息 編程模型 cut 大型 狀態 參數 dfs 好處 . MapReduce基本編程模型和框架 1.1 MapReduce抽象模型 大數據計算的核心思想是:分而治之。如下圖1所示。把大量的數據劃分開來,分配給各個子任務來完成。再將結果合並到一起輸出。 註:如果

JS入門筆記+基本操作(剛接觸JS,很多筆記就是看到啥寫啥的,希望多多包涵)。

外部 friend mage fff pen scrip 表示 num 很好 1.註釋: html的註釋:<!--我是註釋--> CSS的註釋:/*我是註釋*/ JS的註釋://我是註釋 2.變量: 變量要先聲明再賦值,如下: var mychar; myc

Oracle入門筆記 ——啟動進階

rac tro distrib 排序 可能 重建 1.2 重要 scn 1.2 進階內容: 兩個概念:SCN 和 檢查點 1.SCN的定義: system change member ,系統改變號,是數據庫中非常重要的一個數據結構。 SCN 用以標示數據庫

awk 新手入門筆記

and count tin 顯示 使用 border date 用法 $1 轉自:http://www.habadog.com/2011/05/22/awk-freshman-handbook/ awk新手入門筆記 @作者 : habadog@郵箱 : [email&#

SSH入門筆記

命令 故障 創建對象 pre 捕獲 mon like commons 創建時間 一、Oracle數據庫基礎 Oracle數據庫的主要特點如下: (1)支持多用戶、大事務量的事務處理。 (2)在保持數據安全性和完整性方面性能優越。 (3)支持分布式數據處理。將分布在不同物理位

前端入門筆記

選擇 onchange word top 動態 option 訪問 checkbox 困難 1、html基本結構<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"&g

PS入門筆記

元素 印刷 數字化 question ima 另一個 img 定量 矩陣 一、基本術語 以下圖像和通道內容參考知乎:https://www.zhihu.com/question/21849710/answer/19529410* 數字圖像:本質是一個多維矩陣。數字圖像,又稱

Shader 入門筆記(二) CPU和GPU之間的通信

draw drawcall 進行 時間 包含 spa 入門 光柵 著色器 渲染流水線的起點是CPU,即應用階段。   1)把數據加載到顯存中   2)設置渲染狀態,通俗說這些狀態定義了場景中的網格是怎樣被渲染的。   3)調用DrawCall,一個命令,CPU通知GPU。(

Spring MVC學習入門筆記

分享圖片 快捷 png epo 為什麽 學習 -c ava 報錯 使用Spring步驟 添加依賴 創建xml文件 配置(需要被管理的類)bean 實例化上下文類 GetBean對象 使用idea新建一個maven項目,在pom.xml中添加依賴: <depe

Python入門筆記

成功 assert red ins cor http ima 筆記 sin (來自小甲魚零基礎入門學習Python) 要學習Python可以把菜鳥教程裏面的內容過一遍:http://www.runoob.com/python3/python3-basic-syntax.ht