4270|4

655

帖子

30

TA的资源

版主

楼主
 

18“万里”树莓派小车——Makefile学习 [复制链接]

本帖最后由 lb8820265 于 2021-12-13 23:43 编辑

前面介绍过电机驱动C++代码,使用了Makefile进行多文件编译,原本不想深入了解,可是往后发现不会Makefile语言后面还真是寸步难行,是时候学习一下了。

系统的学习还是推荐“C语言中文网”http://c.biancheng.net/makefile/,Makefile就是一个纯文本,电机驱动Makefile内容如下。

CROSS =
CC = $(CROSS)gcc
CXX = $(CROSS)g++
DEBUG = -g -O2
CFLAGS = $(DEBUG) -Wall -c
SRCS = $(wildcard ./*.cpp)
OBJS = $(patsubst %.cpp, %.o, $(SRCS))
TARGET = out
$(TARGET) : $(OBJS)
$(CXX) -o $@ $^ -lwiringPi  
rm -rf $(OBJS)
$(OBJS):%.o : %.cpp
$(CXX) $(CFLAGS) $< -o  $@

     这看起来就像是一堆乱码,下面介绍一些基本知识。

Makefile的结构

targets : prerequisites
       Command

     电机驱动Makefile中最后五行代码就体现了该基本结构。通过下面的例子来具体使用一下 Makefile 的规则:

test:test.c    
 gcc -o test test.c
  • targets:规则的目标,可以是 Object File(一般称它为中间文件),也可以是可执行文件,还可以是一个标签;
  • prerequisites:是我们的依赖文件,要生成 targets 需要的文件或者是目标。可以是多个,也可以是没有;
  • command:make 需要执行的命令(任意的 shell 命令)。可以有多条命令,每一条命令占一行。

      上述代码实现的功能就是编译 test.c 文件,通过这个实例可以详细的说明 Makefile 的具体的使用。其中 test 是的目标文件,也是我们的最终生成的可执行文件。依赖文件就是 test.c 源文件,重建目标文件需要执行的操作是gcc -o test test.c。

Makefile的工流程

    电机驱动Makefile中需要编译多个文件,因此需要知道工作流程,例如当有main.c和test1.c两个文件的工程需要编译时Makefile文件如下。

main:main.o test1.o
   gcc main.o test1.o -o main
main.o:main.c test.h
   gcc -c main.c -o main.o
test1.o:test1.c test.h
   gcc -c test1.c -o test1.o

第一行是最终需要生成的文件, main是可执行文件名,main.o、test1.o是依赖文件,也就是中间文件。

第二行是生成main需要执行的操作。

第三行是生成中间件main.o所需要的依赖文件。

第四行是生成main.o需要执行的操作。

第五六行与第三四行含义类似。

gcc的基本语法

     这里补充一下gcc的最基本的编译链接命令。详见“C语言中文网”。

编译:

gcc -c test.s

     将汇编输出文件test.s编译输出test.o文件。加“-Wall”表示产生尽可能多的警告信息。

链接:

gcc test.c -o test

     将test.c预处理、汇编、编译并链接形成可执行文件test。-o选项用来指定输出文件的文件名,可以缺省,-lwiringPi表示添加wiringPi链接库

变量的定义

在Makefile中有“=”号的就叫做变量的定义,有点像宏定义,等号右边的可以用等号左边的代替。例如。

VALUE_LIST = one two three

调用变量的时候用

$(VALUE_LIST)

电机驱动中前8行都是使用的变量的定义和调用。

通配符

代码中“*.cpp”表示所有后缀是“.cpp”的文件,“*”:匹配0个或者是任意个字符。但注意不能通过引用变量的方式来使用通配符,例如

OBJ=*.c
test:$(OBJ)

直接识别成了一个文件。文件名是 "*.c"。正确的是使用扩展函数“wildcard”,如下

OBJ=$(wildcard *.c)

顺便介绍一下路径,假设工程中有子文件夹“sub”,那么该选择该文件夹下所有.c文件就的命令为。

OBJ=$(wildcard ./sub/*.c)

当前路径可以用“./”或者直接缺省。

代码中“%.o : %.cpp”表示,提取所有的“.o”结尾的的文件名列表,然后替换“.cpp”后缀的。

同样的也有替换通配符函数patsubst,它需要三个参数,第一个是需要匹配的式样,第二个表示用什么来替换它,第三个是需要被处理的字列。

自动化变量

     在 Makefile 中描述规则时,依赖文件和目标文件是变动的,显然在命令中不能出现具体的文件名称,否则模式规则将失去意义。这就需要使用“自动化变量”。

$@:表示规则的目标文件名。

$<:规则的第一个依赖的文件名。

$^:代表的是所有依赖文件列表,使用空格分隔。

删除指令

大名鼎鼎的删库跑路代码。

rm -rf

       删除当前目录下的所有文件及目录,并且是直接删除,无需逐一确认。

运行结果

知道了上面这些规则,替换所有的变量,自动化变量,通配符,这个Makefile的含义也就清楚了。输入make,会输出如下的命令。

g++ -g -O2 -Wall -c Emakefun_MotorDriver.cpp -o  Emakefun_MotorDriver.o 
g++ -g -O2 -Wall -c DC_MotoTest.cpp -o  DC_MotoTest.o 
g++ -g -O2 -Wall -c Emakefun_MotorShield.cpp -o  Emakefun_MotorShield.o 
g++ -g -O2 -Wall -c Raspi_i2c.cpp -o  Raspi_i2c.o 
g++ -o out Emakefun_MotorDriver.o DC_MotoTest.o Emakefun_MotorShield.o Raspi_i2c.o -lwiringPi  
rm -rf  Emakefun_MotorDriver.o  DC_MotoTest.o  Emakefun_MotorShield.o  Raspi_i2c.o

问题

Makefile文件看起来还是挺复杂的,有不有更简单的办法,不用自己写Makefile,而让什么软件自动生成呢?

此帖出自创意市集论坛

最新回复

"万里"树莓派小车汇总贴: lb8820265的“万里”树莓派小车开源分享 - DIY/开源硬件专区 - 电子工程世界-论坛 (eeworld.com.cn)   目录:   “万里”树莓派小车开张贴  1“万里”树莓派小车——建立项目仓库 2“万里”树莓派小车——python学习(Thonny的使用) 3“万里”树莓派小车——python学习(定时任务) 4“万里”树莓派小车——C++学习(编译与运行,geany使用) 5“万里”树莓派小车——wiringPi学习(延时与线程模拟定时器) 6“万里”树莓派小车——wiringPi学习(PWM与外部中断模拟定时器) 7“万里”树莓派小车——RPi.GPIO学习(PWM与外部中断模拟定时器) 8“万里”树莓派小车——socket学习(本机通讯) 9“万里”树莓派小车——socket学习(TCP两机通讯) 10“万里”树莓派小车——socket学习(UDP两机通讯) 11“万里”树莓派小车——socket学习(Android发送) 12“万里”树莓派小车——socket学习(Android收发) 13“万里”树莓派小车——配件准备 14“万里”树莓派小车——电机驱动学习 15“万里”树莓派小车——光电编码器学习(正反转的判断) 16“万里”树莓派小车——光电编码器学习(转速的获取) 17“万里”树莓派小车——VSCode学习(编译和调试) 18“万里”树莓派小车——Makefile学习 19“万里”树莓派小车——VSCode学习(多C文件链接调试) 20“万里”树莓派小车——电机控制学习(控制速度) 21“万里”树莓派小车——电机控制学习(4轮速度控制) 22“万里”树莓派小车——手机遥控电机转动 23“万里”树莓派小车——无屏幕连接树莓派 24“万里”树莓派小车——树莓派64位系统bullseye跑分测试 25“万里”树莓派小车——纳姆轮控制 26“万里”树莓派小车——程序开机启动 27“万里”树莓派小车——固定和获取树莓派IP地址 28“万里”树莓派小车——小车组装 29“万里”树莓派小车——直行偏向问题与新控制模式 30.“万里”树莓派小车——第一阶段完成展示(从零开始介绍)   详情 回复 发表于 2022-3-21 13:39
点赞 关注
个人签名QQ:252669569
 
 

回复
举报

1万

帖子

203

TA的资源

管理员

来自 5楼
 

"万里"树莓派小车汇总贴:

lb8820265的“万里”树莓派小车开源分享 - DIY/开源硬件专区 - 电子工程世界-论坛 (eeworld.com.cn)

 

目录:

 

“万里”树莓派小车开张贴 

1“万里”树莓派小车——建立项目仓库

2“万里”树莓派小车——python学习(Thonny的使用)

3“万里”树莓派小车——python学习(定时任务)

4“万里”树莓派小车——C++学习(编译与运行,geany使用)

5“万里”树莓派小车——wiringPi学习(延时与线程模拟定时器)

6“万里”树莓派小车——wiringPi学习(PWM与外部中断模拟定时器)

7“万里”树莓派小车——RPi.GPIO学习(PWM与外部中断模拟定时器)

8“万里”树莓派小车——socket学习(本机通讯)

9“万里”树莓派小车——socket学习(TCP两机通讯)

10“万里”树莓派小车——socket学习(UDP两机通讯)

11“万里”树莓派小车——socket学习(Android发送)

12“万里”树莓派小车——socket学习(Android收发)

13“万里”树莓派小车——配件准备

14“万里”树莓派小车——电机驱动学习

15“万里”树莓派小车——光电编码器学习(正反转的判断)

16“万里”树莓派小车——光电编码器学习(转速的获取)

17“万里”树莓派小车——VSCode学习(编译和调试)

18“万里”树莓派小车——Makefile学习

19“万里”树莓派小车——VSCode学习(多C文件链接调试)

20“万里”树莓派小车——电机控制学习(控制速度)

21“万里”树莓派小车——电机控制学习(4轮速度控制)
22“万里”树莓派小车——手机遥控电机转动

23“万里”树莓派小车——无屏幕连接树莓派

24“万里”树莓派小车——树莓派64位系统bullseye跑分测试

25“万里”树莓派小车——纳姆轮控制

26“万里”树莓派小车——程序开机启动

27“万里”树莓派小车——固定和获取树莓派IP地址

28“万里”树莓派小车——小车组装

29“万里”树莓派小车——直行偏向问题与新控制模式

30.“万里”树莓派小车——第一阶段完成展示(从零开始介绍)

此帖出自创意市集论坛
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
个人签名玩板看这里:
https://bbs.eeworld.com.cn/elecplay.html
EEWorld测评频道众多好板等你来玩,还可以来频道许愿树许愿说说你想要玩的板子,我们都在努力为大家实现!
 
 
 

回复

7671

帖子

2

TA的资源

五彩晶圆(高级)

沙发
 

Makefile 了解一下就好了,现在纯手写makefile的太少了。还有用cmake的,也是一堆坑,都挺麻烦。还是微软的vs好啊,哈哈。

此帖出自创意市集论坛
个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 
 

回复

1239

帖子

68

TA的资源

纯净的硅(中级)

板凳
 

用cmake方便

此帖出自创意市集论坛
 
 
 

回复

6107

帖子

4

TA的资源

版主

4
 

嗯,必须了解。

此帖出自创意市集论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表