www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 公眾號精選 > C語言編程
[導(dǎo)讀]一、文件我們將該項(xiàng)目的所有功能函數(shù)放到以該函數(shù)名命名的c文件,同時放到對應(yīng)名稱的子目錄中。比如函數(shù)allfree(),存放到allfree/allfree.c中最終目錄結(jié)構(gòu)如下圖所示:?peng@ubuntu:/mnt/hgfs/code/phone$?tree?..├──?al...


一、文件

我們將該項(xiàng)目的所有功能函數(shù)放到以該函數(shù)名命名的c文件,同時放到對應(yīng)名稱的子目錄中。

比如函數(shù)allfree(),存放到 allfree/allfree.c中

最終目錄結(jié)構(gòu)如下圖所示:

?peng@ubuntu:/mnt/hgfs/code/phone$?tree?.
.
├──?allfree
│???├──?allfree.c
│???└──?Makefile
├──?create
│???├──?create.c
│???└──?Makefile
├──?delete
│???├──?delete.c
│???└──?Makefile
├──?display
│???├──?display.c
│???└──?Makefile
├──?include
│???├──?Makefile
│???└──?phone.h
├──?init
│???├──?init.c
│???└──?Makefile
├──?login
│???├──?login.c
│???└──?Makefile
├──?main
│???├──?main.c
│???└──?Makefile
├──?Makefile
├──?menu
│???├──?Makefile
│???└──?menu.c
├──?scripts
│???└──?Makefile
└──?search
????├──?Makefile
????└──?search.c

11?directories,?22?files
直接看下編譯結(jié)果吧:

