makefile學習筆記(1)
將學習makefile的過程記錄下,做個筆記,一是加深理解和記憶,二也方便日後遺忘了查詢,因為自己也是邊學邊記錄的,難免有很多問題,請多多指正和包涵
因為主要是學習makefile,所以開始只有一個main.c的函式,內容如下:
一.基本的makefile
main.c
首先來個最簡單,也是最直接的makefile,makefile的語法可以參考我前面學習的筆記#include <stdio.h> int main(int argc,char** argv) { int i = 0; int sum = 0; printf("hello\n"); for(;i<10;i++) { sum += i; } printf("sum=%d\n",sum); return 0; }
https://blog.csdn.net/qq_33706673/article/details/78446928
這裡不再詳細介紹
makefile version1.0
#生成的目標檔案是socket,\ 依賴檔案是main.o socket:main.o cc -o socket main.o #編譯main.c檔案,生成main.o檔案,依賴main.c檔案 main.o:main.c cc -c main.c #clean命令,rm -rf表示刪除時遇到錯誤(如沒有檔案等)繼續執行 .PHONY:clean clean: rm -rf main.o socket
這裡的#後面的是註釋,如果註釋一行寫不完,可以用\,然後下一行的也是註釋,如第一行
執行make命令
二.makefile中使用變數
上面的是最簡單的情況,要是編譯的檔案比較多的話,可以用變量表示.o檔名稱,簡化makefile,當然變數不僅僅可以表示.o檔名
假設現在有main.c;test.c;test.h三個檔案
/*main.c檔案*/ #include <stdio.h> #include "test.h" int main(int argc,char** argv) { int i = 0; int sum = 0; test(); for(;i<10;i++) { sum += i; } printf("sum=%d\n",sum); return 0; }
/*test.c檔案*/
#include <stdio.h>
#include "test.h"
void test()
{
printf("這是test.c檔案的test函式\n");
}
/*test.h檔案*/
void test();
先看沒有用到變數正常編譯的情況
#生成的目標檔案是socket,依賴檔案是main.o,test.o
socket:main.o test.o
cc -o socket main.o test.o
#編譯main.c檔案,生成main.o檔案,依賴main.c檔案
main.o:main.c
cc -c main.c
#編譯test.c檔案,生成test.o檔案,依賴test.c,test.h
test.o:test.h test.c
cc -c test.c
.PHONY:clean
clean:
rm -rf main.o test.o socket
下面看使用了變數的情況
Makefile version2.1
#用變數object表示main.o和test.o檔案
object = main.o test.o
#生成的目標檔案是socket,依賴檔案是main.o,test.o
socket:$(object)
cc -o socket $(object)
#編譯main.c檔案,生成main.o檔案,依賴main.c檔案
main.o:main.c
cc -c main.c
#編譯test.c檔案,生成test.o檔案,依賴test.c,test.h
test.o:test.h test.c
cc -c test.c
.PHONY:clean
clean:
rm -rf $(object) socket
因為上面的檔案比較少,所以使用變數的好處不是很明顯,檔案越多,使用變數的好處越明顯,比如
1. 增加或者刪除檔案時,只需要修改變數就可以了,類似於C語言的巨集2. 可以做到見名知意的好處
3. 其他。。。
三.Makefile裡的列印資訊
列印資訊有很多的方法,這裡只介紹一種,用@echo方式輸出列印資訊,格式如下:
@echo 列印資訊 不需要帶冒號(不推薦) @echo “列印資訊”帶冒號(推薦)一般情況下加上冒號比較好,echo執行完後自動換行,不需要加換行字元\n,加了的話相當於換2行
Makefile version3.0
#用變數object表示main.o和test.o檔案
object = main.o test.o
#其他變數,做到見名知意
endReleaseFile = socket
#生成的目標檔案是socket,依賴檔案是main.o,test.o
$(endReleaseFile):$(object)
cc -o $(endReleaseFile) $(object)
@echo "連結main.o test.o,生成目標檔案socket\n"
#編譯main.c檔案,生成main.o檔案,依賴main.c檔案
main.o:main.c
@echo 編譯開始,請稍等... ...
cc -c main.c
@echo "編譯main.c結束,生成mian.o,依賴main.c\n"
#編譯test.c檔案,生成test.o檔案,依賴test.c,test.h
test.o:test.h test.c
cc -c test.c
@echo "編譯test.c結束,生成test.o,依賴test.c test.h\n"
.PHONY:clean
clean:
rm -rf $(object) socket
@echo "刪除main.o test.o socket檔案\n"
在列印的時候也可以直接使用變數列印變數的內容
四.Makefile中的編譯命令
比如我現在想做幾個命令
make c :make clean的簡寫命令
make r :make rebuild;不管是不是最新的.o和目標檔案都強制重新編譯
make a:這個相當於make五.Makefile中其他說明
1. linux命令
使用@命令2. 刪除沒有的檔案時報錯
rm命令引數
-r,-R,--recursive
遞迴地移除目錄中的內容。
-f,--force
忽略不存在的檔案,並且從不向使用者提示。
rm 加上 -f的選項,這樣,即使要刪除的檔案不存在,也不提示報錯。
rm 加上 -r的選項,可以遞迴刪除資料夾。
所以一般使用rm -rf命令
3. 目標檔案中的.o檔案的順序與下面誰先編譯的順序無關
即這裡的test.o和main.o與下面是先編譯test.c還是先編譯main.c無關