一个通用的Makefile

一个比较通用的makefile CXX = g++ LIB = -L/data/protobuf/2.5.0_x64/lib/ INC = -I/data/protobuf/2.5.0_x64/include/ -I./ CXXFLAGS = -DSNACC_DEEP_COPY -DHAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS -Wno-deprecated -fPIC TARGET=main SRC=$(wildcard ./*.cpp) OBJ=$(patsubst %.cpp, %.o, $ 阅读详情

一、makefile的作用

Makefile是用于自动编译和链接的,一个工程有很多文件组成,每一个文件的改变都会导致工程的重新链接,但是不是所有的文件都需要重新编译,Makefile中记录有文件的信息,在make时会决定在链接的时候需要重新编译哪些文件。Makefile的宗旨就是:让编译器知道要编译一个文件需要依赖其他的哪些文件。当那些依赖文件有了改变,编译器会自动发现最终的生成文件已经过时,而应该重新编译相应的模块。 makefile带来的好处就是—“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。默认的情况下,make命令会在当前目录下按顺序找寻文件名为"GNUmakefile"、“makefile”、"Makefile"的文件,找到了解释这个文件。当然也可以使用make -f DIR/makefile 来指定用于makefile文件。

二、makefile语法简述

2.1 makefile规则

target ... : dependencies ... 
            command

target目标文件,可以是Object File,也可以是执行文件,还可以是一个标签 。
dependencies就是,要生成那个target所需要的文件或是目标。
command也就是make需要执行的命令。(任意的Shell命令,可以有若干行)。

这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于dependencies中的文件,其生成规则定义在command中。dependencies 中如果有一个以上的文件时间要比target文件要新的话,command所定义的命令就会被执行。这就是 Makefile的规则。也就是Makefile中最核心的内容。在Makefile中的命令,必须要以[Tab]键开始。

2.2 变量定义

Makefile中变量的定义一般有两种: =和:=。 =符号定义的变量叫延时变量,只有在使用的时候才扩展开来; :=符号定义的变量为立即变量,一旦定义就扩展。 使用=定义的变量不能追加新值,使用:=定义的变量可以使用+=追加新值

2.3 文件指示

在Makefile使用include关键字可以把别的Makefile包含进来,这很像C语言的#include,被包含的文件会原模原样的放在当前文件的包含位置。include的语法是:include<filename>  filename可以是当前操作系统Shell的文件模式(可以保含路径和通配符)

2.4 伪目标

伪目标并不是一个文件,只是一个标签,由于伪目标不是文件,所以make无法生成它的依赖关系和决定 它是否要执行。我们只有通过显示地指明这个目标才能让其生效。当然,伪目标的取名不能和文件名重名,不然其就失去了伪目标的意义了。当然,为了避免和文件重名的这种情况,我们可以使用一个特殊的标记.PHONY来显示地指明一个目标是伪目标,向make说明,不管是否有这个文件,这个目标就是伪目标。

2.5 自动化变量

$<    第一个依赖文件的名称
$?    所有的依赖文件,以空格分开,这些依赖文件的修改日期比目标的创建日期晚
$@    目标的完整名称
$^    所有的依赖文件,以空格分开,不包含重复的依赖文件

三、通用的makefile实例

工程必备:

  • 顶层Makefile
  • 顶层Makefile.build
  • 子目录Makefile

编译过程:

从顶层开始递归进入子目录,当进入到一个目录的最底层时,开始使用GCC编译,再将该层的所有.o文件打包成build-in.o,返回它的上一层目录再递归进入子目录,当编译完所有的子目录后,就开始编译顶层的.c文件,最后将顶层的.o文件和顶层每个子目录的build-in.o链接成我们的目标文件

顶层Makefile解析(随工程而变):

#-------------------------指定编译工具链-------------------------
CROSS_COMPILE =                         #指定编译器种类

AS        = $(CROSS_COMPILE)as          
LD        = $(CROSS_COMPILE)ld          #链接工具
CC        = $(CROSS_COMPILE)gcc         #编译工具
CPP       = $(CC) -E                    
AR        = $(CROSS_COMPILE)ar          #打包工具
NM        = $(CROSS_COMPILE)nm          

STRIP     = $(CROSS_COMPILE)strip    	#优化工具
OBJCOPY   = $(CROSS_COMPILE)objcopy  	
OBJDUMP   = $(CROSS_COMPILE)objdump  	

export AS LD CC CPP AR NM               #将定义的变量导出,方便其他makefile使用
export STRIP OBJCOPY OBJDUMP            #将定义的变量导出,方便其他makefile使用

CFLAGS := -Wall -O2 -g                  #编译器参数
CFLAGS += -I $(shell pwd)/include       #指定编译器头文件(根据实际项目手动修改)
LDFLAGS := -lm -lfreetype -lvga         #指定编译器链接库(根据实际项目手动修改)
export CFLAGS LDFLAGS                   #将定义的变量导出,方便其他makefile使用
TOPDIR := $(shell pwd)                  #获得当前程序的顶层目录

export TOPDIR                           #输出顶层目录
TARGET := show_file                     #编译后的程序名(根据实际项目手动修改)

#--------------顶层要生成的.o文件以及顶层文件夹(根据实际项目手动修改)--------------
obj-y += main.o
obj-y += display/
obj-y += draw/
obj-y += encoding/
obj-y += fonts/

#----------------------------顶层的第一个规则(默认规则)--------------------------
all :
    make -C ./ -f $(TOPDIR)/Makefile.build      #进入当前目录,使用顶层的makefile.build进行编译
    $(CC) $(LDFLAGS) -o $(TARGET) built-in.o    #将编译好的built-in.o文件链接生成我们的目标文件

#---------------------------------顶层的清除规则-------------------------------
clean:
    rm -f $(shell find -name "*.o")       #删除所有的.o文件
	rm -f $(shell find -name "*.d")       #删除所有的.d文件
    rm -f $(TARGET)                       #删除目标文件
.PHONY:all clean

顶层Makefile.build解析(无需改动):

PHONY := __build        #定义一个PHONY变量
__build:                #开头说明__build伪目标,使其成为Makefile.build的第一个目标
obj-y :=                #定义当前目录的目标变量,初始值为空
subdir-y :=             #定义当前目录的子目录变量,初始值为空
include Makefile        #将当前目录的Makefile包含进来,初始化obj-y
                        #obj-y:=a.o b.o c/ d/
__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))    #筛选出当前目录的目标变量中的子目录,并且去掉/
							 						  	 #$(filter %/, $(obj-y)):c/ d/
							 							 #__subdir-y:c d
subdir-y += $(__subdir-y)				 				 #将开始定义的subdir-y赋值为__subdir-y
							 							 #subdir-y:c d
subdir_objs := $(foreach f,$(subdir-y),$(f)/built-in.o)  #对于subdir-y里面的每一个值(目录),增加一个相应的目录/built-in.o的变量值
							 							 #subdir_objs:c/built-in.o d/built-in.o
cur_objs := $(filter-out %/, $(obj-y))     		 		 #得到obj-y中的.o文件
							 							 #cur_objs:a.o b.o
dep_files := $(foreach f,$(cur_objs),.$(f).d)     		 #对于所有的.o文件,定义它的依赖文件名
							 							 #dep_files: .a.d .b.d
dep_files := $(wildcard $(dep_files))

ifneq ($(dep_files),)          #根据依赖文件名,判断依赖文件是否存在,存在就包含就来
    include $(dep_files)
endif

PHONY += $(subdir-y) 		   #将$(subdir-y)也加入到变量PHONY中

#------------------------Makefile. build的第一个规则-------------------------
__build : $(subdir-y) built-in.o			#第一个规则
$(subdir-y):                                #第一个规则的第一个依赖规则
    make -C $@ -f $(TOPDIR)/Makefile.build  #依次进入该子目录变量里面存储的值,使用的Makefile.build进行编译
built-in.o : $(cur_objs) $(subdir_objs)     #第一个规则的第二个依赖规则
      $(LD) -r -o $@ $^                     #该规则的命令:将该目录下的.o和$(subdir_obj)打包成built-in.o文件
dep_file = .$@.d                            
%.o : %.c                                   	 #第一个规则的第二个依赖规则的依赖规则 
$(CC) $(CFLAGS) -Wp,-MD,$(dep_file) -c -o $@ $<  #用于将目录下所有的.c文件编译成.o文件
.PHONY : $(PHONY)                           	 #将PHONY声明为伪目标

子目录Makefile(随工程而变):

子目录的Makefile就是包含该目录下所有的目标文件名和子目录文件夹名。

例如任何一个子目录可写成:

objs-y := a.o
objs-y += b.o
objs-y += c/
objs-y += d/

转载地址: http://www.cnblogs.com/lidabo/p/4521123.html

PCL 计算点云法向量并显示【2026最新版】 PCL计算法向量并显示,用OMP进行计算加速以及法线定向的深层次理解、操作。博客长期更新,本文最近更新时间为:2026年1月28日。 阅读详情

相关推荐

FreeRtos——10、全局看门狗设计

RTOS 里的看门狗不只是为了证明 CPU 还在动,而是为了证明每个业务逻辑都在按预期的节奏“呼吸”。

qq_40170041的博客 901

通用makefile

文章目录1 最基本的makefile1.1 简单粗暴的makefile1.2 稍微提高效率的makefile1.3 更加精炼的makefile1.4 需要手工添加头文件规则的makefile1.5 支持自动检测头文件的makefile1.6 支持自动获取目标文件的makefile 1 最基本的makefile 有main.c、sub.c、sub.h三个文件,文件内容如下: main.c: #inc...

木子皿--啥都不会的菜鸟 1340

FineReport SQL查询分页

打开模板>模板web属性>分页预览设置,选择为该模板单独设置,将默认的工具栏按钮全部清除掉,然后依次添加两个自定义按钮,一个邮件按钮,两个自定义按钮,一个Word格式,一个PDF按钮。如下所示:注:使用具体格式按钮,如邮件、Word格式、PDF按钮是为了JS直接使用控件名称获取空间方便修改其内容;

lep的博客 2428

一个通用的Makefile写法

makefile的一种写法

远方客的专栏 722

OCR开发实战:如何用PaddleOCR C++版实现本地文字识别(附模型文件处理技巧)

本文详细介绍了如何使用PaddleOCR C++版实现本地文字识别,包括环境搭建、工程编译、运行时优化等全流程。重点讲解了在VS2019/VS2022环境下配置PaddleOCR的CPU推理性能优化技巧,以及模型文件处理的实际应用方法,帮助开发者高效完成OCR本地化部署。

devops8pract的博客 335

论文理解【LLM-OR】——【OptMATH】A Scalable Bidirectional Data Synthesis Framework for Optimization Modeling

本文提出 LLM-OR 领域的双向数据合成框架 OptMATH,从已有 MF/PD 出发反向生成 NL,再使用 AutoFormulator 进行正向建模,通过最优值匹配 rejection sampling 确保语义一致性。实现了难度可控的语义一致数据合成

佚失的诗篇 499

makefile的作用是什么?

作用:管理工程文件,通过makefile的编写,对工程下不同目录中的文件的编译、链接的方式、顺序进行描述。 在编写makefile后,编译工程只要求输入make命令,极大的提高了编译效率。

ZWHCYY001的博客 3451

LIGGGHTS开源离散元仿真:从基础安装到高级应用实战

本文详细介绍了LIGGGHTS开源离散元仿真软件的基础安装、脚本编写及高级应用实战。从颗粒自由落体模拟到工业级复杂系统建模,涵盖CFD-DEM耦合、高性能计算优化等关键技术,帮助用户快速掌握这一强大的颗粒仿真工具。特别适合需要处理颗粒系统仿真的科研人员和工程师。

l1k9j8h7g6的博客 620

跟我一起写 Makefile(三)

Makefile 总述———————一、Makefile里有什么?Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。1、显式规则。显式规则说明了,如何生成一个或多的的目标文件。这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。2、隐晦规则。由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书

陈皓专栏 【空谷幽兰,心如皓月】 10万+

嵌入式系统开发笔记101:STM32CubeIDE安装过程中的2个错误及其解决方法

STM32CubeIDE在安装过程中,遇到了2个错误,本文阐述其解决方法。产生上述错误的原因,都在于中文。STM32CubeIDE不能很好的支持中文,所以在使用STM32CubeIDE进行项目设计的过程中,不要使用中文,包括项目所在的路径。

snmplink的博客 8557

12、无人机系统的建模与仿真

本文深入探讨了无人机系统的建模与仿真技术,涵盖其发展需求、历史演变、动力学建模方法、常用参考框架与状态变量表示,并分析了在控制系统设计、操作员培训和子系统测试中的关键应用。文章还介绍了不同类型无人机(固定翼、旋翼、混合翼)在建模与仿真中的差异,提出了多学科融合、高精度实时仿真及VR/AR技术等未来发展趋势,并给出了实际建模与仿真的标准操作流程,为无人机系统的设计与优化提供了全面的技术支持与展望。

websocket5live的博客 196

关于 Makefile, 该知道这些

一 Makefile 的用途 (1)可用做于管理工程文件的工具 (2)make 是解释Makefile的解释命令工具 (3)可以提高工作效率,减少出错的几率。 二 基本规则 2.1 目标:依赖 (tab)命令 目标 --> 要生成的目标文件。(关于伪目标,请看最后补充说明。) 依赖 --> 生成目标文件需要的一些文件。 命令 --> 借助依赖文件生成目标文件的手段。忽略错误命令继续执行,不显示执行时候的命令细节。tab --> 缩进,有且只有...

那么菜的博客 2165

YOLO26涨点改进 | 小目标损失函数独家改进篇 | TGRS 2025 | 引入AdaFocalLoss损失函数,改进小目标检测,自适应聚焦小目标与样本分布不平衡,提升检测精度与训练稳定性

本文提出将AdaFocalLoss损失函数应用于YOLO26模型优化,有效提升小目标检测性能。AdaFocalLoss通过目标尺寸感知机制和IoU引导的动态调节,自动调整训练权重和聚焦程度,解决了样本不平衡问题。相比传统损失函数,它无需手动调参,能增强训练稳定性,在多尺度、复杂场景下表现优异。文章详细介绍了AdaFocalLoss的原理、优势及实现方法,并提供了代码集成指南。实验表明该方法能显著提升检测精度和鲁棒性,特别适用于小目标检测任务。

Ai缝合怪、助力小伙伴高效发论文 337

一个通用的makefile文件应该怎么写

目标文件名为demo#没有去掉符号表和调试信息的目标文件版本#map文件包含目标文件链接阶段的细节内容,通常包含全局符号,交叉引用和内存映射等信息#交叉编译工具链#C语言编译工具gcc#C++编译工具g++#GNU中用来将目标文件打包为静态链接库的工具#GNU链接器,用来将目标文件与库链接为可执行文件#GNU中的用来裁剪调试信息与符号表的工具#GNU中AR的子工具,用来为归档文件创建符号表索引,符号表文件可以让链#接器快速查找函数符号在相应对应文件的位置。

qq_40854508的博客 1161

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

一个通用的makefile

我们在Linux环境下开发程序,少不了要自己编写Makefile,一个稍微大一些的工程下面都会包含很多.c的源文 件。 如果我们用gcc去一个一个编译每一个源文件的话,效率会低很多,但是如果我们可以写一个Makefile,那么只需要执行一个make就OK了,这 样大大提高了开发效率。 但是Makefile的语法规则众多,而且缺乏参考资料,对于初学者来说,写起来还是有一定的难度,往往令很多人

kesaihao862的专栏 914

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

一个通用Makefile

############################################################### # # # 通用Makefile # # 需要定义好程序文件、目标文件、编译选项 # # ############################################################### # i586-mingw32msvc-gcc ...

爱自在的专栏 193

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

一个通用makefile的编写

linux编译多个源文件的程序比较麻烦,这下就需要通用的Makefile了,编译的时候执行一下make命令就OK,下面介绍通用makfile的写法。 假设现在有以下源文件:file1.h file1.c file2.h file2.c mainproc.c,程序的主函数在mainproc.c中。 #######通用Makefile模板######## # 目标文件名字 TARGET = Mypro

gl23838的专栏 563

一个跨平台通用的Makefile文件

这是一个跨平台的Makefile项目,支持C/C++混合编译、动态/静态库生成、交叉编译等功能。项目特点包括:单一Makefile文件实现简洁管理;支持Linux/Windows平台(Windows需Busybox);提供丰富的配置选项,如编译类型(Release/Debug)、目标文件位置等;内置错误检查和学习文档。通过脚本可灵活配置参数,适合企业开发和学习Makefile使用。项目开源,遵循MIT许可证。

qq_31340093的博客 1123

一个通用makefile文件

有没有一个比较通用的makefile呢? 写在前面: 这个通用mkaefile文档,来源于正电原子学习板中提到的一种,当然这不代表这个就是最合适的,这只是我在学习过程中遇到的文档中,觉得最厉害的一个。 重点还是以学习为主,学学一般的makefile文件是怎么写的,以及makefile的基础知识。 上代码:(上接我写那个bsp推文) 项目源:Linux驱动开发: Makefile+driver可直接下载其中的5_ledc_bsp,都是整理好的。 CROSS_COMPILE ?= arm-l.

小胡同学的工程师学习之路 390

一个通用Makefile模板

最近学习Makefile,写了一个C++编译的通用Makefile模板 它能做什么: 1. 能编译出应用程序,静态库,动态库 2. 可以用在任意目录结构的工程 3. 可以指定多个源文件后缀 4. 可以指定源文件的排除目录和排除文件列表 5. 已经充分考虑了源文件与头文件的依赖关系 6. 使用简单,只需要修改USER-DEFINED SECTION中的几个参数 执行流程:

2042

一个比较通用的Makefile

一个比较通用的Makefile TARGET = xxxSRCDIRS = .SRCEXTS := .c .cppSRC = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(SRCEXTS))))OBJ = $(foreach x,$(SRCEXTS), $(patsubst %$(x),%.o,$(filter %$...

afdd28617的博客 122

一个较通用的makefile

########################################################## #This is a common makefile templet #By WSL 2018-07-26 ########################################################## CROSS = CC = $(CROSS) gcc ...

Lasuerte的博客 402
上一篇: 嵌入式Linux--解决编译buildroot出错
下一篇: bmp文件头信息
奔向星辰花海
博客等级 码龄10年 113粉丝 58原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值