CMake 簡介和 CMake 模板

轉(zhuǎn)載自我的博客:CMake 簡介和 CMake 模板芙粱。


如果你用 Linux 操作系統(tǒng)催蝗,使用 cmake 會簡單很多饵婆,可以參考一個很好的教程:CMake 入門實戰(zhàn) | HaHack笼吟。如果你用 Linux 操作系統(tǒng)伞鲫,而且只是運行一些小程序粘茄,可以看看我的另一篇博客:你就編譯一個 cpp,用 CMake 還不如用 pkg-config 呢秕脓。

但如果你用 Windows柒瓣,很大的可能你會使用圖形界面的 CMake(cmake-gui.exe)和 Visual Studio。本文先簡單介紹使用 CMake + Visual Studio 的使用流程吠架,然后以幾個例子介紹 CMake 相關(guān)知識芙贫。

CMake 使用流程

如果你還沒安裝 cmake,下載 https://cmake.org/files/v3.6/cmake-3.6.0-win64-x64.msi(15 MB)安裝它傍药。如果你還沒裝 VS磺平,推薦使用 VS2015 社區(qū)版本,到 這里 下載拐辽,選擇那個 3.7 GB 的拣挪。因為一次下載好,安裝起來很省心薛训。如果你已經(jīng)有了 VS2010 或者 VS2013媒吗,也可以不安裝 VS2015。

下載第一份源碼 cpp.zip(1.16 KB)乙埃。解壓進入文件夾闸英,打開 cmake-gui,把源碼和 cmake-gui 界面對半放介袜。如下圖:

然后甫何,

  1. 把源碼根目錄的 CMakeLists.txt 拖動到 cmake-gui 界面上
  2. 修改輸出目錄(我通常都是添加 /build
  3. 點擊 configure(配置),選擇【Visual Studio 14 VS2015 Win64】遇伞,點擊確定^[“Win64”是指的是編譯 VS2015 x64 工程辙喂,沒有“Win64”則為 x86 工程)。]
  4. 點擊 generate(生成)

最后鸠珠,到輸出目錄巍耗,用 VS2015 打開 CPP.sln 工程。在 Solution Explorer 中右鍵單擊 CPP渐排,然后【Set as StartUp Project】炬太,然后 <kbd>Ctrl</kbd>+<kbd>F5</kbd> 運行。

相信你已經(jīng)看到了程序運行結(jié)果驯耻,大概如下:

0^2 --->    0
0^2 --->    0
2^2 --->    4
3^2 --->    9
4^2 --->    16

