亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 服務器 > Linux服務器 > 正文

Linux里Makefile是什么?它是如何工作的?

2024-09-05 23:05:03
字體:
來源:轉載
供稿:網友

用這個方便的工具來更有效的運行和編譯你的程序
makefile是用于自動編譯和鏈接的,一個工程有很多文件組成,每一個文件的改變都會導致工程的重新鏈接-----但是不是所有的文件都需要重新編譯,makefile能夠紀錄文件的信息,決定在鏈接的時候需要重新編譯哪些文件!

當你需要在一些源文件改變后運行或更新一個任務時,通常會用到 make 工具。make 工具需要讀取一個 Makefile(或 makefile)文件,在該文件中定義了一系列需要執行的任務。你可以使用 make 來將源代碼編譯為可執行程序。大部分開源項目會使用 make 來實現最終的二進制文件的編譯,然后使用 make install 命令來執行安裝。
本文將通過一些基礎和進階的示例來展示 make 和 Makefile 的使用方法。在開始前,請確保你的系統中安裝了 make。

基礎示例
依然從打印 “Hello World” 開始。首先創建一個名字為 myproject 的目錄,目錄下新建 Makefile 文件,文件內容為:

 

say_hello:echo "Hello World"

在 myproject 目錄下執行 make,會有如下輸出:

$ makeecho "Hello World"Hello World

在上面的例子中,“say_hello” 類似于其他編程語言中的函數名。這被稱之為 目標(target)。在該目標之后的是預置條件或依賴。為了簡單起見,我們在這個示例中沒有定義預置條件。echo ‘Hello World' 命令被稱為 步驟(recipe)。這些步驟基于預置條件來實現目標。目標、預置條件和步驟共同構成一個規則。

總結一下,一個典型的規則的語法為:

目標: 預置條件
<TAB> 步驟

作為示例,目標可以是一個基于預置條件(源代碼)的二進制文件。另一方面,預置條件也可以是依賴其他預置條件的目標。

final_target: sub_target final_target.cRecipe_to_create_final_targetsub_target: sub_target.cRecipe_to_create_sub_target

目標并不要求是一個文件,也可以只是步驟的名字,就如我們的例子中一樣。我們稱之為“偽目標”

再回到上面的示例中,當 make 被執行時,整條指令 echo "Hello World" 都被顯示出來,之后才是真正的執行結果。如果不希望指令本身被打印處理,需要在 echo 前添加 @

say_hello:@echo "Hello World"

重新運行 make,將會只有如下輸出:

$ makeHello World

接下來在 Makefile 中添加如下偽目標:generate 和 clean:

say_hello:@echo "Hello World"generate:@echo "Creating empty text files..."touch file-{1..10}.txtclean:@echo "Cleaning up..."rm *.txt

隨后當我們運行 make 時,只有 say_hello 這個目標被執行。這是因為Makefile 中的第一個目標為默認目標。通常情況下會調用默認目標,這就是你在大多數項目中看到 all 作為第一個目標而出現。all 負責來調用它他的目標。我們可以通過 .DEFAULT_GOAL 這個特殊的偽目標來覆蓋掉默認的行為。

在 Makefile 文件開頭增加 .DEFAULT_GOAL:

.DEFAULT_GOAL := generate

make 會將 generate 作為默認目標:

$ makeCreating empty text files...touch file-{1..10}.txt

顧名思義,.DEFAULT_GOAL 偽目標僅能定義一個目標。這就是為什么很多 Makefile 會包括 all 這個目標,這樣可以調用多個目標。
下面刪除掉 .DEFAULT_GOAL,增加 all 目標:

all: say_hello generatesay_hello:@echo "Hello World"generate:@echo "Creating empty text files..."touch file-{1..10}.txtclean:@echo "Cleaning up..."rm *.txt

運行之前,我們再增加一些特殊的偽目標。.PHONY 用來定義這些不是文件的目標。make 會默認調用這些偽目標下的步驟,而不去檢查文件名是否存在或最后修改日期。完整的 Makefile 如下:

.PHONY: all say_hello generate cleanall: say_hello generatesay_hello:@echo "Hello World"generate:@echo "Creating empty text files..."touch file-{1..10}.txtclean:@echo "Cleaning up..."rm *.txt

make 命令會調用 say_hello 和 generate:

$ makeHello WorldCreating empty text files...touch file-{1..10}.txt

clean 不應該被放入 all 中,或者被放入第一個目標中。clean 應當在需要清理時手動調用,調用方法為 make clean

$ make cleanCleaning up...rm *.txt

現在你應該已經對 Makefile 有了基礎的了解,接下來我們看一些進階的示例。

進階示例
變量
在之前的實例中,大部分目標和預置條件是已經固定了的,但在實際項目中,它們通常用變量和模式來代替。

