makefile及其相关知识介绍

发布者:SparklingStar22最新更新时间:2025-02-21 来源: cnblogs关键字:makefile  变量 手机看文章 扫描二维码
随时随地手机看文章

makefile是用来管理工程的。


示例1:


1 exe: a.c b.c

2         gcc a.c b.c -o exe

4 clean:

5         rm exe

基本概念:


目标:顶格写,在:前面


依赖: 在:后面,用来产生目标的原材料


命令:前面一定是table,不能是多个空格。命令是生成目标所做的动作


示例2:


 1 led.bin: start.o 

 2         arm-linux-ld -Ttext 0x0 -o led.elf $^

 3         arm-linux-objcopy -O binary led.elf led.bin

 4         arm-linux-objdump -D led.elf > led_elf.dis 

 5         gcc mkv210_image.c -o mkx210   // 该处生成的mkx210是为了在Linux下执行的,这里的gcc和交叉编译工具链的gcc不相同

 6         ./mkx210 led.bin 210.bin  

 7     

 8 %.o : %.S

 9         arm-linux-gcc -o $@ $< -c

10 

11 %.o : %.c

12         arm-linux-gcc -o $@ $< -c 

13 

14 clean:

15         rm *.o *.elf *.bin *.dis mkx210 -f


示例分析:


(1)Makefile有三个非常有用的变量。分别是$@,$^,$<代表的意义分别是: 


$@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件


(2)交叉编译工具链工具及作用


先决条件:linux系统下面有一个环境变量叫PATH,必须把该工具链的地址导入到该环境变量下面,export PATH=工具链地址:$PATH


最好是该语句加到~/.bash文件中,这样每次启动终端都会执行该语句。


arm-linux-gcc:


用来编译源文件


arm-linux-ld:


用来链接,其中,-Ttest是用来指定链接地址的,在该处也可以使用链接脚本来去进行链接。在该处生成的elf文件还不能烧录执行。


objcopy:


作用以led.elf为源材料为源材料制作镜像的工具。


解释:led.elf已经是可执行程序,在操作系统下已经可以执行,裸机中需要的是可以烧录的二进制文件(镜像image)。


以led.elf为源材料为源材料制作镜像


objdump:


作用:反汇编,将elf格式的可执行程序反过来得到其汇编源代码。


mkx210(由mkv210_image.c得到):


作用:以led.bin为源材料得到210.bin(为BL1添加校验头)


解释:usb启动时不需要头校验,SD卡启动时需要,让led.bin加上header(校验头)成为210.bin。


