国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Makefile——Linux下C/C++編譯方法

這篇具有很好參考價值的文章主要介紹了Makefile——Linux下C/C++編譯方法。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1. C

linux下常見的C語言項目相關(guān)的文件如下圖所示。
linux怎么編譯c++文件,c++,linux,makefile

1.1 編譯C

通常使用GCC來編譯C文件。編譯過程為源文件.c文件 -> 預(yù)編譯成.i文件 -> 編譯成匯編語言.s -> 匯編成.o文件 -> 鏈接成可執(zhí)行文件。編譯命令為gcc -參數(shù) .c -o 輸出文件名稱

  1. 預(yù)處理:將頭文件拷貝進(jìn).c文件內(nèi)容中,執(zhí)行預(yù)編譯命令。采用gcc -E命令
gcc -E [.c源文件] -o [輸出文件名.i]
  1. 編譯成匯編:將c語言代碼編譯為對應(yīng)的匯編指令。采用gcc -S命令
gcc -S [.c源文件] -o [輸出文件名.s]
  1. 編譯成目標(biāo)文件:二進(jìn)制文件
gcc -c [.c源文件] [.c源文件] [...] -o [文件名]
  1. 編譯成可執(zhí)行文件:
gcc [.c源文件] [.c源文件] [...] -o [輸出文件名]
gcc [.c源文件] [.c源文件] [...] -o [輸出文件名] -l[庫名] -L[庫所在路徑]

1.2 創(chuàng)建靜態(tài)庫

程序庫是已寫好的、供使用的可復(fù)用代碼,每個程序都要依賴很多基礎(chǔ)的底層庫。從本質(zhì)上,庫是一種可執(zhí)行代碼的二進(jìn)制形式。靜態(tài)庫可以在編譯c項目時,將引用的庫一起鏈接到可執(zhí)行文件中,可執(zhí)行文件在運(yùn)行時不再需要庫的支持,但可執(zhí)行文件會變大。

  1. 將庫的.c源文件編譯成.o目標(biāo)文件
gcc -c [.c] -o [自定義文件名] 
gcc -c [.c] [.c] ...
  1. 將.o目標(biāo)文件編譯成靜態(tài)庫
ar -r [lib自定義庫名.a] [.o] [.o] ...
  1. 將C程序和靜態(tài)庫鏈接,編譯成可執(zhí)行文件。庫名為lib***.a的***。
gcc [.c] -o [輸出文件名] -l[庫名] -L[庫所在路徑]

1.3 創(chuàng)建動態(tài)庫

動態(tài)庫在程序編譯時不會鏈接到目標(biāo)代碼中,而是在程序運(yùn)行時才被調(diào)用,可執(zhí)行文件比靜態(tài)鏈接的可執(zhí)行文件要小。不同的程序可以共享相同的動態(tài)庫。

  1. 將庫的.c源文件編譯成.o目標(biāo)文件(要加入-fpic選項)
gcc -c -fpic [.c/.cpp][.c/.cpp]... 
  1. 將.o目標(biāo)文件編譯成動態(tài)庫
gcc -shared [.o][.o]... -o [lib自定義庫名.so]

#將1和2合并為一步
gcc -fpic -shared [.c源文件] [.c源文件] [...] -o lib[庫名].so
  1. 將C程序和動態(tài)庫鏈接,編譯成可執(zhí)行文件。庫名為lib***.so的***。
gcc [.c/.cpp] -o [自定義可執(zhí)行文件名]  -l[庫名] -L[庫路徑] -Wl,-rpath=[庫路徑]

2. C++

編譯C++的流程與編譯C幾乎一致,只不過用的時g++命令。將上述編譯.c的gcc改為g++即可編譯cpp文件。靜態(tài)庫與動態(tài)庫同理。

3. Makefile