peng@ubuntu:/mnt/hgfs/code/phone$?make
make[1]:?Entering?directory?'/mnt/hgfs/code/phone/allfree'
make[1]:?Nothing?to?be?done?for?'all'.
make[1]:?Leaving?directory?'/mnt/hgfs/code/phone/allfree'
make[1]:?Entering?directory?'/mnt/hgfs/code/phone/create'
make[1]:?Nothing?to?be?done?for?'all'.
make[1]:?Leaving?directory?'/mnt/hgfs/code/phone/create'
make[1]:?Entering?directory?'/mnt/hgfs/code/phone/delete'
make[1]:?Nothing?to?be?done?for?'all'.
make[1]:?Leaving?directory?'/mnt/hgfs/code/phone/delete'
make[1]:?Entering?directory?'/mnt/hgfs/code/phone/display'
make[1]:?Nothing?to?be?done?for?'all'.
make[1]:?Leaving?directory?'/mnt/hgfs/code/phone/display'
make[1]:?Entering?directory?'/mnt/hgfs/code/phone/init'
make[1]:?Nothing?to?be?done?for?'all'.
make[1]:?Leaving?directory?'/mnt/hgfs/code/phone/init'
make[1]:?Entering?directory?'/mnt/hgfs/code/phone/login'
make[1]:?Nothing?to?be?done?for?'all'.
make[1]:?Leaving?directory?'/mnt/hgfs/code/phone/login'
make[1]:?Entering?directory?'/mnt/hgfs/code/phone/menu'
make[1]:?Nothing?to?be?done?for?'all'.
make[1]:?Leaving?directory?'/mnt/hgfs/code/phone/menu'
make[1]:?Entering?directory?'/mnt/hgfs/code/phone/search'
make[1]:?Nothing?to?be?done?for?'all'.
make[1]:?Leaving?directory?'/mnt/hgfs/code/phone/search'
make[1]:?Entering?directory?'/mnt/hgfs/code/phone/main'
make[1]:?Nothing?to?be?done?for?'all'.
make[1]:?Leaving?directory?'/mnt/hgfs/code/phone/main'
gcc?-Wall?-O3?-o?phone?allfree/*.o?create/*.o?delete/*.o?display/*.o?init/*.o?login/*.o?menu/*.o?search/*.o?main/*.o?-lpthread
phone?make?done!?
運(yùn)行結(jié)果如下:

二、Makefile常用基礎(chǔ)知識點(diǎn)

[0] 符號'@' '$' '$$' '-' '-n '的說明

  1. '@'
    通常makefile會將其執(zhí)行的命令行在執(zhí)行前輸出到屏幕上。如果將‘@’添加到命令行前,這個命令將不被make回顯出來。例如:
@echo??--compiling?module----;??//?屏幕輸出??--compiling?module----
echo??--compiling?module----;??//?沒有@?屏幕輸出echo??--compiling?module----???
  1. ' - '
通常刪除,創(chuàng)建文件如果碰到文件不存在或者已經(jīng)創(chuàng)建,那么希望忽略掉這個錯誤,繼續(xù)執(zhí)行,就可以在命令前面添加 -,

-rm dir;
-mkdir aaadir;
  1. ' $ '美元符號$,主要擴(kuò)展打開makefile中定義的變量

  2. ' $$ '$$ 符號主要擴(kuò)展打開makefile中定義的shell變量

[1] wildcard

說明: 列出當(dāng)前目錄下所有符合模式“ PATTERN”格式的文件名,并且以空格分開?!?PATTERN”使用shell可識別的通配符,包括“ ?”(單字符)、“ *”(多字符)等。示例:

$(wildcard?*.c)?
返回值為當(dāng)前目錄下所有.c 源文件列表。

[2] patsubst

說明:把字串“ x.c.c bar.c”中以.c 結(jié)尾的單詞替換成以.o 結(jié)尾的字符。示例:

$(patsubst?%.c,%.o,x.c.c?bar.c)
函數(shù)的返回結(jié)果 是

?x.c.o?bar.o

[3] notdir

說明:去除文件名中的路徑信息 示例:

SRC?=?(?notdir?./src/a.c?)?
去除文件a . c 的路徑信息 , 使用 (notdir ./src/a.c) 去除文件a.c的路徑信息,使用 (notdir./src/a.c)去除文件a.c的路徑信息,使用(SRC)得到的是不帶路徑的文件名稱,即a.c。

[4] 包含頭文件路徑

使用-I 頭文件路徑的方式可以指定編譯器的頭文件的路徑 示例:

INCLUDES?=?-I./inc
$(CC)?-c?$(INCLUDES)?$(SRC)

[5] addsuffix

函數(shù)名稱:加后綴函數(shù)—addsuffix。語法:

$(addsuffix?SUFFIX,NAMES…)?
函數(shù)功能:為“NAMES…”中的每一個文件名添加后綴“SUFFIX”。參數(shù)“NAMES…” 為空格分割的文件名序列,將“SUFFIX”追加到此序列的每一個文件名 的末尾。返回值:以單空格分割的添加了后綴“SUFFIX”的文件名序列。函數(shù)說明:示例:

$(addsuffix?.c,foo?bar)?
返回值為

foo.c?bar.c

[6] 包含另外一個文件:include

在Makefile使用include關(guān)鍵字可以把別的Makefile包含進(jìn)來,這很像C語言的#include,被包含的文件會原模原樣的放在當(dāng)前文件的包含位置。比如命令

include?file.dep
即把file.dep文件在當(dāng)前Makefile文件中展開,亦即把file.dep文件的內(nèi)容包含進(jìn)當(dāng)前Makefile文件

在 include前面可以有一些空字符,但是絕不能是[Tab]鍵開始。

[7] foreach

foreach函數(shù)和別的函數(shù)非常的不一樣。因?yàn)檫@個函數(shù)是用來做循環(huán)用的 語法是:

$(foreach?,
  • ,?)
    這個函數(shù)的意思是,把參數(shù)
  • 中的單詞逐一取出放到參數(shù)所指定的變量中,然后再執(zhí)行所包含的表達(dá)式。

    每一次會返回一個字符串,循環(huán)過程中,的所返回的每個字符串會以空格分隔,最后當(dāng)整個循環(huán)結(jié)束時,所返回的每個字符串所組成的整個字符串(以空格分隔)將會是foreach函數(shù)的返回值。

    所以,最好是一個變量名,
  • 可以是一個表達(dá)式,而中一般會使用這個參數(shù)來依次枚舉
  • 中的單詞。

    舉例:

    names?:=?a?b?c?d
    files?:=?$(foreach?n,$(names),$(n).o)
    上面的例子中,$(name)中的單詞會被挨個取出,并存到變量“n”中,“$(n).o”每次根據(jù)“$(n)”計(jì)算出一個值,這些值以空格分隔,最后作為foreach函數(shù)的返回,所以,$(files)的值是“a.o b.o c.o d.o”。

    注意,foreach中的參數(shù)是一個臨時的局部變量,foreach函數(shù)執(zhí)行完后,參數(shù)的變量將不在作用,其作用域只在foreach函數(shù)當(dāng)中。

    [8] call

    “ call”函數(shù)是唯一一個可以創(chuàng)建定制化參數(shù)函數(shù)的引用函數(shù)。使用這個函數(shù)可以實(shí)現(xiàn)對用戶自己定義函數(shù)引用。我們可以將一個變量定義為一個復(fù)雜的表達(dá)式,用“ call”函數(shù)根據(jù)不同的參數(shù)對它進(jìn)行展開來獲得不同的結(jié)果。

    函數(shù)語法:

    $(call?variable,param1,param2,...)
    函數(shù)功能:在執(zhí)行時,將它的參數(shù)“ param”依次賦值給臨時變量“ $(1)”、“ $(2)” call 函數(shù)對參數(shù)的數(shù)目沒有限制,也可以沒有參數(shù)值,沒有參數(shù)值的“ call”沒有任何實(shí)際存在的意義。執(zhí)行時變量“ variable”被展開為在函數(shù)上下文有效的臨時變量,變量定義中的“ $(1)”作為第一個參數(shù),并將函數(shù)參數(shù)值中的第一個參數(shù)賦值給它;變量中的“ $(2)”一樣被賦值為函數(shù)的第二個參數(shù)值;依此類推(變量**$(0)**代表變量“ variable”本身)。之后對變量“ variable” 表達(dá)式的計(jì)算值。

    返回值:參數(shù)值“ param”依次替換“ $(1)”、“ $(2)”…… 之后變量“ variable”定義的表達(dá)式的計(jì)算值。

    函數(shù)說明:

    1. 函數(shù)中“ variable”是一個變量名,而不是變量引用。因此,通?!?call”函數(shù)中的“ variable”中不包含“ $”(當(dāng)然,除非此變量名是一個計(jì)算的變量名)。
    2. 當(dāng)變量“ variable”是一個 make 內(nèi)嵌的函數(shù)名時(如“ if”、“ foreach”、“ strip”等),對“ param”參數(shù)的使用需要注意,因?yàn)椴缓线m或者不正確的參數(shù)將會導(dǎo)致函數(shù)的返回值難以預(yù)料。
    3. 函數(shù)中多個“ param”之間使用逗號分割。
    4. 變量“ variable”在定義時不能定義為直接展開式!只能定義為遞歸展開式。
    函數(shù)示例:

    reverse?=?$(2)$(1)
    foo?=?$(call?reverse,a,b)
    all:
    ?@echo?"foo=$(foo)"
    執(zhí)行結(jié)果:

    foo=ba
    即a替代了(2)

    三、編譯詳細(xì)說明

    我們在根目錄下執(zhí)行make命令后,詳細(xì)步驟如下:

    1. include scripts/Makefile :將文件替換到當(dāng)前位置,
    2. 使用默認(rèn)的目標(biāo)all,該目標(biāo)依賴于$(Target)$(Target) 在scripts/Makefile中定義了,即phone
    3. $(Target)依賴于mm
    4. mm這個目標(biāo)會執(zhí)行
    @?$(foreach?n,$(Modules),$(call?modules_make,$(n)))
    Modules是所有的目錄名字集合, foreach 會遍歷字符串$(Modules)中每個詞語, 每個詞語會賦值給n, 同時執(zhí)行語句:

    call?modules_make,$(n)
    1. modules_make 被$(MAKE) -C $(1)所替代,
    $(MAKE) 有默認(rèn)的名字make -C:進(jìn)入子目錄執(zhí)行make$(1) :是步驟4中$(n),即每一個目錄名字

    最終步驟4的語句就是進(jìn)入到每一個目錄下,執(zhí)行每一個目錄下的Makefile

    1. 進(jìn)入某一個子目錄下,執(zhí)行Makefile 默認(rèn)目標(biāo)是all,依賴Objs
    Objs?:=?$(patsubst?%.c,%.o,$(Source))
    patsubst 把字串$ource中以.c 結(jié)尾的單詞替換成以.o 結(jié)尾的字符 而

    Source?:=?$(wildcard?./*.c)
    wildcard 會列舉出當(dāng)前目錄下所有的.c文件

    所以第6步最終就是將子目錄下的所有的.c文件,編譯生成對應(yīng)文件名的.o文件


    $(CC)?$(CFLAGS)?-o?$(Target)?$(AllObjs)?$(Libs)
    這幾個變量都在文件scripts/Makefile中定義$(CC) :替換成gcc,制定編譯器$(CFLAGS) :替換成-Wall -O3,即編譯時的優(yōu)化等級-o $(Target):生成可執(zhí)行程序phone$(AllObjs)

    AllObjs?:=?$(addsuffix?/*.o,$(Modules))
    addsuffix 會將 /*.o追加到$(Modules)中所有的詞語后面,也就是我們之前在子目錄下編譯生成的所有的.o文件$(Libs) :替換為-lpthread,即所需要的動態(tài)庫

    版權(quán)申明:內(nèi)容來源網(wǎng)絡(luò),版權(quán)歸原創(chuàng)者所有。除非無法確認(rèn),我們都會標(biāo)明作者及出處,如有侵權(quán)煩請告知,我們會立即刪除并表示歉意。謝謝!


  • 本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。

    C語言編程

    178 篇文章

    關(guān)注

    發(fā)布文章

    編輯精選

    技術(shù)子站

    關(guān)閉