想玩兒github開源,怎能對make场靴、cmake一知半解啡莉?

如果要接觸源碼,就不可避免地要觸及 編譯(python這種不需要編譯的 解釋性語言 源碼除外V及_中馈!)為了完成編譯動作轨帜,我們有眾多的編譯工具魄咕,很多情況下,編譯工具的調(diào)用被集成到了 IDE 當(dāng)中蚌父。然而哮兰,如果上手一些開源項目,我們會發(fā)現(xiàn)梢什,更常見到的是「奇奇怪怪」的 MakeFileCMakeLists.txt奠蹬。我們參照 ReadMe 的教程朝聋,裝這個裝那個嗡午,然后運行同樣奇奇怪怪的 makecmake 命令……折騰半天或許成功完成了編譯……但腦子是否還是一片混沌冀痕?別說定制修改MakeFileCMakeLists.txt荔睹,甚至連自己做了些什么都無法記憶起來……Why?

因為我們沒理清Ta們?yōu)槭裁创嬖冢?/em>

認(rèn)識 make & cmake,我們先看看可執(zhí)行文件是如何生成的

一言蛇、從 main.c 到 可執(zhí)行文件 輸出 Hello World

我們編輯一份最簡單的 main.c 文件(認(rèn)真上過1節(jié)C語言課的同學(xué)該都可以看懂)僻他,并期望經(jīng)過編譯將其變?yōu)榭蓤?zhí)行文件,然后運行輸出Hello World腊尚。

#include <stdio.h>

int main(int argc, char * argv[]) {
    printf("\nHello World!\n");
    return 0;
}

Step1:預(yù)處理 Preprocess

預(yù)處理即將源文件中的宏吨拗、頭文件進(jìn)行 ”展開“

參考命令:
gcc -E main.c -o main_preprocess.c
預(yù)處理展開

Step2:匯編 Assembly

匯編可以將預(yù)處理后的代碼轉(zhuǎn)換為匯編語言婿斥,看看下面的匯編語言是不是特別「優(yōu)美」捏劝篷!

參考命令:
gcc -S main_preprocess.c
匯編

Step3:生成機(jī)器語言

機(jī)器語言(二進(jìn)制命令語言)即計算機(jī)可以識別的語言,匯編代碼可以進(jìn)一步轉(zhuǎn)化為機(jī)器語言

參考命令:
gcc -c main.s
匯編

Step4:鏈接

將多個二進(jìn)制文件(.o文件民宿,雖然當(dāng)前只有一個main.o)鏈接成一個文件娇妓,根據(jù)需求,可能是一個lib活鹰,也可能是一個可執(zhí)行文件哈恰。

參考命令:
gcc  main.o -o main
鏈接

Step5:執(zhí)行

向世界問好吧V还馈:)

你好世界

二、用gcc着绷、make蛔钙、cmake編譯同一套代碼

2.1:使用gcc編譯

GCC 是一個linux下的常用的編譯工具。我們擬寫了如下的源文件荠医,并嘗試用 GCC 對齊進(jìn)行編譯:

- ./main.c -

#include "submodule.h"

int main(int argc, char * argv[]) {
    subTest(10);
    return 0;
}
- ./include/submodule.h -

#include <stdio.h>

int subTest(int a);
- ./submodule/submodule.c - 

#include "submodule.h"

int subTest(int a) {
    printf("\n<%s:%d> Function Called... %d \n\n", __func__, __LINE__, a);
    return 1;
}

gcc的命令很簡單夸楣,只要如下 4條命令 就能完成可執(zhí)行文件 main 的編譯和調(diào)用:

# 1 生成subModel的二進(jìn)制文件(.o)
gcc ./submodule/submodule.c -c -I ./include -o ./submodule.o

# 2 生成main的二進(jìn)制文件(.o)
gcc ./main.c -c -I ./include -o ./main.o

# 3 鏈接二進(jìn)制文件
gcc ./submodule.o ./mian.o -o ./main

# 4 執(zhí)行可執(zhí)行文件
./main

2.2 構(gòu)造MakeFile文件,使用make編譯

我們?yōu)槭裁匆?strong>MakeFile子漩?如果是為了封裝命令豫喧,方便調(diào)用,我們完全可以將相關(guān)的編譯命令放置到一個shell腳本中幢泼,MakeFile 有什么其他優(yōu)勢呢紧显?

1)它封裝一套簡單的指定編譯目標(biāo)的語法,這比寫shell的參數(shù)解析簡單得多
2)藉由這套語法缕棵,make封裝了編譯依賴孵班、增量編譯等邏輯。即大型工程進(jìn)行小范圍局部改動時候招驴,重新的編譯的速度會非掣莩蹋快。(未涉及改動的內(nèi)容不會重編)

那么别厘,同樣的 mainsubmodule虱饿,使用 MakeFile 我們可以編輯兩個 MakeFile 文件

- ./MakeFile -