makefile是自動化編譯的一款工具。實際中C/C++工程項目可能十分龐大,直接用手一條一條的敲gcc/g++效率極低。在makefile文件中編寫編譯流程可以簡化編譯工作。

  • make 會在當(dāng)前目錄下找到一個名字叫 Makefile 或 makefile 的文件
  • 如果找到,它會找文件中第一個目標(biāo)文件(target),并把這個文件作為最終的目標(biāo)文件
  • 如果 target 文件不存在,或是 target 文件依賴的 .o 文件(prerequities)的文件修改時間要比 target 這個文件新,就會執(zhí)行后面所定義的命令 command 來生成 target 這個文件
  • 如果 target 依賴的 .o 文件(prerequisties)也存在,make 會在當(dāng)前文件中找到 target 為 .o 文件的依賴性,如果找到,再根據(jù)那個規(guī)則生成 .o 文件
#makefile格式
targets : prerequisties
[tab鍵]command

targets為生成的目標(biāo)文件;
prerequisties為為了生成targets目標(biāo)而所需的依賴目標(biāo)文件;
conmmand為需要運(yùn)行的命令

為了避免 target 和 Makefile 同級目錄下 文件/文件夾 重名的這種情況,我們可以使用一個特殊的標(biāo)記 .PHONY 來顯式地指明一個目標(biāo)是 “偽目標(biāo)”,如下例中的clean

.PHONY : clean

3.1 變量

  1. 變量定義用:=
cpp := src/main.cpp 
obj := objs/main.o
  1. 使用變量()或{}
cpp := src/main.cpp 
obj := objs/main.o

$(obj) : ${cpp} #cpp中的字符串代表的依賴文件,obj為生成的目標(biāo)文件
	@g++ -c $(cpp) -o $(obj)  
	#等價于g++ -c src/main.cpp -o objs/main.o
compile : $(obj) #compile為偽目標(biāo),可執(zhí)行make compile命令
  1. 預(yù)定義變量:
    $@: 目標(biāo)(target)的完整名稱
    $<: 第一個依賴文件(prerequisties)的名稱
    $^: 所有的依賴文件(prerequisties),以空格分開,不包含重復(fù)的依賴文件
cpp := src/main.cpp 
obj := objs/main.o

$(obj) : ${cpp}
	@g++ -c $< -o $@
	#等價于g++ -c src/main.cpp -o objs/main.o
	@echo $^
	#執(zhí)行shell命令echo,打印出cpp的內(nèi)容

compile : $(obj)
.PHONY : compile
  1. 特殊符號:\為續(xù)行符,*通配符(匹配任意字符串,可用與目錄名和文件名中),%通配符(匹配任意字符串,并將匹配到的字符串作為變量使用)

3.2 常用函數(shù)

函數(shù)執(zhí)行格式通常為$(fn, arguments) or ${fn, arguments}

  1. shell:調(diào)用shell命令,返回shell命令執(zhí)行結(jié)果,使用格式為
    $(shell <command> <arguments>)
# shell 指令,src 文件夾下找到 .cpp 文件
cpp_srcs := $(shell find src -name "*.cpp") 
# shell 指令, 獲取計算機(jī)架構(gòu)
HOST_ARCH := $(shell uname -m)
  1. subst:把字串 <text> 中的 <from> 字符串替換成 <to>,使用格式為
    $(subst <from>,<to>,<text>)
cpp_srcs := $(shell find src -name "*.cpp")
cpp_objs := $(subst src/,objs/,$(cpp_objs)) 
  1. patsubst:從 text 中取出 patttern(其中%為通配符), 替換成 replacement,使用格式為 $(patsubst <pattern>,<replacement>,<text>)
cpp_srcs := $(shell find src -name "*.cpp") #shell指令,src文件夾下找到.cpp文件
cpp_objs := $(patsubst %.cpp,%.o,$(cpp_srcs)) #cpp_srcs變量下cpp文件替換成 .o文件
  1. foreach:把字串<list>中的元素逐一取出來,執(zhí)行<text>包含的表達(dá)式,使用格式為 $(foreach <var>,<list>,<text>)
