makefile

gcc编译的原理

1、预处理

   gcc -E main.c > main.i

   作用:

       1、展开头文件

       2、宏替换

       3、去掉注释

       4、条件编译

2、编译

    gcc -S main.i

    作用:

        1、将代码转成汇编代码

3、汇编

    gcc -c main.s

    作用:

        将汇编转成机器码 .o文件就是常见的依赖项

4、链接

gcc main.o

作用:编译器将多个.o文件链接到一起,生成一个a.out/.exe可执行文件

Makefile基本语法

Makefile就是将一系列的工作流串到一起自动执行,构成Makefile最基本的要素是目标、依赖、命令。也就是为了实现目标需要那些依赖并执行什么样的命令。

目标:一般是指要编译的目标,也可是一个动作。

依赖:指执行当前目标所要依赖的选项,包括其他目标,某个具体文件或库等,一个目标可以 有多个依赖。

命令:该目标下要执行的具体命令,可以没有、也可以有多条。

实例:

targe:dependences1 dependences2 ...

    command1 command2 ...

其中,target表示要生成的目标,dependences表示生成target需要的依赖,而command就是生成target要执行什么命令。格式上,命令所在行行首都有一个<tab>(备注:4个space键不可以:makefile:2 ***missing separator. Stop).

Makefile变量

Makefile也支持变量,使用上和Shell中的变量很相似,比如:Makefile中的变量可以分为三大类:系统变量、系统常量和自定义变量。

系统变量:

$*不包括扩展名的目标文件名称

$@表示目标文件的完整名称

$<表示第一个依赖文件

$?表示比目标文件还要新的依赖文件列表

$^表示所有不重复的依赖文件,以空格分隔

$+这个变量很像"$^",也是所有依赖目标的集合,只是它不去除重复的依赖目标

$% 仅当目标是归档成员,则该变量表示目标的归档成员名单

系统常量(可以使用make -p命令查看)

AR:函数库打包程序,默认命令是ar

AS:汇编语言编译程序,默认命令是as

CC:C语言编译程序,默认命令是cc

CXX:C++语言编译程序,默认命令是g++

CPP:C语言的预处理器,(输出是标准输出设备),默认命令是$(cc) -E

RM:删除文件命令,默认命令是rm -f

Makefile模式匹配

在Makefile中模式匹配使用%来实现,表示匹配任意多个非空字符,相当于shell中的*。

模式匹配有什么用呢?

假如现在有非常多的.c源文件要生成目标.o源文件,我们可以像下面这样写:

%.o:%.c

cc -c $^ -o $@

上面的意思是将所有.c文件都经过编译器编译生成.o文件,其中表示的是所有依赖,在上面的场景中就是当前目录下所有.c文件。而$^表示的是所有依赖,在上面的场景中就是当前目录下所有.c文件。而表示的是所有的依赖,在上面的场景中就是当前目录下所有.c文件。而$@表示目标文件,也就是%.o所代表的所有文件。可以看到模式匹配可以大幅减少Makefile的代码量。

OBJ=$(patsubst %.c, %.o, $(wildcard ./*.c)) #将当前目录下所有.c文件替换成.o文件

main:$(OBJ)
	gcc main.o myAdd.o mySub.o -o main  

%.o:%.c 
	gcc -c main.c -o main.o  

wildcard:匹配文件。(使用例示:获取指定目录下所有.c文件)

patsubst:模式匹配与替换(使用例示:指定目录下所有.c文件替换成.o文件)

[Makefile 动态库] (wins:.dll文件 类uinx: .so文件)

动态库链接:不会把代码编译到二进制文件中,而是在运行时候才会去加载,所以只需要一个地址。

-fPIC:产生位置无关的代码

-shared:共享

-l(小写L):指定动态库

-I(大写i):指定头文件目录,默认当前目录

-L:手动指定库文件搜索目录,默认只链接共享目录

gcc -shared -fPIC SoTest.c -o libSoTest.so

gcc -ISoTest -L/main.c -o main

提供libSoTest.so和SoTest.h给客户使用

生成动态库

OBJ=$(patsubst %.c, %.o, $(wildcard ./*.c))
TARGET=libMyAdd.so

LIBPATH=/usr/lib/

$(TARGET):$(OBJ)
	$(CC) -shared  -fPIC $^ -o $@
	cp $(TARGET) $(LIBPATH)

使用动态库

OBJ=$(patsubst %.c, %.o, $(wildcard ./*.c))
TARGET=main

LDFLAGS=-L./src_so
LIBS=-lMyAdd


$(TARGET):$(OBJ)
	$(CC) $^ $(LIBS) $(LDFLAGS) -o $@

[Makefile]静态库

静态链接库:会把静态库的代码编译到二进制中,当程序编译完成后,该文件可以删除。

缺点:程序体积过大,并且库中的内容如果有更新,则需要重新编译生成程序。

OBJ=$(patsubst %.c, %.o, $(wildcard ./*.c))
TARGET=libMySub.a


$(TARGET):$(OBJ)
	$(AR) -r $(TARGET) $^

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值