Makefile实战论(一)

简介: Makefile实战论(一)

为什么写这个呢,其实我有系统学过Makefile和CMake。但是因为用的不是很多或者说没有深入的使用场景,导致我不是很熟练,或者说没法优雅地使用。刚好最近对Linux的嵌入式编程比较感兴趣,借着demo来分析一下资深工程师写的Makefile,学习一下。由易到难吧,先来第一个,是一个GPIO的Makefile。

Makefile文件

BIN = test_gpio  
CC = $(CROSS)gcc  
CPP = $(CROSS)g++  
LD = $(CROSS)ld  
#
INCS = 
LIBS =  
SUBDIRS =  
#
DEFINC = -I ./ \
  
# LIBVAR =-shared -fPIE -L.
#
INCS += $(DEFINC)  
LIBS +=$(LIBVAR)
#  
CSRCS = $(wildcard *.c)  
CPPSRCS = $(wildcard *.cpp)  
#  
COBJS := $(CSRCS:.c=.o)  
CPPOBJS := $(CPPSRCS:.cpp=.o)  
#  
CFLAGS += $(INCS)  
CFLAGS += -O2 -Wall -g -fPIE
CPPFLAGS += $(INCS)  
CPPFLAGS += -O2 -Wall -g -fPIE
LDFLAGS += -lm -lrt -lstdc++ -ldl
all:$(BIN)  
$(COBJS) : %.o: %.c  
  $(CC) $(CFLAGS) -c $< -o $@   
$(CPPOBJS) : %.o: %.cpp  
  $(CPP) $(CPPFLAGS) -c $< -o $@ 
  
$(BIN) : $(COBJS) $(CPPOBJS)  
  $(CC) -o $(BIN)    $(COBJS) $(CPPOBJS) $(LDFLAGS) $(LIBS)    
  rm -rf $(COBJS)  
  rm -rf $(CPPOBJS)  
.PHONY:clean cleanall  
   
clean:              
  rm  -rf $(BIN) $(COBJS) $(CPPOBJS)  
#rm *.d  
cleanall:  
  rm $(BIN) $(COBJS) $(CPPOBJS)

拆解分析