使用 CMake 的好處是亲族,它可以生成 VS 工程炒考,也可以生成 Linux 系統(tǒng)下常用的 Makefile工程,甚至還可以用 Qt creator 打開 CMakeLists.txt 文件霎迫,然后生成 qt 工程斋枢。^[參考我的教程:HOWTO: Use Qt creator to Open CMakeLists.txt directly (will generate proper project files) · Issue #5 · district10/cmake-templates,里面包含一個 Linux 上的例子知给,一個 Windows 上的例子瓤帚。]這份代碼,在 Linux 上也可以迅速跑起來涩赢,這是我虛擬機中運行的截圖:

CMake 基礎(chǔ)

簡單的四行 CMakeLists.txt

本小節(jié)源碼:cmake-templates/cpp at master · district10/cmake-templates缘滥。

我們從根目錄的 CMakeLists.txt 看起,它簡潔到只有 4 行谒主!如下:

project( CPP )
cmake_minimum_required( VERSION 2.6 )
file( GLOB SRCS *.c *.cpp *.cc *.h *.hpp )
add_executable( ${PROJECT_NAME} ${SRCS} )

我們一行一行看朝扼,

  • 第一行,設(shè)置了工程名稱霎肯,叫“CPP”(所以后來生成的 VS 工程名為 CPP.sln)擎颖;
  • 第二行,設(shè)置了 CMake 最低版本號观游,通常在根目錄的 CMakeLists.txt 添加這個指定搂捧;
  • 第三行,把當(dāng)前文件夾下的源碼列表(文件后綴匹配的那些文件)存到變量 SRCS 中懂缕;
  • 第四行允跑,把源碼編譯成一個二進制這里的 ${PROJECT_NAME} 就是 CPP,是在第一行設(shè)置的搪柑。

這就是一個基本的用 CMake 組織的 C++ 程序聋丝。只要四行配置,利用 CMake工碾,我們就生成了 Windows 下的 VS 工程弱睦,還生成了 Linux 下的 Makefile 工程。只要四行渊额!

當(dāng)然還可以生成多個二進制况木,如果你有多份源碼,比如

add_executable( foo foo.cpp )
add_executable( bar bar.cpp )

如果上面沒問題旬迹,還是這兩個代碼火惊,我們在 CMakeLists.txt 里去掉上面兩行,改成 add_executable( foobar foo.cpp bar.cpp ){.cmake}奔垦,會不會有什么問題屹耐?

生成靜態(tài)、動態(tài)庫

本小節(jié)源碼:cmake-templates/modules at master · district10/cmake-templates宴倍。

還可以用 CMake 生成鏈接庫张症,可以是靜態(tài)庫(.lib),也可以是動態(tài)庫(.dll)鸵贬,語法如下:

add_library(    動態(tài)鏈接庫名稱      SHARED      源碼列表    )
add_library(    靜態(tài)鏈接庫名稱      STATIC      源碼列表    )

如果不指定 SHARED 或是 STATIC俗他,默認(rèn)生成的是 STATIC,這個例子里阔逼,src 文件夾下生成了 3 個鏈接庫兆衅,LibCubic 是“指定”生成的靜態(tài)庫,LibExtras 是“指定”生成的動態(tài)庫嗜浮,LibSquare 是“默認(rèn)”生成的靜態(tài)庫羡亩。

生成庫文件就是為了讓人用,所以我們要把它鏈接給某個二進制危融,語法如下:

add_executable(             二進制名    源碼列表        )
target_link_libraries(      二進制名    動靜態(tài)庫名      )

生成庫的源碼有什么最基本的要求嗎畏铆?如果 add_executable( baz baz.cpp b.cpp a.cpp z.cpp ){.cmake} 可以正確地生成二進制文件 baz(windows 上就是 baz.exe),那這行 CMake 配置可以修改為 add_library( baz baz.cpp b.cpp a.cpp z.cpp ){.cmake} 嗎吉殃?為什么辞居。

鏈接系統(tǒng)配置了的庫

本小節(jié)源碼:cmake-templates/opencv3 at master · district10/cmake-templates

CMake 的一個方便之處蛋勺,便是添加第三方庫瓦灶。在我的 CMake 安裝目錄(C:\Program Files\CMake\share\cmake-3.6\Modules)下,有多達 145 個 FindX.cmake 文件抱完,比如FindQt4.cmake贼陶。當(dāng)你在自己源碼中使用 find_package( Qt4 ) 時,CMake 就會嘗試去引入 FindQt4.cmake巧娱,這個文件引入后碉怔,特定的變量里就存儲了頭文件地址(include_directories)、鏈接庫地址(link_directories)禁添、鏈接庫的名稱以及一些開關(guān)配置(options)眨层。

本節(jié)用 OpenCV 來說明如何鏈接使用第三方庫,這里用的是 opencv3上荡。OpenCV3 官網(wǎng)提供的只有 VS2013 (vc12) 和 VS2015 (vc14) 的 prebuild趴樱,如果你使用 VS2012,你只能使用 OpenCV2(或者你要自己編譯 OpenCV3酪捡?)叁征。OpenCV 的配置可以參考我寫得教程:HOWTO: OpenCV 2 & OpenCV 3 · Issue #4 · district10/cmake-templates

本節(jié)源碼的 CMakeLists.txt 里逛薇,我沒有使用 find_package( OpenCV REQUIRED )捺疼,而是使用了include( $ENV{OpenCV3_DIR}/OpenCVConfig.cmake ),因為我覺得這是一種更好的解決方案永罚,如此一來啤呼,你只要設(shè)置環(huán)境變量(%OpenCV3_DIR%)卧秘,添加相應(yīng)目錄到 %PATH%,便可以同時使用 OpenCV2 和 OpenCV3(當(dāng)然是在不同的項目中)官扣。上面的源碼鏈接中對此也有簡要說明翅敌。

看看我們的 CMakeLists.txt:

project( OPENCV3 )
cmake_minimum_required( VERSION 2.8 )

# find_package( OpenCV REQUIRED )                       # 不使用 find_package
include( $ENV{OpenCV3_DIR}/OpenCVConfig.cmake )         # 直接引入 cmake 文件

message( STATUS "OpenCV library status:" )              # 輸出一下得到的變量
message( STATUS "    version: ${OpenCV_VERSION}" )
message( STATUS "    libraries: ${OpenCV_LIBS}" )
message( STATUS "    include path: ${OpenCV_INCLUDE_DIRS}" )

include_directories( ${OpenCV_INCLUDE_DIRS} )           # 引入 OpenCV 頭文件目錄

add_executable( ${PROJECT_NAME} example.cpp )
target_link_libraries( ${PROJECT_NAME} ${OpenCV_LIBS} ) # exe 鏈接 OpenCV

在我的系統(tǒng)下,輸出如下(我調(diào)整了換行):

OpenCV ARCH: x64
OpenCV RUNTIME: vc14
OpenCV STATIC: ON
Found OpenCV 3.1.0 in C:/OpenCV/opencv3/build/x64/vc14/lib
You might need to add C:\OpenCV\opencv3\build\x64\vc14\bin to your PATH to be able to run your applications.
OpenCV library status:
    version: 3.1.0
    libraries:  opencv_world;opencv_videostab;opencv_videoio;opencv_video;
                opencv_superres;opencv_stitching;opencv_shape;opencv_photo;
                opencv_objdetect;opencv_ml;opencv_imgproc;opencv_imgcodecs;
                opencv_highgui;opencv_flann;opencv_features2d;opencv_core;opencv_calib3d
    include path: C:/OpenCV/opencv3/build/include;C:/OpenCV/opencv3/build/include/opencv
Configuring done

很容易地惕蹄,程序也運行起來了蚯涮。

更多的了解

只要掌握上面那基本的幾點(通俗地說,就是生成 exe卖陵、lib遭顶、dll,鏈接 lib泪蔫、dll棒旗,引入第三方庫),然后積攢一些別人的 CMakeLists.txt 片段撩荣,CMake 便不難了嗦哆。

如果你還覺得 CMake 很麻煩,那一定是我博客寫得不好婿滓。如果你覺得 CMake 不好用老速,那不是我的錯,那是 CMake 的官方教程太垃圾導(dǎo)致的凸主,我反正從來沒見過如此晦澀橘券,一個例子都不給的教程。當(dāng)時寫 https://github.com/district10/cmake-templates/blob/master/qt4-project/CMakeLists.txt 的時候卿吐,我可是深受其苦旁舰。

寫起來雖難,但用起來方便嗡官,所以……我大贊 CMake箭窜。

想對 CMake 有更多的了解,可以參考我的 district10/cmake-templates: Some CMake Templates. Qt, Boost, OpenCV, C++11, etc.衍腥,里面有簡單的 C 工程磺樱,C++ 工程,C++11 工程婆咸,Boost 庫的配置竹捉,OpenCV2、OpenCV3 的配置尚骄,Qt4块差、Qt5 的配置,等等。代碼在大多在 Windows + VS2010/VS2015 和 Linux + GCC4.8 測試通過憨闰。

我還寫了一些庫的配置状蜗,不同平臺不同 IDE、編譯器上有關(guān) CMake 使用的教程:Issues · district10/cmake-templates鹉动。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末轧坎,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子训裆,更是在濱河造成了極大的恐慌,老刑警劉巖蜀铲,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件边琉,死亡現(xiàn)場離奇詭異,居然都是意外死亡记劝,警方通過查閱死者的電腦和手機变姨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來厌丑,“玉大人定欧,你說我怎么就攤上這事∨停” “怎么了砍鸠?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長耕驰。 經(jīng)常有香客問我爷辱,道長,這世上最難降的妖魔是什么朦肘? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任饭弓,我火速辦了婚禮,結(jié)果婚禮上媒抠,老公的妹妹穿的比我還像新娘弟断。我一直安慰自己,他們只是感情好趴生,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布阀趴。 她就那樣靜靜地躺著,像睡著了一般苍匆。 火紅的嫁衣襯著肌膚如雪舍咖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天锉桑,我揣著相機與錄音排霉,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛攻柠,可吹牛的內(nèi)容都是我干的球订。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼瑰钮,長吁一口氣:“原來是場噩夢啊……” “哼冒滩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起浪谴,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤开睡,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后苟耻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體篇恒,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年凶杖,在試婚紗的時候發(fā)現(xiàn)自己被綠了胁艰。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡智蝠,死狀恐怖腾么,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情杈湾,我是刑警寧澤解虱,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站漆撞,受9級特大地震影響饭寺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜叫挟,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一艰匙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧抹恳,春花似錦员凝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至瓶蚂,卻和暖如春糖埋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背窃这。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工瞳别, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓祟敛,卻偏偏與公主長得像疤坝,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子馆铁,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容