近期在学习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 ", 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 "); } else { printf("%s ", 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.hmake会依据目标文件自己主动推到须要的.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的之后增加这个文件名称就能够了,这在大的项目中非常节省时间。