1. 程式人生 > >makefile學習筆記(1)

makefile學習筆記(1)

將學習makefile的過程記錄下,做個筆記,一是加深理解和記憶,二也方便日後遺忘了查詢,因為自己也是邊學邊記錄的,難免有很多問題,請多多指正和包涵

因為主要是學習makefile,所以開始只有一個main.c的函式,內容如下:

一.基本的makefile

main.c

#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;
}
首先來個最簡單,也是最直接的makefile,makefile的語法可以參考我前面學習的筆記

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();

先看沒有用到變數正常編譯的情況

makefile version2.0
#生成的目標檔案是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無關