5.makefile

makefile

一、gcc

gcc是用来编译代码的编译器

编译完之后有一些常见的输出文件
1 .a	静态库(文档)
2 .c	需要预处理的c语言源代码
3 .h	C语言源代码的头文件
4 .i	经过预处理后的C语言源代码
5 .o	目标文件(经过汇编产生)
6 .s	经过编译后产生的汇编语言代码
7 .elf	可执行文件(linux下的可执行文件)
    
//编译过程
.c -》 .i -》 .s -》 .o
//链接过程
把多个.o链接成一个可执行文件(ELF/.exe)
-o:是输出的意思
1. gcc -E test.c -o test.i  //查看经过预处理之后的c语言源代码
    
2. gcc -s test.c -o test.s  //查看编译后产生的汇编语言编码
   gcc -s test.i -o test.s	 //也可以查看编译后产生的汇编语言编码
   //意思就是.c文件可以直接到.s文件,也可以.c——>.i——>.s
    
3. gcc -c test.c -o test.o  //形成目标文件
4. gcc test.o -o test	//形成可执行文件
//经过上面四步形成了可执行文件
 
5. gcc test.c -o hello //直接将test.c编译成叫hello的可执行文件
    
6. ./hello //运行hello这个可执行文件
.0——二进制可执行代码(机械码),不具备可执行的能力
    

二、makefile---数据库文件或则叫文本文件

linux的过程都是自己可以控制的

在gcc中可以通过将.c文件编译成.o文件

那么如果有多个.c文件呢,这些都要编译成.o文件,这样需要输入多条指令去执行吗?

可以通过makefile

例如:

myadd.h文件
int myAdd(int a,int b);

myadd.c文件
#include<myadd.h>
int myAdd(int a,int b)
{
    return a+b;
}

mysub.h文件
int mySub(int a,int b);

mysub.c文件
#include<mysub.h>
int mySub(int a,int b)
{
    return a-b;
}

muproject.c文件
#include<stdio.h>
#include<myadd.h>
#include<mysub.h>
void main()
{
    int num1=10;
    int num2=20;
    int num3=30;
    printf("%d\n",myAdd(num1,mySub(num2,num2)));
}

myproject.c文件引用了两个自定义的头文件,那么要实现myproject.c就必须将三个自定义的.c文件编译成.o文件,然后再将这三个.o文件一起链接成一个可执行文件
    
    gcc -c myadd.c -o myadd.o
    gcc -c mysub.c -o mysub.o
    gcc -c myproject.c -o myproject.o
    gcc  myadd.o mysub.o myproject.o -o test1

makefile的好处:自动化编译

make命令,需要一个makefile文件,在makefile文件中去告诉make命令需要这怎样去编译和链接程序。makefile是一个文本形式的数据库文件,包含一些规则来告诉make处理哪些文件以及如何处理这些文件

规则

target:depend
    command
    整个算一条执行语句
target:目标,可以是一个中间文件,也可以是一个最终的执行文件
depend:依赖,指要生成目标文件所需要的文件或目标
command:make需要执行的命令
//gcc -c test.c -o test.0——gcc就是命令,test.c是依赖,test.o是目标
  
hello.i:hello.c
    gcc -E -o hello.i hello.c

makefile执行顺序

默认执行第一条语句,在执行第一条时,先找所有的依赖文件,如果没有,继续往下找有没有脚本能生成这个依赖文件,如果有就会先执行下面生成依赖文件的语句
test:prog.o code.o
    gcc -o test prog.o code.o
prog.o:prog.c
    gcc -c prog.c -o prog.o
code.o:code.c
    gcc -c code.c -o code.o
             
clean:
	rm -f *.o
//清除,伪目标,没有依赖项
        
myproject:myadd.o mysub.o myproject.o
	gcc myadd.o mysub.o myproject.o -o myproject
myadd.o:myadd.c
	gcc -c myadd.c -o myadd.o
mysub.o:mysub.c
	gcc -c mysub.c -o mysub.o
myproject.o:myproject.c
	gcc -c myproject.c -o myproject.o
clean:
	rm -f *.o myproject
           

makefile变量

变量理解为字符串
OBJ = a b c	  表示OBJ就是 a b c这三个变量,不能再改变了
OBJ := a b c  表示OBJ是 a b c这三个变量,但是可以用+=去追加
OBJ += d	表示OBJ变量添加了 d 这一个变量
  
变量引用:
    $(变量名)
 

makefile示例

通配符:% * ?
    %——表示任意一个
    *——表示所有
    ?——表示匹配一个未知的东西
OBJ:=myadd.o mysub.o
OBJ+=myproject.o
    
myproject:$(OBJ)
    gcc $(OBJ) -o myproject
*.o:*.c
    gcc -c *.c -o *.o
    
.MYDEL://表示clean是一个伪标签
clean:
	rm -rf *.o myproject
        
$@——表示目标文件
$^——表示依赖文件
      
target=myproject
OBJ:=myadd.o mysub.o
OBJ+=myproject.o
CC:=gcc
CFLAGS:=-C
    
$(target):$(OBJ)
    $(CC) $^ -o $@
*.o:*.c
    $(CC) $(CFLAGS) $^ -o $@
    
.MYDEL://表示clean是一个伪标签
clean:
	rm -rf *.o $(target)
上一篇:Makefile学习笔记(1):基础书写格式


下一篇:06项目自动化构建工具-make/Makefile