BIN = gpio_red_blink
CC = $(CROSS)gcc
CPP = $(CROSS)g++
LD = $(CROSS)ld
  • 定义了变量BIN,表示生成可执行文件名为gpio_red_blink
  • 定义变量CC,表示使用的C编译器为$(CROSS)gcc(其中$(CROSS)是一个可能存在的前缀
  • 定义变量CPP,表示使用的C++编译器为$(CROSS)g++
  • 定义变量LD,表示使用的链接器为$(CROSS)ld
INCS =
LIBS =
SUBDIRS =
  • 定义空变量INCE,LIBS,SUBDIRS
DEFINC = -I ./ \
  • 定义变量DEFINC,指定编译过程中需要包含的头文件路径。这里设置为当前路径
INCS += $(DEFINC)
LIBS +=$(LIBVAR)
  • 将DEFINC添加到INCS中
  • 将未定义变量LIBVAR添加到LIBS中
CSRCS = $(wildcard *.c)
CPPSRCS = $(wildcard *.cpp)
  • 使用通配符,将当前目录所有.c文件加入到CSRCS变量中
  • 使用通配符,将当前目录所有.cpp文件加入到CSRCS变量中
COBJS := $(CSRCS:.c=.o)
CPPOBJS := $(CPPSRCS:.cpp=.o)
  • 将CSRCS中所有.c文件扩展名替换为.o,并且赋值给COBJS
  • 将CPPSRCS中所有,cpp文件扩展名替换为.o,并且赋值给CPPOBJS
CFLAGS += $(INCS)
CFLAGS += -O2 -Wall -g -fPIE
CPPFLAGS += $(INCS)
CPPFLAGS += -O2 -Wall -g -fPIE
LDFLAGS += -lm -lrt -lstdc++ -ldl -lpthread
  • 将INCS分别添加到CFLAGS和CPPFLAGS,指定了编译包含头文件路径
  • 将-O2 -Wall -g -fPIE添加到CFLAGS和CPPFLAGS,表示编译选项
  • 将-lm -lrt -lstdc++ -ldl -lpthread,添加到LDFLAGS中,表示链接选项
all:$(BIN)
  • 定义了一个目标叫做all
  • 依赖于可执行文件$(BIN)
$(COBJS) : %.o: %.c
  $(CC) $(CFLAGS) -c $< -o $@
  • 定义了一个规则模式,将.c文件编译为.o文件
  • %表示通配符,任意字符
  • $<表示第一个依赖的文件,即.c文件
  • $@表示目标文件,即.o文件
$(CPPOBJS) : %.o: %.cpp
  $(CPP) $(CPPFLAGS) -c $< -o $@
  • 定义了一个规则模式,将.cpp文件编译为.o文件
$(BIN) : $(COBJS) $(CPPOBJS)
  $(CC) -o $(BIN)    $(COBJS) $(CPPOBJS) $(LDFLAGS) $(LIBS)
  rm -rf $(COBJS)
  rm -rf $(CPPOBJS)
  • 定义一个规则模式,用于链接目标文件生成可执行文件$(BIN)
  • $(BIN)依赖$(COBJS) $(CPPOBJS)
  • 链接完成后删除中间文件
.PHONY:clean cleanall
clean:
  rm  -rf $(BIN) $(COBJS) $(CPPOBJS)
cleanall:
  rm $(BIN) $(COBJS) $(CPPOBJS)
  • 定义两个伪目标(.PHONY),用于执行清理操作
相关文章
|
存储 缓存 监控
安谋科技(Arm China)马闯:Arm架构下性能分析与优化介绍
2023年9月19日,系列课程第九节《Arm®架构下性能分析与优化介绍》正式上线,由安谋科技 (Arm China)主任工程师马闯主讲,内容涵盖:Arm架构下性能监控单元 (PMU) 介绍、Arm统计性能分析扩展 (SPE) 介绍、Arm性能分析工具介绍、Arm架构下性能优化案例分享,本期节目在阿里云官网、阿里云微信视频号、阿里云钉钉视频号、InfoQ官网、阿里云开发者微信视频号、阿里云创新中心直播平台 & 微信视频号同步播出,同时可以点击【https://developer.aliyun.com/topic/ecs-yitian】进入【倚天实例迁移课程官网】了解更多内容。
|
传感器 网络协议 物联网
Linux MQTT通信:实现轻量级物联网传输协议
MQTT(Message Queuing Telemetry Transport)是一种轻量级的物联网传输协议,专门设计用于低带宽、不稳定网络环境下的传感器和物联网设备通信。本文将深入探讨Linux环境下如何实现MQTT通信,介绍MQTT协议的基本原理、常用MQTT库以及如何在Linux系统中编写MQTT客户端和服务器端程序。
2077 0
|
Oracle Ubuntu Java
Ubuntu安装JDK
一. Ubuntu 安装JDK的两种方式 1. 通过apt安装. 2. 通过官网下载安装包安装. 这里推荐第1种,因为可以通过 apt-get upgrade 方式方便获得jdk的升级 二. 通过apt安装(jdk有很多版本, 这里介绍两种: openjdk和oracle的JDK) 1.
72049 4
|
7月前
|
API Python
利用openvino模型推理图片
本文介绍了如何使用 OpenVINO 格式模型文件对图片进行推理。通过将训练好的模型转换为 OpenVINO 格式,可实现跨设备部署。文中详细展示了利用 Python 和 OpenVINO API 完成模型加载、编译及推理的步骤。核心代码包括初始化 OpenVINO 模型、设置预测参数(如置信度和 IoU 阈值)以及对图片进行检测并显示结果。注意:OpenVINO 模型文件需完整存放于同一目录下,路径需正确配置,参数可根据模型性能调整。
|
Java 应用服务中间件 Shell
Nginx+Keepalived+Tomcat 实现Web高可用集群
Nginx+Keepalived+Tomcat 实现Web高可用集群
379 0
|
数据采集 JSON 开发者
Python爬虫京东商品详情数据接口
京东商品详情数据接口(JD.item_get)提供商品标题、价格、品牌、规格、图片等详细信息,适用于电商数据分析、竞品分析等。开发者需先注册账号、创建应用并申请接口权限,使用时需遵循相关规则,注意数据更新频率和错误处理。示例代码展示了如何通过 Python 调用此接口并处理返回的 JSON 数据。
|
12月前
|
消息中间件 存储 JSON
Net使用EasyNetQ简化与RabbitMQ的交互
EasyNetQ是专为.NET环境设计的RabbitMQ客户端API,简化了与RabbitMQ的交互过程。通过NuGet安装EasyNetQ,可轻松实现消息的发布与订阅,支持多种消息模式及高级特性。文中提供了详细的安装步骤、代码示例及基础知识介绍,帮助开发者快速上手。关注公众号“Net分享”获取更多技术文章。
334 1
Net使用EasyNetQ简化与RabbitMQ的交互
|
SQL 运维 前端开发
一款现代化、高颜值的一站式智能运维管理平台
orion-ops-pro —— 一款现代化、高颜值的一站式智能运维管理平台,集资产管理、资产授权、批量执行、计划任务、WebShell、WebSftp、角色管理、系统管理等功能于一体,致力于简化运维团队的治理工作。
270 1
一款现代化、高颜值的一站式智能运维管理平台
|
前端开发
前端开发之Element Plus的分页组件el-pagination显示英文转变为中文
前端开发之Element Plus的分页组件el-pagination显示英文转变为中文
268 0
前端开发之Element Plus的分页组件el-pagination显示英文转变为中文