makefile 學習一

最近在學習nginx,由於實在linux下,一些代碼需要用makefile文件來編譯,比較節省時間。因爲在nginx中添加一個新的模塊如果用./configure方法來添加,特別是當你的代碼有錯時,修改以後又./configure,那麼沒編譯一次都需要幾分鐘,實現在受不了了,就學習一下makefile,另一個原因是自己以前沒有接觸過linux,跟沒有在linux下編寫過代碼,這次決定在學nginx的同時學習一個linux編程,當然就有必要學習一下makefile(按需求學習,重點放在學習nginx)。

gcc編譯過程

(1)預處
理:生成
test.i文件

# cpp test.c-o test.i   //或者

# cpp test.c > test.i    //或者

# gcc -E test.c -o test.i

 

(2)編譯:生成test.s文件

# gcc -S test.i

 

(3)彙編:生成test.o文件

# as -o test.o test.s    //或者

# gcc -c test.s -o test.o

 

(4)鏈接:生成可執行文件test

# gcc -o test test.o


例子:

##程序運行的四個過程
gcc -E test.c -o test.i #預編譯
gcc -S test.i -o test.s #彙編
gcc -c test.s -o test.o #編譯
gcc -o test test.o      #link

makefile的第一個例子:

main.c的代碼:

#include <stdio.h>
#include <stdlib.h>
#include "print.h"
#include "computer.h"

int main()
{
    print("xxxx");
    printf("%d\n", ret_add(1, 2));
    return 0;
}
print.h的代碼:
#include <stdio.h>

void print(const char *str);
print.c的代碼:
#include "print.h"

void print(const char *str)
{
   if (str == NULL) 
   {
      printf("Empty String\n");
   }
   else
   {
      printf("%s\n", str);
   }
}
computer.h的代碼:
int ret_add(int a, int b);
computer.c的代碼:
#include "computer.h"

int ret_add(int a, int b)
{
   return a+b;
}

用makefile來編譯main.c:
main : main.o print.o computer.o
       gcc -o main main.o print.o computer.o
main.o : main.c print.h computer.h
       gcc -c main.c
print.o : print.c print.h
       gcc -c print.c
computer.o : computer.c computer.h
       gcc -c computer.c
命令make -f mymakename

注意有時候會報如下錯誤:

makefile:11: *** 遺漏分隔符 。 停止.
這是因爲gcc命令是以TAB開始的,所以所有的gcc命令之前必須加上一個TAB鍵

以上“:”左邊的都稱爲目標文件,computer.o print.o main.o main 都是目標文件,但一個makefile只有一個最終目標文件,其他目標文件都是爲這個最終目標服務的,main是最終目標,其他目標都是服務於最終目標main,或者main依賴於其他目標。

“:”右邊的是爲生成左邊的目標必須依賴的文件。computer.o的生成依賴預computer.c computer.h, main.o的生成依賴於main.c print.h  couputer.h等


一些有用的變量:

$@目標文件。 比如computer.o print.o main.o main

$^所有依賴文件。比如main.o所有的依賴文件是main.c print.h  couputer.h

$<所有依賴文件的第一文件。比如main.o所依賴的第一個文件是main.c

所以makefile可以這樣寫:

main : main.o print.o computer.o	
	gcc -o $@ $^	
main.o : main.c print.h computer.h	
	gcc -c $<	
print.o : print.c print.h	
	gcc -c $<	
computer.o : computer.o computer.h
	gcc -c $<


自動推到機制

makefile:

main : main.o print.o 
computer.o
	gcc -o main main.o print.o computer.o
main.o : print.h computer.h
print.o : print.h
computer.o : computer.h
make會根據目標文件自動推到需要的.c(.h?)文件,並且調用gcc去編譯,不如print.o這個目標,make知道需要computer.c這個文件並且條用gcc去編譯。


使用變量

makefile

objects = main.o 
print.o computer.o
main : $(objects)
	gcc -o main $(objects)
main.o : main.c print.h computer.h
	gcc -c main.c
print.o : print.c print.h
	gcc -c print.c
computer.o : computer.c computer.h
	gcc -c computer.c
.PHONY: clean
clean:
	-rm main $(objects)
makefile中可以使用變量,比如使用變量objects來保存目標文件。</p>

使用變量的好處是我們可以是修改變量的值,而不用修改相應的依稀項。比如我們定義一個變量depend = main.c print.h comput.h 來保存main.o的依賴項,當main.o的依稀項增加或減少時我們只修改depend這個變量就可以了。

比如我們新增一個文件create.h,我們只需要在depend的之後加入這個文件名就可以了,這在大的項目中很節省時間。







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章