Linux学习之Makefile编写

1.GCC常见命令

1.1 查看gcc版本号

查看GCC版本号
Target: x86_64-linux-gnu :说明只能编译在X86架构上运行的程序

1.2 GCC输出目标文件

编译生成目标文件及错误提示
GCC输出目标文件
GCC 中错误提示

1.3 编译流程

GCC编译器的编译流程是:预处理、编译 、汇编和链接。预处理 就是展开所有的头文件、
替换程序中的宏、解析条件编译并添加到文件中。编译是将经过预编译处理的代码编译成汇编
代码,也就是我们常说的程序编译。汇编就是将汇编语言文件编译成二进制目标文件。链接就
是将汇编出来的多个二进制目标文件链接在一起,形成最终的可执行文件,链接的时候还会涉
及到静态库和动态库等问题。
引用自:《【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.6》

2.Makefile基础

2.1 编译多个文件

在这里插入图片描述

引入问题:如果项目有很多文件,一次编译时间非常长,如何之编译修改后的文件?

2.2 单独编译各个文件,最后链接

在这里插入图片描述
-c 命令为只编译不链接, 假如只修改了某个文件,只对该文件进行编译,最有再一起链接即可

问题:加入不记得自己修改了哪个文件该如何处理?

2.3 Makefile基础

在这里插入图片描述

上述代码中一共有5条规则,1、2行为第一条规则,3、4行为第二条规则,5~6行为第三条
规则,,7、8行为第四条规则,10~12为第五条规则,make命令在执行这个Makefile的时候其执
行步骤如下:
首先更新第一条规则中的main,第一条规则的目标成为默认目标,只要默认目标更新了那
么就认为Makefile的工作。在第一次编译的时候由于main还不存在,因此第一条规则会执行,
第一条规则依赖于文件main.o、input.o和calcu.o这个三个.o文件,这三个.o文件目前还都没
有,因此必须先更新这三个文件。make会查找以这三个.o文件为目标的规则并执行。以main.o为例,发现更新main.o的是第二条规则,因此会执行第二条规则,第二条规则里面的命令为“gcc–cmain.c”,这行命令很熟悉了吧,就是不链接编译main.c,生成main.o,其它两个.o文件同理。
最后一个规则目标是clean,它没有依赖文件,因此会默认为依赖文件都是最新的,所以其对应
的命令不会执行,当我们想要执行clean的话可以直接使用命令“makeclean”,执行以后就会删
命令列表中的每条命令必须以TAB键开始,不能使用空格!
引用自:《【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.6》

2.4 引入其他变量

常用自动化变量
在这里插入图片描述

在这里插入图片描述

3.Linux驱动中实际用到的Makefile文件

3.1 汇编驱动LED灯实验

led.bin:led.s
	arm-linux-gnueabihf-gcc -g -c led.s -o led.o
	arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf
	arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
	arm-linux-gnueabihf-objdump -D led.elf > led.dis
clean:
	rm -rf *.o led.bin led.elf led.dis
  • arm-linux-gnueabihf-gcc -g -c led.s -o led.o
    -g产生调试信息
    -c编译源文件不链接
    -o指定编译产生的文件名
    用到交叉编译器为arm-linux-gnueabihf-gcc

  • arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf
    arm-linux-gnueabihf-ld 用来将众多的.o 文件链接到一个指定的链接位置

  • arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
    “-O”选项指定以什么格式输出 binary为二进制 “-S”表示不要复制源文件中的重定位信息和符号信息,“-g”表示不复制源文件中的调试信息

  • arm-linux-gnueabihf-objdump -D led.elf > led.dis
    上述代码中的“-D”选项表示反汇编所有的段

3.2 C语言驱动LED灯实验

在这里插入图片描述

  • 第4行

arm-linux-gnueabihf-ld -Timx6ul.lds -o ledc.elf $^ 相当于arm-linux-gnueabihf-ld -Ttext 0X87800000 -o ledc.elf start.o main.o , ”S“”的意思是所有依赖文件的集合

  • 第5行

arm-linux-gnueabihf-objcopy -O binary -S ledc.elf @ 相 当 于 r m − l i n u x − g n u e a b i h f − o b j c o p y − O b i n a r y − S l e d c . e l f l e d c . b i n , " @ 相当于rm-linux-gnueabihf-objcopy -O binary -S ledc.elf ledc.bin," @rmlinuxgnueabihfobjcopyObinarySledc.elfledc.bin"@"的意思是所有目标文件集合

  • 第8、9行

%.o:%.s #模式规则
arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o $@ $< 相当于rm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o start.o start.s

3.3 官方SDK移植实验

在这里插入图片描述

  • Makefile中赋值规则

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.4 bsp工程管理实验

在这里插入图片描述
Makefile指定头文件路径,需要-I。我们编译源码的时候需要指定头文件路径。比如
bsp/clk/bsp_clk.h 变为-I bsp/clk/bsp_clk.h
通过一堆的变量,将要编译的原材料准备好了。
Makefile静态模式
<targets …>: : <prereq-patterns …>
$(OBJS): obj/%.o : %.S 表示将所有的.S文件编译为.o并且存放到obj目录下去

CROSS_COMPILE 	?= arm-linux-gnueabihf-

TARGET		  	?= bsp



CC 				:= $(CROSS_COMPILE)gcc

LD				:= $(CROSS_COMPILE)ld

OBJCOPY 		:= $(CROSS_COMPILE)objcopy

OBJDUMP 		:= $(CROSS_COMPILE)objdump



INCDIRS 		:= imx6ul \   #NCDIRS := imx6ul bsp/clk bsp/led bsp/delay 头文件路径

				   bsp/clk \

				   bsp/led \

				   bsp/delay 

				   			   

SRCDIRS			:= project \  #SRCDIRS := project bsp/clk bsp/led bsp/delay

				   bsp/clk \

				   bsp/led \

				   bsp/delay 

				   

				   
#INCLUDE := -I imx6ul -I bsp/clk -I bsp/led -I bsp/delay
INCLUDE			:= $(patsubst %, -I %, $(INCDIRS)) 


#SFILES := project/start.S
SFILES			:= $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))

#CFILES = project/main.c bsp/clk/bsp_clk.c bsp/led/bsp_led.c bsp/delay/bsp_delay.c 
CFILES			:= $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))



SFILENDIR		:= $(notdir  $(SFILES))

CFILENDIR		:= $(notdir  $(CFILES))


#目标文件存放路径
SOBJS			:= $(patsubst %, obj/%, $(SFILENDIR:.S=.o))

COBJS			:= $(patsubst %, obj/%, $(CFILENDIR:.c=.o))

OBJS			:= $(SOBJS) $(COBJS)  



VPATH			:= $(SRCDIRS)



.PHONY: clean

	

$(TARGET).bin : $(OBJS)

	$(LD) -Timx6ul.lds -o $(TARGET).elf $^

	$(OBJCOPY) -O binary -S $(TARGET).elf $@

	$(OBJDUMP) -D -m arm $(TARGET).elf > $(TARGET).dis



$(SOBJS) : obj/%.o : %.S

	$(CC) -Wall -nostdlib -c -O2  $(INCLUDE) -o $@ $<



$(COBJS) : obj/%.o : %.c

	$(CC) -Wall -nostdlib -c -O2  $(INCLUDE) -o $@ $<

	

clean:

	rm -rf $(TARGET).elf $(TARGET).dis $(TARGET).bin $(COBJS) $(SOBJS)


  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

i阳光仔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值