定義變量最簡單的方式是使用 = 操作符。例如,將命令 gcc 賦值給變量 CC:

CC = gcc

這被稱為遞歸擴展變量,用于如下所示的規則中:

hello: hello.c${CC} hello.c -o hello

你可能已經想到了,這些步驟將會在傳遞給終端時展開為:

gcc hello.c -o hello

${CC} 和 $(CC) 都能對 gcc 進行引用。但如果一個變量嘗試將它本身賦值給自己,將會造成死循環。讓我們驗證一下:

CC = gccCC = ${CC}all:@echo ${CC}

此時運行 make 會導致:

$ makeMakefile:8: *** Recursive variable 'CC' references itself (eventually). Stop.

為了避免這種情況發生,可以使用 := 操作符(這被稱為簡單擴展變量)。以下代碼不會造成上述問題:

CC := gccCC := ${CC}all:@echo ${CC}

模式和函數
下面的 Makefile 使用了變量、模式和函數來實現所有 C 代碼的編譯。我們來逐行分析下:

# Usage:# make # compile all binary# make clean # remove ALL binaries and objects.PHONY = all cleanCC = gcc # compiler to useLINKERFLAG = -lmSRCS := $(wildcard *.c)BINS := $(SRCS:%.c=%)all: ${BINS}%: %.o@echo "Checking.."${CC} ${LINKERFLAG} $< -o $@%.o: %.c@echo "Creating object.."${CC} -c $<clean:@echo "Cleaning up..."rm -rvf *.o ${BINS}

以 # 開頭的行是評論
.PHONY = all clean 行定義了 all 和 clean 兩個偽目標。
變量 LINKERFLAG 定義了在步驟中 gcc 命令需要用到的參數。
SRCS := $(wildcard *.c):$(wildcard pattern) 是與文件名相關的一個函數。在本示例中,所有 “.c”后綴的文件會被存入 SRCS 變量。
BINS := $(SRCS:%.c=%):這被稱為替代引用。本例中,如果 SRCS 的值為 'foo.c bar.c',則 BINS的值為 'foo bar'。
all: ${BINS} 行:偽目標 all 調用 ${BINS} 變量中的所有值作為子目標。
規則:

%: %.o@echo "Checking.."${CC} ${LINKERFLAG} $< -o $@

下面通過一個示例來理解這條規則。假定 foo 是變量 ${BINS} 中的一個值。% 會匹配到 foo(%匹配任意一個目標)。下面是規則展開后的內容:

foo: foo.o@echo "Checking.."gcc -lm foo.o -o foo

如上所示,% 被 foo 替換掉了。$< 被 foo.o 替換掉。$<用于匹配預置條件,$@ 匹配目標。對 ${BINS} 中的每個值,這條規則都會被調用一遍。
規則:

%.o: %.c@echo "Creating object.."${CC} -c $<

之前規則中的每個預置條件在這條規則中都會都被作為一個目標。下面是展開后的內容:

foo.o: foo.c@echo "Creating object.."gcc -c foo.c

最后,在 clean 目標中,所有的二進制文件和編譯文件將被刪除。
下面是重寫后的 Makefile,該文件應該被放置在一個有 foo.c 文件的目錄下:

# Usage:# make # compile all binary# make clean # remove ALL binaries and objects.PHONY = all cleanCC = gcc # compiler to useLINKERFLAG = -lmSRCS := foo.cBINS := fooall: foofoo: foo.o@echo "Checking.."gcc -lm foo.o -o foofoo.o: foo.c@echo "Creating object.."gcc -c foo.cclean:@echo "Cleaning up..."rm -rvf foo.o foo

這些和到一起,就是makefile,當然這些功能還太少,可以加上很多別的項目。但宗旨就是:讓編譯器知道要編譯一個文件需要依賴其他的哪些文件。當那些依賴文件有了改變,編譯器會自動的發現最終的生成文件已經過時,而重新編譯相應的模塊。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對VEVB武林網的支持。如果你想了解更多相關內容請查看下面相關鏈接