library_paths := /lib \
                 /usr/local/lib64
#每一個元素前面加上-I
I_flag := $(foreach item,$(library_paths),-I$(item))
#等價于
I_flag := $(include_paths:%=-I%)
  1. dir:從文件路徑+文件名字符串序列中取出目錄部分,使用格式為
    $(dir <names…>)
$(dir src/foo.c hacks)    # 返回值是“src/ ./”。
  1. notdir:與dir函數(shù)相反,去除目錄部分,只保留文件名
#嵌套使用,先用shell中的find命令尋找lib開頭的文件,然后去掉這些文件的目錄前綴
libs   := $(notdir $(shell find /usr/lib -name lib*))
  1. filter:從字符串序列中,過濾出滿足條件的
libs    := $(notdir $(shell find /usr/lib -name lib*))
a_libs  := $(filter %.a,$(libs)) #過濾出靜態(tài)庫
so_libs := $(filter %.so,$(libs))  #過濾出動態(tài)庫
  1. basename:去掉文件名后綴
libs    := $(notdir $(shell find /usr/lib -name lib*))
#去掉后綴和lib前綴,得到庫名
a_libs  := $(subst lib,,$(basename $(filter %.a,$(libs))))
so_libs := $(subst lib,,$(basename $(filter %.so,$(libs))))
  1. filter-out:去除不要的字符串
objs := objs/add.o objs/minus.o objs/main.o
cpp_objs := $(filter-out objs/main.o, $(objs))

3.3 makefile編譯文件

編譯選項:
-m64: 指定編譯為 64 位應(yīng)用程序
-std=: 指定編譯標(biāo)準(zhǔn),例如:-std=c++11、-std=c++14
-g: 包含調(diào)試信息
-w: 不顯示警告
-O: 優(yōu)化等級,通常使用:-O3
-I: 加在頭文件路徑前
fPIC: (Position-Independent Code), 產(chǎn)生的沒有絕對地址,全部使用相對地址,代碼可以被加載到內(nèi)存的任意位置,且可以正確的執(zhí)行。這正是共享庫所要求的,共享庫被加載時,在內(nèi)存的位置不是固定的

鏈接選項:
-l: 加在庫名前面
-L: 加在庫路徑前面
-Wl,<選項>: 將逗號分隔的 <選項> 傳遞給鏈接器
-rpath=: “運(yùn)行” 的時候,去找的目錄。運(yùn)行的時候,要找 .so 文件,會從這個選項里指定的地方去找文章來源地址http://www.zghlxwxcb.cn/news/detail-776537.html

cpp_srcs := $(shell find src -name *.cpp)
cpp_objs := $(patsubst src/%.cpp,objs/%.o,$(cpp_srcs))

include_dirs :=/home/include
I_options := $(include_dirs:%=-I%)
compile_options := -g -O3 -w $(I_options)

lib_dirs := /home/lib #庫路徑
link_libs := xxx      #庫名
L_options := $(lib_dirs:%=-L%)
l_options := $(link_libs:%=-l%)
link_options := $(l_options) $(L_options) $(I_options)

#每個.cpp生成一個對應(yīng)的目標(biāo)文件
objs/%.o : src/%.cpp
	#創(chuàng)建文件夾,@表示make的時候不打印make信息
	@mkdir -p $(dir $@)
	@g++ -c $^ -o $@ $(compile_options)

workspace/exec : $(cpp_objs)
	@mkdir workspace/exec
	@g++ $^ -o $@ $(link_options)
	
# 輸入make run即可生成run偽目標(biāo)
run : workspace
	@./$<
	
# 輸入make clean即可生成clean偽目標(biāo)
clean :
	@rm -rf objs workspace/exec

debug :
	@echo $(as_files)

.PHONY : debug run clean

