Makefile详解(附通用Makefile)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/BluseLIBB/article/details/98619122
  • Makefile规则

    显示规则:
    规则目标:依赖
    <tab 空格> 命令(将依赖生成目标的规则)
    隐式规则:
    cc 依赖.c -c 依赖.o
    伪目标:
    没有依赖的目标
    变量定义
    自定义变量: 变量名=值(字符串替换)
    变量赋值
    变量名=值 替换赋值
    变量名+=值 追加赋值,变量增长
    变量名?=值 若变量存在,该语句不操作,若不存在,创建变量并赋值
    自动变量
    $* 不包含扩展名的目标文件名称
    $+ 所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件
    $< 第一个依赖文件的名称
    $? 所有时间戳比目标文件晚的的依赖文件,并以空格分开
    $@ 目标文件的完整名称
    $^ 所有不重复的目标依赖文件,以空格分开
    $% 如果目标是归档成员,则该变量表示目标的归档成员名称

    make
    选项
    -C dir读入指定目录下的Makefile
    -f file读入当前目录下的file文件作为Makefile
    -i忽略所有的命令执行错误
    -I dir指定被包含的Makefile所在目录
    -n只打印要执行的命令,但不执行这些命令
    -p显示make变量数据库和隐含规则
    -s在执行命令时不显示命令
    -w如果make在执行过程中改变目录,打印当前目录名

    环境变量
    环境变量make在启动时会自动读取系统当前已经定义了的环境变量,并且会创建与之具有相同名称和数值的变量
    如果用户在Makefile中定义了相同名称的变量,那么用户自定义变量将会覆盖同名的环境变量

    Makefile字符串操作
    ALLC=$(wildcard *.c)
    OBJ= ( p a t s u b s t (patsubst %.c,%.o, (ALLC))
    检测当前工程下的.c文件并将之修改为.o付给变量OBJ
    make OUTPUT=project_name 在编译时将输出可执行文件名
    make -f ~/Makefile 指定某个目录下的Makefile编译当前目录下的工程
    make -f ~/Makefile OUTPUT =hello

  • 简单示例

    新建test_1.c

     vim test_1.c
    

    写一个简单的程序

     #include<stdio.h>
     void main()
     {
             char msg[80]="Hello , World !!";
             printf("%s\n", msg);
     }
    

    写它的Makefile,单个文件体现不出Makefile的方便

     vim Makefile
     all:test_1.o
             gcc test_1.o -o test_1
     test_1.o:test_1.c
             gcc -c test_1.c -o test_1.o
     clean:
             rm *.o
    

    Makefile也可以这样写

     CC=gcc
     OBJECT=test_1.o
     all:$(OBJECT)
             $(CC) $(OBJECT) -o test_1
     test_1.o:test_1.c
             $(CC) -c test_1.c -o $(OBJECT)
     clean:
             rm *.o
    

    下面是一个多文件的Makefile(我记得是某本书上的例子)
    Version 1 挨个挨个文件的写

     CC=gcc
     TARGET=All
     OBJECTS=main.o visit.o listen.o watch.o study.o play.o
     $(TARGET):$(OBJECTS)
             $(CC) $(OBJECTS) -o main
     main.o:main.c main.h
             $(CC) -c main.c -o main.o
     visit.o:visit.c
             $(CC) -c visit.c -o visit.o
     listen.o:listen.c
             $(CC) -c listen.c -o listen.o
     study.o:study.c
             $(CC) -c study.c -o study.o
     watch.o:watch.c
             $(CC) -c watch.c -o watch.o
     paly.o:play.c
             $(CC) -c play.c -o play.o
     clean:
             rm * .o
    

    Version 2 使用了一些变量,对照版本1和版本2便于理解各文件之间的依赖关系

     vim Makefile
     CC=gcc
     TARGET=All
     OBJECTS=main.o visit.o listen.o watch.o study.o play.o
     $(TARGET):$(OBJECTS)
             $(CC) $(OBJECTS) -o main
     main.o:main.c main.h
             $(CC) -c $< -o $@
     visit.o:visit.c
             $(CC) -c $< -o $@
     listen.o:listen.c
             $(CC) -c $< -o $@
     study.o:study.c
             $(CC) -c $< -o $@
     watch.o:watch.c
             $(CC) -c $< -o $@
     paly.o:play.c
             $(CC) -c $< -o $@
     clean:
             rm * .o
    

    Version 3 这个看起就就简单多了 简单工程可直接以下面为模板

     vim Makefile
     CC=gcc
     TARGET=All
     OBJECTS=main.o visit.o listen.o watch.o study.o play.o
     $(TARGET):$(OBJECTS)
             $(CC) $^ -o main
     *.o:*.c
             $(CC) -c $< -o $@
     clean:
             rm * .o
    
  • 模板套用

    贴 一个很腻害的Makefile

     NAME = obj
     CFLAGS += -g   -O0  -mabi=apcs-gnu -mfpu=neon -mfloat-abi=softfp  -fno-builtin -nostdinc  -fexec-charset=GB2312 -I driver/include/ 
     CC = arm-none-linux-gnueabi-gcc
     LD = arm-none-linux-gnueabi-ld
     OBJCOPY = arm-none-linux-gnueabi-objcopy
     DIR = /mnt/hgfs/linuxworkspace/tmp/
     
     
     ALLC =$(wildcard *.c ./driver/src/*.c)
     ALLs =$(wildcard *.s ./driver/src/*.s)
     ALLS =$(wildcard *.S ./driver/src/*.S) 
     
     ALLO =$(patsubst %.c,%.o,$(ALLC))
     ALLO +=$(patsubst %.s,%.o,$(ALLs))
     ALLO +=$(patsubst %.S,%.o,$(ALLS))
     
     
     all:$(ALLO) 
     	@echo 连接文件$(ALLO)
     	@$(LD)   	$(ALLO) -T map.lds -o $(NAME).elf
     	@echo 生成可执行文件 $(NAME).bin
     	@$(OBJCOPY)	-O binary  $(NAME).elf $(NAME).bin
     	@echo 复制文件到目录 $(DIR)
     	cp $(NAME).bin  $(DIR)
     	@echo 清理中间文件
     	@rm  *.elf  *.o ./driver/src/*.o
     	@echo 操作完成
     %.o:%.c
     	@echo 编译文件 $< 
     	@$(CC) $(CFLAGS) -c $< -o $@
     
     %.o:%.s
     	@echo 编译文件 $< 
     	@$(CC) $(CFLAGS) -c $< -o $@
     
     %.o:%.S
     	@echo 编译文件 $< 
     	@$(CC) $(CFLAGS) -c $< -o $@
     
     clean:
     	rm ./driver/src/*.o
     	rm  *.elf *.bin *.o
    

    上面这个看看就可以了 下面这个复制粘贴到工程里面就可以用了

     ALLC=$(wildcard *.c)
     FILEO= $(patsubst %.c,%.o,$(ALLC))
     
     CC=gcc
     OUT=a.out
     CFLAG=-Wall -o
     
     all:$(FILEO)
     	$(CC) $^  $(CFLAG) $(OUT) 
     %.o:%.c
     	@echo 编译文件 $^ 
     	$(CC) -c $^ $(CFLAG) $@
     
     clean:
     	rm *.o
    

猜你喜欢

转载自blog.csdn.net/BluseLIBB/article/details/98619122
今日推荐