makefile 中$@ $< $^含义

  • Post author:
  • Post category:其他


宏观编译对应的微观编译步骤:

对应步骤如下:

编译:

预编译        : 展开头文件和宏定义

编译compile :            main.c -> main.s                arm-linux-gcc -S main.c

汇编assembly:          main.s -> main.o                arm-linux-as -o main.o main.s

链接link    :                main.o -> main(elf)             arm-linux-ld main.o -o main

生成二进制文件:       main -> main.bin

查看反汇编命令

./aarch64-linux-gnu-objdump  -S main -a arm -C

现列举几个做实验的文件:

main.c main.h display.c display.h

目的是想要通过一个makefile实现是这几个文件的编译管理


main.c:

#include "display.h"
int main(int argc, char *argv[])
{
	display();	
	return 0;
}
int test_read(){ 	return 0;  }
int test_write(){	return 0;  }

main.h

#ifndef _MAIN_H_
#define _MAIN_H_
int test_read();
int test_write();
#endif

display.c

#include "display.h"
void display()
{
	printf("======================\n");
	printf("==r==read opt ========\n");
	printf("==w==write opt========\n");
	printf("==q==quit opt ========\n");
}

display.h

#ifndef _DISPLY_H_
#define _DISPLY_H_
void display();
#endif

正常一两个文件我们直接在目录下执行

gcc main.c display.c -o main   直接执行就可以了

如果文件较多并且只更新一个或几个文件来编译就要用makefile

CC := gcc                                #声明一个变量

src_o := main.o display.o        #声明变量表示所有 .o 汇编后的中间文件

.PHONY :all                             #声明一个伪目标

all:    main                                #

main : $(src_o)                        #目标为 main  依赖于 main.o  display.o

$(CC) -o $@ $^                   #翻一下就是 gcc -o main   main.o display.o

%.o : %.c                                 #匹配%.o   匹配%.c

$(CC) -c $<                         # gcc -c  main.c  ;  gcc -c display.c

.PHONY :clean

clean:

rm *.o main -f


解释三个变量: $@    $<    $^

$@ : 表示目标

$^: 表示所有依赖

$<: 表示第一个依赖

%.o : %.c                                 #匹配%.o   匹配%.c

$(CC) -c $<                         # gcc -c  main.c  ;  gcc -c display.c

%.c 有多个  main.c 和 display.c 因此匹配后%.o 也有多个

这个  $(CC) -c $<   就会执行多次, 分别是gcc -c  main.c 和gcc -c display.c

我的实验环境是使用xilinx zcu102 开发板:

编译:

aarch64-linux-gnu-gcc -S main.c

aarch64-linux-gnu-gcc -S display.c

aarch64-linux-gnu-as main.s -o main.o

aarch64-linux-gnu-as display.s -odisplay.o

aarch64-linux-gnu-ld main.o display.o -o main



aarch64-linux-gnu-objdump -S main -C

最后有个报错: 因为没有指定入口,GNU汇编文件一般都是_start: 为入口, 给分配了默认起始执行地址,也可以添加lds指定。

形式如下:

.globl _start:

_start:

b   reset

…..



版权声明:本文为c4679281314原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。