INCLUDE_PATH := ./include
SRCS += $(wildcard ./*.c)
OBJS += $(SRCS:.c=.o)

SUB_DIR = ./submodule
SUB_SRCS = $(wildcard ${SUB_DIR}/*.c)
SUB_OBJS += $(SUB_SRCS:.c=.o)

TARGET := main

all: clean build linkobjs
    
linkobjs:
    gcc ${OBJS} ${SUB_OBJS} -o ${TARGET}
    
build:
    cd ${SUB_DIR} && make build
    gcc -c ${SRCS} -I${INCLUDE_PATH}
    
clean:
    cd ${SUB_DIR} && make clean
    rm -rf ${OBJS}
    rm -rf ${TARGET} 
- ./submodule/MakeFile - 

INCLUDE_PATH := ../include
SRCS += $(wildcard ./*.c)
OBJS += $(wildcard ./*.o)

all: clean build

build:
    gcc -c ${SRCS} -I${INCLUDE_PATH}

clean:
    rm -rf ${OBJS}

然后,在 main.c 所在的目錄執(zhí)行 make all 就好啦

編寫好MakeFile触趴,執(zhí)行make all

關(guān)于MakeFile氮发,有幾個 tips 可能對大家上手有幫助:
1)其完成支持語法和Shell腳本是有些相似的
2)各個編譯目標(biāo)下可以執(zhí)行 linux 命令
3)編譯目標(biāo)要執(zhí)行的命令,前面要加4個空格(這個和 python 的函數(shù)語法有些相似)
4)示例中的「all : clean build」表示「make all」等同于順序執(zhí)行「make clean」「make build」

2.3 構(gòu)造CMakeLists.txt冗懦,使用 cmake 命令生成MakeFile爽冕,再make

cmake 定義了另一套語法來組織 CMakeLists.txt 文件,然后通過 cmake 命令可以結(jié)合 CMakeLists.txt 文件的”配置“生成 MakeFile披蕉,然后再……make……

最終同樣是使用MakeFile颈畸,干嘛加一步再讓大家學(xué)習(xí)cmake的語法呢?

原來没讲,不同平臺(linux眯娱、Windows、Macos……)的編譯環(huán)境是有差異的食零,為了應(yīng)對這種差異困乒,各平臺編譯所需的 MakeFile 文件也各不相同。而 cmake 抽象了一套上層的編譯配置語法贰谣,并負(fù)責(zé)了將Ta針對平臺進(jìn)行 MakeFile 文件翻譯的任務(wù)娜搂。

還是同樣的 mainsubmodule迁霎,使用 cmake 我們將構(gòu)造兩個 CMakeLists.txt 文件:

- ./CMakeLists.txt -

# cmake最低版本約定
cmake_minimum_required(VERSION 2.8)

# 工程名稱
project(main)

# 宏開關(guān)
option(DT "Demo Test Switch" OFF)
if(DT)
add_definitions("-DDEMO_TEST=1")
endif()

# include目錄
include_directories(./include)

# 子模塊文件目錄
add_subdirectory(./submodule)

# 查找當(dāng)前文件夾源文件
aux_source_directory(. SRCS)

# 生成可執(zhí)行文件
add_executable(main ${SRCS})

# 可執(zhí)行文件鏈接靜態(tài)庫
target_link_libraries(main submodule)

- ./submodule/CMakeLists.txt - 

# cmake最低版本約定
cmake_minimum_required(VERSION 2.8)

# include目錄
include_directories(../include)

# 查找當(dāng)前文件夾源文件
aux_source_directory(. SRCS)

# 生成靜態(tài)鏈接庫
add_library(submodule ${SRCS})

然后,我們創(chuàng)建一個 build 文件夾百宇,并進(jìn)行 cmake

mkdir build
cd build
cmake ../

build 目錄下回生成一系列文件考廉,我們可以理解Ta們都是為了支持 Makefile 存在的就好。??

cmake生成的MakeFile

那么携御,在 build 下執(zhí)行 make 吧昌粤!

make

成功編譯出我們的目標(biāo)。??

目標(biāo)出現(xiàn)了

有沒有發(fā)現(xiàn) cmake 的另一點「優(yōu)雅」:Ta能將所有的編譯信息有效地管理在一個文件夾下啄刹!當(dāng)我們想清理編譯數(shù)據(jù)時涮坐,只需要刪除build文件夾就好了。

三誓军、草草結(jié)束

相關(guān)的示例代碼我放在了 這里
然后看看之前在 github 上遇到的 Makefile袱讹、CMakeLists.txt 文件,現(xiàn)在能看懂一些了嘛昵时?
還有問題也可以留言交流哦~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末捷雕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子壹甥,更是在濱河造成了極大的恐慌救巷,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件句柠,死亡現(xiàn)場離奇詭異浦译,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)俄占,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門管怠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來淆衷,“玉大人缸榄,你說我怎么就攤上這事∽U” “怎么了甚带?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長佳头。 經(jīng)常有香客問我鹰贵,道長,這世上最難降的妖魔是什么康嘉? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任碉输,我火速辦了婚禮,結(jié)果婚禮上亭珍,老公的妹妹穿的比我還像新娘敷钾。我一直安慰自己枝哄,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布阻荒。 她就那樣靜靜地躺著挠锥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪侨赡。 梳的紋絲不亂的頭發(fā)上蓖租,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天,我揣著相機(jī)與錄音羊壹,去河邊找鬼蓖宦。 笑死,一個胖子當(dāng)著我的面吹牛油猫,可吹牛的內(nèi)容都是我干的球昨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼眨攘,長吁一口氣:“原來是場噩夢啊……” “哼主慰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起鲫售,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤共螺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后情竹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體藐不,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年秦效,在試婚紗的時候發(fā)現(xiàn)自己被綠了雏蛮。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡阱州,死狀恐怖挑秉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情苔货,我是刑警寧澤犀概,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站夜惭,受9級特大地震影響姻灶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜诈茧,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一产喉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦曾沈、人聲如沸尘颓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽疤苹。三九已至,卻和暖如春敛腌,著一層夾襖步出監(jiān)牢的瞬間卧土,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工像樊, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留尤莺,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓生棍,卻偏偏與公主長得像颤霎,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子涂滴,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354