Makefile教程
来源:互联网 发布:正则表达式 手机号js码 编辑:程序博客网 时间:2024/06/08 02:57
arm裸板程序编译过程:
arm-linux-gnueabihf-gcc test.c -c -o test.o arm-linux-gnueabihf-gcc abc.c -c -o abc.o arm-linux-gnueabihf-ld test.o abc.o -o test arm-linux-gnueabihf-objcopy -O binary test test.bin
这个编译过程比较麻烦, 文件越多越麻烦. 但用Mafile来管理编译会方便很多.
1). 如当前目录下有: main.S, a.c , b.c 写Makefile来管理, 先记住Mafile是倒序来写的. 像我们最终目标是test.bin, 但test.bin由test生成, test又是由main.o、a.o 、b.o组成. main.o是由main.S, *.o 由 *.c生成. Makefile里的写法: test.bin : test //test.bin表示目标, test表示依赖. 也就是test.bin由test生成 arm-linux-gnueabihf-objcopy -O binary test test.bin //接着的这行写当有test之后怎样生成test.bin的语句. 注意执行语句前面不能有空格 test : main.o a.o b.o arm-linux-gnueabihf-ld main.o a.o b.o -o test main.o : main.S arm-linux-gnueabihf-gcc main.S -c -o main.o a.o : a.c arm-linux-gnueabihf-gcc a.c -c -o a.o b.o : b.c arm-linux-gnueabihf-gcc b.c -c -o b.o
2). Makefile里的符号 "$@" 表示目标, "$<"表示第一个依赖, "$^"表示所有的依赖 所以上例又可以改造成: test.bin : test arm-linux-gnueabihf-objcopy -O binary $< $@ test : main.o a.o b.o arm-linux-gnueabihf-ld $^ -o $@ main.o : main.S arm-linux-gnueabihf-gcc $< -c -o $@ a.o : a.c arm-linux-gnueabihf-gcc $< -c -o $@ b.o : b.c arm-linux-gnueabihf-gcc $< -c -o $@
3). Makefile里的通配符"%" test.bin : test arm-linux-gnueabihf-objcopy -O binary $< $@ test : main.o a.o b.o arm-linux-gnueabihf-ld $^ -o $@ %.o : %.S arm-linux-gnueabihf-gcc $< -c -o $@ %.o : %.c arm-linux-gnueabihf-gcc $< -c -o $@
4). Makefile里应用变量, 如CROSS_COMPILE变量用于指定交叉编译器的前缀. OBJS变量指定编译目标. TARGET指定生成程序镜像名. $(变量)就是取变量的值. 而且在执行Makefile时可以指定变量的值: "make CROSS_COMPILE=arm-linux-" CROSS_COMPILE ?= arm-linux-gnueabihf- OBJS += main.o OBJS += a.o OBJS += b.o TARGET ?= test $(TARGET).bin : $(TARGET) $(CROSS_COMPILE)objcopy -O binary $< $@ $(TARGET) : $(OBJS) $(CROSS_COMPILE)ld $^ -o $@ %.o : %.S $(CROSS_COMPILE)gcc $< -c -o $@ %.o : %.c $(CROSS_COMPILE)gcc $< -c -o $@
5). wildcard函数用于获取指定扩展名的所有文件名. patsubst函数可用于替换指定扩展名. 用法$(patsubst %.c, %.o, a.c b.c)) //把"a.c b.c"转换成"a.o b.o" 如实现获取当前目录所有源文件,并把文件名转换成对应的.o CFILES = $(wildcard *.c) //先获取当前目录下的所有.c文件名. 每个文件名空格隔开 SFILES = $(wildcard *.S) COBJS = $(patsubst %.c, %.o, $(CFILES)) //把文件名改成.o名字 SOBJS = $(patsubst %.S, %.o, $(SFILES)) OBJS += $(COBJS) OBJS += $(SOBJS) all: echo $(OBJS)
6). 执行Makefile时,如不指定目标,则默认执行第1个目标. 如"make uboot"表示只执行Makefile里的uboot目标 Makefile里的"PHONY"修饰目标时,可防止目录里有文件名与目标名一致时的冲突. .PHONY : clean clean: rm *.o -rf
7). 多个源码目录的Makefile编写. "make -C 目录路径"执行指定目录里的Makefile 如当前目录下有两个子目录cpu, drivers cpu目录里有start.S a.c main.c drivers目录里有a.c b.c c.c 可以先把子目录里的所有编译生成的.o文件打包成一个.o文件,最后再一起链接成可执行文件. cpu目录里的Makefile: CFILES = $(wildcard *.c) SFILES = $(wildcard *.S) COBJS = $(patsubst %.c, %.o, $(CFILES)) SOBJS = $(patsubst %.S, %.o, $(SFILES)) OBJS += $(COBJS) OBJS += $(SOBJS) libcpu.o : $(OBJS) arm-linux-gnueabihf-ld -r $^ -o $@ %.o : %.S arm-linux-gnueabihf-gcc $< -c -o $@ %.o : %.c arm-linux-gnueabihf-gcc $< -c -o $@ .PHONY : clean clean: rm $(OBJS) libcpu.o -rf drivers目录里的Makefile与cpu目录里的差不多,只是目标名为"libdrivers.o" 当前目录里的Makefile: test.bin : test arm-linux-gnueabihf-objcopy -O binary test test.bin test : mkcpu mkdrivers arm-linux-gnueabihf-ld cpu/libcpu.o drivers/libdrivers.o -o test mkcpu: make -C cpu/ mkdrivers: make -C drivers/ .PHONY : clean clean: make -C cpu/ clean make -C drivers clean
8). 上例子目录里的Makefile内容大多重复,可以进一步精简下. 把重复做的内容放到一个文件里,如: config.mk: CFILES = $(wildcard *.c) SFILES = $(wildcard *.S) COBJS = $(patsubst %.c, %.o, $(CFILES)) SOBJS = $(patsubst %.S, %.o, $(SFILES)) OBJS += $(COBJS) OBJS += $(SOBJS) config2.mk: %.o : %.S $(CROSS_COMPILE)gcc $< -c -o $@ $(CFLAGS) %.o : %.c $(CROSS_COMPILE)gcc $< -c -o $@ $(CFLAGS) .PHONY : clean clean: rm *.o -rf 当前目录的Makefile: #子目录里的Makefile使用此环境变量,需要加"export"成为全局环境变量才可以 export CROSS_COMPILE ?= arm-linux-gnueabihf- export CFLAGS = test.bin : test $(CROSS_COMPILE)objcopy -O binary test test.bin test : mkcpu mkdrivers $(CROSS_COMPILE)ld cpu/libcpu.o drivers/libdrivers.o -o test mkcpu: make -C cpu/ mkdrivers: make -C drivers/ .PHONY : clean clean: make -C cpu/ clean make -C drivers clean cpu子目录里的Makefile: include ../config.mk libcpu.o : $(OBJS) $(CROSS_COMPILE)ld -r $^ -o $@ include ../config2.mk drivers子目录里的Makefile: include ../config.mk libdrivers.o : $(OBJS) $(CROSS_COMPILE)ld -r $^ -o $@ include ../config2.mk
////////////////////////////////////////
还有更多的扩展方法可以在uboot, linux内核里的Makefile进行参考
阅读全文
0 0
- Makefile教程
- Makefile教程
- Makefile教程
- makefile教程
- makefile教程
- Makefile教程
- makefile教程
- makefile教程
- makefile教程
- makefile教程
- Makefile教程
- Makefile教程
- makefile教程
- makefile 教程
- makefile教程
- makefile教程
- makefile教程
- Makefile教程
- SpringMVC的拦截器(Interceptor)和过滤器(Filter)详解
- hadoop入门级总结二:Map/Reduce
- Qt动画框架-(3)分组动画
- よくある例外型
- 31个Android 开发者工具
- Makefile教程
- Android学习二、MediaPlayer播放视频
- 八段锦健身养生功法介绍
- hadoop入门级总结一:HDFS
- 用Caffe自带程序画网络结构图
- Spring MVC 请求响应流程
- Android代码混淆之混淆规则
- 【数据库-MySql】Procedure execution failed 1265
- Android 線上的opengrok