到了這里,關(guān)于Makefile——Linux下C/C++編譯方法的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【嵌入式Linux】編譯應(yīng)用和ko內(nèi)核模塊Makefile使用記錄

    【嵌入式Linux】編譯應(yīng)用和ko內(nèi)核模塊Makefile使用記錄

    在Makefile中,變量的賦值可以使用以下幾種方式: = :最基本的賦值符號,表示簡單的延遲展開(lazy expansion)方式。變量的值將會在使用變量的時候進(jìn)行展開。 := :立即展開(immediate expansion)的賦值方式。變量的值在賦值的時候立即展開,并且在后續(xù)的使用中不再改變。

    2024年02月08日
    瀏覽(24)
  • 【Linux】Linux編譯器-gcc/g++ && Linux項目自動化構(gòu)建工具-make/Makefile

    【Linux】Linux編譯器-gcc/g++ && Linux項目自動化構(gòu)建工具-make/Makefile

    目錄 Linux編譯器-gcc/g++使用 1.背景知識 ?Linux中頭文件的目錄在 Linux 庫 條件編譯的典型應(yīng)用 2.gcc如何完成 動態(tài)庫 vs 靜態(tài)庫 debug release Linux項目自動化構(gòu)建工具-make/Makefile 背景 用法 特殊符號? 預(yù)處理(去注釋,頭文件展開,條件編譯,宏替換) 編譯(生成匯編) 匯編(生成

    2024年02月20日
    瀏覽(33)
  • 【Linux】gcc編譯過程、make和makefile的概念與區(qū)別、Linux簡單進(jìn)度條實現(xiàn)

    【Linux】gcc編譯過程、make和makefile的概念與區(qū)別、Linux簡單進(jìn)度條實現(xiàn)

    ??1. 預(yù)處理(進(jìn)行宏替換) ??2. 編譯(生成匯編) ??3. 匯編(生成機(jī)器可識別代碼) ??4. 連接(生成可執(zhí)行文件或庫文件) ??預(yù)處理(Preprocessing):在這個階段,gcc會對源代碼進(jìn)行預(yù)處理,主要包括處理宏定義、頭文件包含、條件編譯等操作。預(yù)處理器會根據(jù)預(yù)處

    2024年02月12日
    瀏覽(22)
  • Linux下gcc編譯,動態(tài)庫和靜態(tài)庫,makefile,gdb調(diào)試

    Linux下gcc編譯,動態(tài)庫和靜態(tài)庫,makefile,gdb調(diào)試

    展開頭文件, 宏替換(變量宏、函數(shù)宏)、替換空格等 逐行檢查程序中出現(xiàn)的語法錯誤,簡單的邏輯錯誤 將 .s 匯編文件中所有的匯編指令翻譯成二進(jìn)制機(jī)器碼(下面就是來了個截圖,二進(jìn)制顯示了亂碼) 將 .o 的目標(biāo)文件,鏈接庫文件、數(shù)據(jù)段合并,地址回填(把匯編里相

    2024年02月08日
    瀏覽(52)
  • Linux(基礎(chǔ)IO、文件權(quán)限、Makefile)

    Linux(基礎(chǔ)IO、文件權(quán)限、Makefile)

    目錄 1、man 手冊 1.1 漢化 1.2 具體使用 2、文件權(quán)限 2.1 權(quán)限理解 2.2 文件詳細(xì)信息查詢 2.3 權(quán)限更改 3、常用函數(shù)接口 3.1 open 3.2 read 3.3?write 3.4?close 3.5 函數(shù)使用示例 4、make與Makefile 4.1 make 與 Makefile區(qū)別 4.2 Makefile的編寫 5、vim簡單操作 安裝中文包 使用三種方式查詢open接口的詳

    2024年02月11日
    瀏覽(42)
  • Linux驅(qū)動開發(fā)筆記(一):helloworld驅(qū)動源碼編寫、makefile編寫以及驅(qū)動編譯基本流程

    Linux驅(qū)動開發(fā)筆記(一):helloworld驅(qū)動源碼編寫、makefile編寫以及驅(qū)動編譯基本流程

    若該文為原創(chuàng)文章,轉(zhuǎn)載請注明原文出處 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/130534343 紅胖子網(wǎng)絡(luò)科技博文大全:開發(fā)技術(shù)集合(包含Qt實用技術(shù)、樹莓派、三維、OpenCV、OpenGL、ffmpeg、OSG、單片機(jī)、軟硬結(jié)合等等)持續(xù)更新中… 上一篇:沒有了 下一篇:《Linu

    2024年02月08日
    瀏覽(26)
  • 【Linux】--- Linux編譯器-gcc/g++、調(diào)試器-gdb、項目自動化構(gòu)建工具-make/Makefile 使用

    【Linux】--- Linux編譯器-gcc/g++、調(diào)試器-gdb、項目自動化構(gòu)建工具-make/Makefile 使用

    格式: gcc [選項] 要編譯的文件 [選項] [目標(biāo)文件] , gcc / g++ 安裝: sudo yum install -y gcc-c++ 。安裝后的編譯器默認(rèn)的版本是較低的,我們可以 使用選項 -std=c99 (即使用c99標(biāo)準(zhǔn)), -std=c++11 (即使用c++11的標(biāo)準(zhǔn))來進(jìn)行版本提升 。使用 -o 選項,可以將編譯生成的可執(zhí)行重命名

    2024年03月10日
    瀏覽(26)
  • 韋東山Linux教學(xué)視頻中的makefile文件詳細(xì)介紹

    韋東山Linux教學(xué)視頻中的makefile文件詳細(xì)介紹

    (1)在學(xué)習(xí)韋東山Linux教學(xué)視頻的時候,他的makefile并沒有做詳細(xì)的介紹。以至于我學(xué)了很長時間對他的makefile文件不理解。所以本文將會詳細(xì)介紹韋東山Linux教學(xué)視頻中的makefile文件含義。 (2)注意:我使用的是韋東山的配套i.max6ull pro開發(fā)板。 如果是其他系列開發(fā)板,mak

    2024年02月16日
    瀏覽(22)
  • Linux驅(qū)動開發(fā)筆記(三):基于ubuntu的helloworld驅(qū)動源碼編寫、makefile編寫以及驅(qū)動編譯加載流程測試

    Linux驅(qū)動開發(fā)筆記(三):基于ubuntu的helloworld驅(qū)動源碼編寫、makefile編寫以及驅(qū)動編譯加載流程測試

    若該文為原創(chuàng)文章,轉(zhuǎn)載請注明原文出處 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/130542981 紅胖子網(wǎng)絡(luò)科技博文大全:開發(fā)技術(shù)集合(包含Qt實用技術(shù)、樹莓派、三維、OpenCV、OpenGL、ffmpeg、OSG、單片機(jī)、軟硬結(jié)合等等)持續(xù)更新中… 上一篇:《Linux驅(qū)動開發(fā)筆記(二

    2024年02月05日
    瀏覽(30)
  • C語言,Linux,靜態(tài)庫編寫方法,makefile與shell腳本的關(guān)系。

    C語言,Linux,靜態(tài)庫編寫方法,makefile與shell腳本的關(guān)系。

    靜態(tài)庫編寫: 編寫.o文件 gcc -c( 小寫) seqlist.c(需要和頭文件、main.c文件在同一文件目錄下) libs.a- 去掉lib與.a剩下的為庫的名稱‘s’。 -ls 是指庫名為s。 -L 庫的路徑。 makefile文件編寫: 這個是編譯后的文件,app文件為編譯后的二進(jìn)制文件。? ? ? makefile與shell腳本關(guān)系 shell?腳

    2024年02月12日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包