最近在學習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的之後加入這個文件名就可以了,這在大的項目中很節省時間。