什么是Makefile
今天我们在linux开启terminal打上make,系统会去执行你自定义的一些指令且这些指令是可以多个的,至于要怎们自订义指令呢?
这个时候就是要靠Makeflie了
我们可以在Makefile里执行c/c++、python也能做出一系列的档案操作,且今天若要执行多个程式也可以只靠make指令达成,此外每次make系统会去检查指定的档案是否有变更,系统只会重新编译有做更改的档案藉此加快编译速度,接下来我将会以c/c++搭配Makefile作为範例介绍。
gcc/g++介绍
在介绍撰写编译c/c++的Makfile之前,我们必须先了解要如何在linux底下执行c/c++
用gcc执行c code很简单照下面格式即可,而产生的执行档案可透过./去执行
gcc filename.c -o targetName ./targetName
下面例子是利用gcc执行test.c这个档案,而test.c做的只是输出hello world!而已
//test.c#include<stdio.h>int main(){ printf("hello world!\n"); return 0;}
常用的gcc mode
若今天要执行的档案为cpp时只需将gcc改成g++即可
gdb
上述提到的gdb是简易的debug工具使用方法如下
gdb ./targetName
打完指令后透过start开始,接者输入n可以逐行执行这样就能知道哪一行出现error
Makefile撰写架构
介绍完这些背景后,我们可以来讲Makefile的撰写格式了!
target: target filecommand# 是注解$@ #目标文件$^ # 所有的依赖文件$< # 第一个依赖文件$? # 比目标还要新的依赖文件列表
我们直接用例子解释
下面例子为一次执行foo1.c foo2.c main.c,而程式在做的事情只是a+b跟a-b而已
至于makefile想要制定以下规则
c code
// foo1.cint foo1(int a,int b){return a+b;}// foo2.cint foo2(int a,int b){return a-b;}// main.c#include<stdio.h>int foo1(int a,int b);int foo2(int a,int b);int main(void){int a;int b;printf("input a:");scanf("%d",&a);printf("input b:");scanf("%d",&b);printf("foo1 (%d)\nfoo2 (%d)\n ",foo1(a,b),foo2(a,b));return 0;}
Makefile 较长的版本
main:main.o foo.ogcc main.o foo.o -o main -g foo.o:foo.s gcc -g -c foo.s main.o:main.sgcc -g -c main.s foo.s:foo.c gcc -g -S foo.c main.s:main.cgcc -g -S main.c clean:rm -f *.orm -f *.srm -f main
但是造上面每一个档案就要打一个指令真的太蠢,可以透过特殊符号来达成精简
Makefile 精简版
main: foo1.o foo2.o main.ogcc -o $@ -g $^ clean:rm -f *.orm -f *.srm -f main%.o: %.cgcc -c -O2 $<%.s: %.cgcc -S -O2 $<
以上介绍就到这边若有疑问欢迎提问~