附:mkv210_image.c源程序:


  1 /*

  2  * mkv210_image.c的主要作用就是由usb启动时使用的led.bin制作得到由sd卡启动的镜像210.bin

  3  *

  4  * 本文件来自于友善之臂的裸机教程,据友善之臂的文档中讲述,本文件是一个热心网友提供,在此表示感谢。

  5  */

  6 /* 在BL0阶段,Irom内固化的代码读取nandflash或SD卡前16K的内容,

  7  * 并比对前16字节中的校验和是否正确,正确则继续,错误则停止。

  8  */

  9 #include

 10 #include

 11 #include

 12 

 13 #define BUFSIZE                 (16*1024)

 14 #define IMG_SIZE                (16*1024)

 15 #define SPL_HEADER_SIZE         16

 16 //#define SPL_HEADER              'S5PC110 HEADER  '

 17 #define SPL_HEADER              '****************'

 18 

 19 int main (int argc, char *argv[])

 20 {

 21     FILE        *fp;

 22     char        *Buf, *a;

 23     int        BufLen;

 24     int        nbytes, fileLen;

 25     unsigned int    checksum, count;

 26     int        i;

 27     

 28     // 1. 3个参数

 29     if (argc != 3)

 30     {

 31         printf('Usage: %s n', argv[0]);

 32         return -1;

 33     }

 34 

 35     // 2. 分配16K的buffer,并且全部填充为0

 36     BufLen = BUFSIZE;

 37     Buf = (char *)malloc(BufLen);

 38     if (!Buf)

 39     {

 40         printf('Alloc buffer failed!n');

 41         return -1;

 42     }

 43 

 44     memset(Buf, 0x00, BufLen);

 45 

 46     // 3. 读源bin到buffer

 47     // 3.1 打开源bin

 48     fp = fopen(argv[1], 'rb');

 49     if( fp == NULL)

 50     {

 51         printf('source file open errorn');

 52         free(Buf);

 53         return -1;

 54     }

 55     // 3.2 获取源bin长度

 56     fseek(fp, 0L, SEEK_END);                                // 定位到文件尾

 57     fileLen = ftell(fp);                                    // 得到文件长度

 58     fseek(fp, 0L, SEEK_SET);                                // 再次定位到文件头

 59     // 3.3 源bin长度不得超过16K-16byte

 60     count = (fileLen < (IMG_SIZE - SPL_HEADER_SIZE))

 61         ? fileLen : (IMG_SIZE - SPL_HEADER_SIZE);

 62     // 3.4 buffer[0~15]存放'S5PC110 HEADER  '

 63     memcpy(&Buf[0], SPL_HEADER, SPL_HEADER_SIZE);

 64     // 3.5 读源bin到buffer[16]

 65     nbytes = fread(Buf + SPL_HEADER_SIZE, 1, count, fp);

 66     if ( nbytes != count )

 67     {

 68         printf('source file read errorn');

 69         free(Buf);

 70         fclose(fp);

 71         return -1;

 72     }

 73     fclose(fp);

 74 

 75     // 4. 计算校验和

 76      // 4.1 从第16byte开始统计buffer中共有几个1

 77     // 4.1 从第16byte开始计算,把buffer中所有的字节数据加和起来得到的结果

 78     a = Buf + SPL_HEADER_SIZE;

 79     for(i = 0, checksum = 0; i < IMG_SIZE - SPL_HEADER_SIZE; i++)

 80         checksum += (0x000000FF) & *a++;

 81     // 4.2 将校验和保存在buffer[8~15]

 82     a = Buf + 8;                            // Buf是210.bin的起始地址,+8表示向后位移2个字,也就是说写入到第3个字

 83     *( (unsigned int *)a ) = checksum;

 84 

 85     // 5. 拷贝buffer中的内容到目的bin

 86     // 5.1 打开目的bin

 87     fp = fopen(argv[2], 'wb');

 88     if (fp == NULL)

 89     {

 90         printf('destination file open errorn');

 91         free(Buf);

 92         return -1;

 93     }

 94     // 5.2 将16k的buffer拷贝到目的bin中

 95     a = Buf;

 96     nbytes    = fwrite( a, 1, BufLen, fp);

 97     if ( nbytes != BufLen )

 98     {

 99         printf('destination file write errorn');

100         free(Buf);

101         fclose(fp);

102         return -1;

103     }

104 

105     free(Buf);

106     fclose(fp);

107 

108     return 0;

109 }


(3)指令解释


-c: 只编译不链接


-o: 用来指定名字


-D: 表示反汇编(反汇编工具有多种用法,-D表示反汇编用法)


-Ttext: 指定代码段的起始地址(链接地址)


(4)其它


第8行到第12行叫做makefile的规则,当看到.S和.c文件会自动转化为.o文件。


printf移植中用到的makefile


 1 CC         = arm-linux-gcc

 2 LD         = arm-linux-ld

 3 OBJCOPY = arm-linux-objcopy

 4 OBJDUMP = arm-linux-objdump

 5 AR         = arm-linux-ar

 6 

 7 INCDIR := $(shell pwd)

 8 

 9 # c预处理器的flag,flag就是编译器可选的选项

10 CPPFLAGS    := -nostdlib -nostdinc -I$(INCDIR)/include

11 # C编译器的flag

12 CFLAGS        := -Wall -O2 -fno-builtin                

13 

14 # 导出这些变量到全局,其实就是给子文件下面的makefile使用

15 export CC LD OBJCOPY OBJDUMP AR CPPFLAGS CFLAGS

16 

17 

18 objs := start.o led.o clock.o uart.o main.o

19 objs += lib/libc.a

20 

21 uart.bin: $(objs) 

22     $(LD) -Tlink.lds -o uart.elf $^

