CMake基礎使用整理

CMake是一個跨平臺的編譯工具,可以一次編寫,在不同平臺自動生成對應的Makefile文件,減少了手寫Makefile以及適配不同平臺時的耗時。

前言

之前大部分時候在windows端使用VS開發,因此對Makefile、CMake等工具接觸較少。最近嘗試從頭實現一個簡單的HTTP服務器,主要開發環境在Linux,因此借此契機熟悉一下CMake等構建工具的使用。

目錄結構

目前項目文件較少,使用了較簡單的目錄結構

┣━ src
┃   ┣━ CMakeLists.txt
┃   ┣━ HttpRequest.cpp
┃   ┣━ HttpResponse.cpp
┃   ┣━ HttpServer.cpp
┃   ...
┣━ include
┃   ┣━ HttpRequest.h
┃   ┣━ HttpResponse.h
┃   ┣━ HttpServer.h
┃   ...
┣━ cmake-build-debug
┃   ┣━...
┃   ┗━...
┣━ main.cpp
┣━ CMakeLists.txt

可以看到源文件和頭文件分別存儲在對應目錄中,根目錄下以main.cpp作為程序入口,最終構建目標及中間文件存放在cmake-build-debug這一獨立文件夾中。

CMakeLists編寫

為了使上述目錄結構能夠正確編譯鏈接,我們需要編寫CMakeLists.txt,同時CMake能夠一定程度上減少多文件多目錄時來回鏈接順序等頭疼的問題。在這個項目里,根目錄下和src目錄下各有一個CMakeLists.txt文件,這也是CMake的特點,可以將Makefile拆分,每個目錄各自進行編譯,最終鏈接起來。

根目錄下的CMakeLists.txt內容如下

cmake_minimum_required (VERSION 2.6)

add_definitions(-std=c++11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g -Wall -Wno-unused-variable -pthread")

project (Minihttpd)

include_directories(include)
add_subdirectory(src)

# 順序不可修改,先link_directories 再 add_executable 最后 target_link_libraries
link_directories(/usr/local/lib)

add_executable(Minihttpd main.cpp)

target_link_libraries(Minihttpd src)
target_link_libraries(Minihttpd -lconfig++)

接下來對每條語句進行簡單的解釋

  • add_definations 指令可以用來手動設置某些宏的開閉,控制編譯選項,這里主要是標注使用c++11標準
  • set指令能夠用前面的變量替代后面的字符串,這里實際上是對預定義的CMAKE_CXX_FLAGS變量進行了一個修改,來設置某些選項,主要鏈接pthread庫使用多線程
  • project指令用來設置項目名(包括版本、所用語言等信息,這里缺省)
  • include_directories指令用來指定尋找頭文件的路徑,這里把include目錄加入到頭文件搜索范圍內,使得項目內文件可以找到對應頭文件
  • add_subdirectory指令用來把子目錄加入到構建列表中,最終構建結果存放在src變量中

之后的幾行是在項目需要引用其他動態鏈接庫,非常需要注意的地方

  • add_executable指令用來指定項目最終構建的目標文件,以及所需要的所有源文件。可以看到這里只有main.cpp,為什么沒有包含src目錄下其他源文件?這里其實在下面使用 target_link_libraries 指令,以動態鏈接庫的形式引入進來。其順序是在子目錄中首先進行了部分構建,在src目錄下生成了相應的libsrc.a文件,最終鏈接到程序入口文件上,實現了構建。
  • link_directories和target_link_libraries指令用來引入外部的動態鏈接庫。其中
    • link_directories用來指定該動態鏈接庫所在目錄
    • target_link_libraries用來把所需的動態鏈接庫引入到該項目中

這里非常需要注意的是幾條語句的順序,一定是

  1. link_directories 把動態鏈接庫所在目錄加入尋找列表中
  2. add_executable 指定最終構建目標名稱
  3. target_link_libraries 把需要的動態鏈接庫加入到項目中

這里的順序錯誤將導致鏈接失敗,出現找不到動態鏈接庫等各種問題(踩過的坑,心酸的淚)

子目錄下的CMakeLists.txt內容如下

aux_source_directory(. srcs)
add_library(src ${srcs})

這里的內容就非常簡單

  • aux_source_directory指令把當前目錄下所有源文件加入到srcs變量中存儲
  • add_library使用srcs變量中所有源文件進行構建,結果輸出為src。不同于add_executable,add_library的構建的最終目標為動態鏈接庫文件,而add_executable的構建結果為一個可執行文件。這里構建成動態鏈接庫文件也是為了在根目錄下構建時進行鏈接

擴展

在理解了多目錄下CMakeLists的編寫后,如果需要把源文件存放在多個不同目錄中,也可以以動態鏈接庫的形式分別進行構建、鏈接。而對于多級目錄,也可以依次逐級構建并鏈接。

對于需要引用的外部動態鏈接庫,也可以通過link_directories和target_link_libraries指令的配合進行引入。

同時本項目內使用了ninja作為構建工具,更方便了項目的構建,主要使用方法為

cd cmake-build-debug
cmake -G Ninja ..     //cmake支持根據CMakeLists.txt自動化生成ninja構建所需要的ninja.build等文件
ninja                 //在該目錄下構建
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,034評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,327評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,337評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,883評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,114評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,625評論 1 332
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,555評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,737評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,973評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,343評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,699評論 2 370