注:相關教程知識閱讀請移步到服務器教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美成人免费全部| 国产精品日韩电影| 欧美激情精品久久久久久| 最新国产成人av网站网址麻豆| 中文字幕亚洲情99在线| 国产精品老牛影院在线观看| 亚洲精选在线观看| 欧美做爰性生交视频| 国产综合久久久久| 亚洲精品久久久一区二区三区| 亚洲精品欧美日韩| 欧美日韩国产中文精品字幕自在自线| 色妞一区二区三区| 久久精品精品电影网| 亚洲精品天天看| 国产中文字幕日韩| 26uuu另类亚洲欧美日本老年| 91免费看片网站| 国产精品色悠悠| 国产成人91久久精品| 日本亚洲欧洲色| 色综合久久中文字幕综合网小说| 成人有码在线视频| 91久久久在线| 91精品视频观看| 91理论片午午论夜理片久久| 亚洲精品videossex少妇| 日韩av电影在线网| 国产精品18久久久久久麻辣| 国产成人鲁鲁免费视频a| 亚洲欧美日韩天堂一区二区| 久久6免费高清热精品| 国产不卡av在线| 在线日韩第一页| 久久中文字幕视频| 久久久免费观看视频| 国产综合久久久久久| 亚洲码在线观看| 久久久久久九九九| 日本道色综合久久影院| 国产在线不卡精品| 中文字幕在线日韩| 亚洲女同性videos| 欧日韩不卡在线视频| 亚洲成人精品久久| 亚洲美女又黄又爽在线观看| 2020国产精品视频| 国产精品第3页| 亚洲一级片在线看| 久久久久久中文| 中文字幕欧美在线| 欧美激情在线观看| 9.1国产丝袜在线观看| 国产成人精品优优av| 国产精品成人一区二区三区吃奶| 国产一区二区三区三区在线观看| 91精品视频大全| 91亚洲精品在线| 欧美精品在线看| 欧美大片大片在线播放| 插插插亚洲综合网| 亚洲精品成人久久久| 国产一区欧美二区三区| 亚洲国产小视频在线观看| 久久综合伊人77777蜜臀| 亚洲国产福利在线| 日韩欧美极品在线观看| 国产成人免费av| 国产精品日韩精品| 亚洲专区在线视频| 久久99久久亚洲国产| 97精品一区二区视频在线观看| 久久久久北条麻妃免费看| 中文字幕日韩欧美精品在线观看| 亚洲国产精品嫩草影院久久| 国产一区二区三区直播精品电影| 成人精品福利视频| 久久久91精品国产一区不卡| 欧美大片在线看| 高潮白浆女日韩av免费看| 欧美另类老肥妇| 亚洲图片在线综合| 久久精品国产电影| 欧美日韩一区二区三区在线免费观看| 日本中文字幕不卡免费| 美女视频久久黄| 欧美在线视频一二三| 亚洲国产天堂久久综合网| 欧洲美女7788成人免费视频| 国产日本欧美在线观看| 日韩激情av在线免费观看| 91精品久久久久久久久青青| 亚洲国产精品久久| 欧美精品videossex88| 欧美精品免费在线观看| 国产一区二区视频在线观看| 国产视频福利一区| 国产日韩欧美在线看| 亚洲全黄一级网站| 精品久久久久久久久久ntr影视| 中文字幕精品在线| 日韩福利在线播放| 欧美日韩亚洲91| 欧美洲成人男女午夜视频| 国模私拍一区二区三区| 久久av在线看| 亚洲精品美女久久| 亚洲在线视频福利| 6080yy精品一区二区三区| 国产人妖伪娘一区91| 精品偷拍各种wc美女嘘嘘| 国产精品9999| 97久久久久久| 91国产视频在线播放| 亚洲国产91色在线| 日韩精品视频中文在线观看| 久久久av网站| 精品无人区太爽高潮在线播放| 亚洲国产另类久久精品| 亚洲精品欧美日韩专区| 欧美性做爰毛片| 欧美—级a级欧美特级ar全黄| 日韩成人高清在线| 91精品美女在线| 国产欧美日韩最新| 欧美在线观看网站| 欧美在线观看www| 久久久久久久久久久av| 伊人伊成久久人综合网站| 亚洲国产一区二区三区在线观看| 中文字幕亚洲国产| 精品女厕一区二区三区| 97香蕉久久超级碰碰高清版| 国产91精品视频在线观看| 国产亚洲精品高潮| 57pao成人永久免费视频| 国外成人在线直播| 欧美极品在线视频| 精品美女久久久久久免费| 精品国产一区二区在线| 国产成人97精品免费看片| 日韩成人激情视频| 日韩av一区在线观看| 国产精品爽爽爽爽爽爽在线观看| 国模私拍视频一区| 午夜精品久久久久久久久久久久久| 久久成人人人人精品欧| 久久久久久久久久婷婷| 色视频www在线播放国产成人| 日韩在线中文字| www国产精品视频| 中文精品99久久国产香蕉| 精品国产拍在线观看| 久久久久久有精品国产| 91精品国产色综合| 久久在精品线影院精品国产| 亚洲欧美制服综合另类| 国产日韩欧美自拍| 欧美天堂在线观看| 欧美性xxxx在线播放| 国产精品一区二区三区在线播放| 亚洲最新在线视频| 欧美—级高清免费播放| 亚洲激情 国产|