23     $(OBJCOPY) -O binary uart.elf uart.bin

24     $(OBJDUMP) -D uart.elf > uart_elf.dis

25     gcc mkv210_image.c -o mkx210

26     ./mkx210 uart.bin 210.bin

27     

28 lib/libc.a:

29     cd lib; make; cd ..

30     

31 

32     

33 %.o : %.S

34     $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< -c 

35 

36 %.o : %.c

37     $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< -c 

38 

39 clean:

40     rm *.o *.elf *.bin *.dis mkx210 -f

41     cd lib; make clean; cd ..


 -nostdlib 不用标准库


-nostdinc 不用标准的头文件


-O2   编译器的优化等级


-Wall  显示所有警告


-I           用来表示寻找头文件的目录(一般用相对路径表示)


关键字:makefile  变量 引用地址:makefile及其相关知识介绍

上一篇:C语言高级第一节杂谈
下一篇:[国嵌笔记][029][ARM处理器启动流程分析v2]

推荐阅读最新更新时间:2026-03-25 11:59

工程师:我推荐这些国产电池管理芯片!
前阵子,EEWorld论坛发起了一次话题讨论,邀请工程师谈一谈在选择电池管理芯片时,重点考虑哪些指标或因素,并鼓励网友推荐自己使用过的具体产品。(原帖地址: https://www.eeworld.com.cn/a90Oeb1) 工程师的推荐,往往是来自一线的心声,希望以下经验能够帮助广大网友。 坛友:qwqwqw2088 BMS芯片,并非特指一种芯片,而是AFE(电池采样芯片)、MCU(微控制处理单元)、ADC(模拟数字转换器)、数字隔离器等产品的统称。按以上说法,把这几个功能包括软件系统集成一起的国产厂商并不多,但有几家电池管理芯片厂,还是很不错的。 比如杰华特的多电池组监控和
[电源管理]
<font color='red'>工程</font>师:我推荐这些国产电池<font color='red'>管理</font>芯片!
新 MATLAB Test 使工程师和研究人员能大规模开发、执行、测量和管理 MATLAB 代码中的动态测试
新的 MATLAB Test 使工程师和研究人员能够大规模开发、执行、测量和管理 MATLAB 代码中的动态测试 MATLAB 和 Simulink 版本 2023a 还包括全新的与更新的模块集及工具箱,可简化航空航天、汽车和无线通信行业中基于模型的设计 中国 北京,2023 年 3 月 22 日 —— MathWorks 今天发布了 MATLAB® 和 Simulink® 产品系列版本 2023a(R2023a)。 R2023a 推出了两款新产品和增强功能,支持工程师和研究人员开发、执行、管理、测试、验证其 MATLAB 代码工程,并生成相关文档。 MATLAB Test™ 使工程师和研究人员能够大规模开发、执行、测
[工业控制]
Linux之ARM(IMX6U)BSP工程管理实验
在我们写工程中,我们都是将所有的源码文件放到工程的根目录下,如果工程文件比较少的话这样做无可厚非,但是如果工程源文件达到几十、甚至数百个的时候,这样一股脑全部放到根目录下就会使工程显得混乱不堪。所以我们必须对工程文件做管理,将不同功能的源码文件放到不同的目录中。另外我们也需要将源码文件中,所有完成同一个功能的代码提取出来放到一个单独的文件中,也就是对程序分功能管理。本章我们就来学习一下如何对一个工程进行整理,使其美观、功能模块清晰、易于阅读。 1、工程管理简介 在我们上一篇博客中(Linux之ARM(MX6U)裸机官方SDK移植)中,文件有: 我们将所有的源码文件都放到工程根目录下,即使这个工程只是完成了一个简单的流水灯的
[单片机]
Linux之ARM(IMX6U)BSP<font color='red'>工程</font><font color='red'>管理</font>实验
使用git管理KEIL5开发的单片机工程文件
前置知识 使用KEIL5开发stm32比较方便,在程序编译、连接等中间过程中会产生很多无用文件。比如一个STM32项目正常编译通过后整个项目大小为: 使用正点原子提供的keilkill.bat执行无用文件删除后文件大小为: 可以看出体积相差10倍多,一般为了备份保存,我们只需要保存执行完keil killbat的项目文件夹即可。 注意:删除无用文件后,不影响程序的正常用呢个。通过build可进行重新编译生成。 基本原理 git可指定忽略的文件类型,我们只需要将上述keilkill.bat脚本中指定删除特定扩展名的文件类型设置为git忽略即可。 具体操作 第一步:增加忽略文件 在git工程根目录下新建 .gitign
[单片机]
使用git<font color='red'>管理</font>KEIL5开发的单片机<font color='red'>工程</font>文件
STM32CubeMX系列教程06_Project Manager工程管理器详细说明
一、写在前面 STM32CubeMX的Project Manager工程管理器包含:Project工程管理、 Code Generator代码生成、 Advanced Settings高级设置三部分内容。 这三部分内容决定了工程的一些属性,相关的配置信息比较重要,也容易理解。初学者有必要掌握其中内容。 二、Project工程管理 Project工程管理包含三部分内容:Projcet Settings工程设置、 Linker Settings堆栈设置、 Mcu and Firmware Package MCU和固件包信息。 2.1 Projcet Settings工程设置 A.Project Name:工程名称
[单片机]
STM32CubeMX系列教程06_Project Manager<font color='red'>工程</font><font color='red'>管理</font>器详细说明
霍尼韦尔与树根互联合作展出工程机械车辆的健康管理平台
2018年4月24日,德国汉诺威市—霍尼韦尔(纽约证券交易所股票交易代码:HON)宣布与树根互联技术有限公司签署了合作备忘录,双方将合作开发针对工程机械车辆与设备的车辆健康管理软件平台,并在最近的德国汉诺威工业博览会上展示了该方案。 工程机械车辆与设备是建筑、矿业以及农业在内的重要行业的必要生产工具。全球每年因工程机械车辆宕机而造成巨大停工损失。霍尼韦尔预测性诊断功能可识别潜在发生故障隐患。结合树根互联的“根云”工业物联网(IIoT)大数据平台,车队管理者可提前安排维修计划并轮修设备以降低停工损失。 随着车辆采用的电子零部件的大量使用,包括挖机等工程车辆和设备的故障愈发复杂多样,极大增加了维护人员判断车辆健康状况和锁定故障
[物联网]
管理现场总线工程
与其它自动化工程毫无区别,成功实施一项现场总线工程的关键延伸是人。和其它努力一样,人也需要来“为了成功而设置”,也就是在团队里完成他们角色的正确技能。 1 、培训 确保团队里的每一个成员都会使用某一技术的方法就是通过培训。因此,一个成功的现场总线工程的最关键因素就是培训。进行团体培训不仅可以确保团队中的每一个成员至少可以拥有相同的理解基础,而且可以用同样的方式使用这个团队。另外,进行成组的初始化培训,以团队服务为每一个成员进行操作训练。 记住,即使你决定以后会用到其它不同的技术,进行团体培训也会比当这项技术的影响力变的很大,不得不对同样的内容进行重复培训所花的费用要少的多。 由澳大利亚终端用户委员会发起的这个在可能会某一天变的十
[嵌入式]
使用Makefile在Windows环境下编译STM32F103C8T6标准库工程,脱离Keil的指南
引言 前段时间学习了Makefile,了解到其批量编译的功能。所以去尝试复刻到keil编译文件。这里实现了window下实现makefile对标准库来编译。之后也会在Linux环境下继续探索。 这里的核心软件还是gcc-arm-none-eabi的arm环境,与MinGW64提供的make软件。 核心修改点为makefile文件的修改与标准库函数里面的两个函数的修改。个人认为这种方法应该也可以用到别的芯片上面,不过目前没有去验证。我会提供此次使用的全部工程文件。每次上传文件到csdn,别人下载都会要收费或者收积分,我真的:)- 一、软件与环境准备 我们需要准备三个环境包与一个软件(提供一个Make file模板) MInG
[单片机]
使用<font color='red'>Makefile</font>在Windows环境下编译STM32F103C8T6标准库<font color='red'>工程</font>,脱离Keil的指南
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved