我的Makefile文件入门

背景:

前端时间搞了个底板,用的是恩智浦的imx8平台,安装了Ubuntu系统,各种驱动安装涉及linux开发,我这方面太弱势,抱大腿学了点皮毛。想写个功能demo,发现Makefile都不会,太悲剧。

用window开发通过ide不需要过多关注底层原理,基本都是ide给你自动生成连接关系。这次我得打破舒适区,拿下Makefile就从这次做起。

基础知识:

GCC(GNU Compiler Collection,GNU编译器套件),是由GNU开发的编程语言编译器。它是以GPL许可证所发行的自由软件,也是 GNU计划的关键部分。我在linux下用的make命令就是去执行了gcc编译编译命令(unix下是cc,当然你也可以是其他编译器的),当你输入make指令的时候,它会自动查找当前目录下的Makefile或者makefile(注意大小写,首字母大小写都可以),然后执行里面的内容。其实本质上Makefile就是个脚本,通过make命令来运行它。但是这个脚本真的很关键呀,兄弟们儿!它能告诉系统我这个文件依赖哪些文件,我要输出的名字是什么,头文件去哪里找,有没有指定的库,甚至于如何克服不同路径带来的安装问题等等。我目前也就学了7788,也不敢乱说,不过就我现在的理解,它真的很强大,我后悔没有早点搞明白这个东西,导致自己对底层的编译过程一头雾水。

学习过程:

我的学习过程很简单,去网上找教程发现大多数都罗七八嗦的,太费时间了,我需要快速上手,所以就大概看了一下(5分钟),然后就找了个阿里的sdk,看其中的Makefile文件,把这个Makefile文件看懂了,我至少能把用法学个大概,可以解决我现在的困难(自己写工程的Makefile)。废话不多说,下面是我今天整理出来的Makefile文件加备注版本,一个字一个字抠出来的,有问题可以留言,咱们可以交流,向大家学习。

Q := @    #此种形式都是定义,给变量赋值,后面的值赋给前面的

TOP_DIR := $(shell pwd)  #pwd获取当前目录,然后赋值
DEMOS_DIR := demos
OUT_DIR := output

CC := gcc  #定义编译器,GCC(GNU Compiler Collection,GNU编译器套件),是由GNU开发的编程语言编译器。它是以GPL许可证所发行的自由软件,也是 GNU计划的关键部分。

BLD_LDFLAGS := $(LDFLAGS) -lpthread    
#LDFLAGS可以用来link动态库或者静态库的,用在gcc选项上,后面可以加-L指定库目录,加-l指定库名称,这里的-lpthread,告诉编译器去连接libpthread.so动态库,如果gcc选项里指定了-static,则代表连接静态库。

SRC_DIR := $(shell find . -type d \( ! -name demos \)) #这里的d类型是目录(directory),但是删去了demos这个目录

HDR_DIR := $(SRC_DIR)
BLD_CFLAGS += $(addprefix -I,$(HDR_DIR))#这里给HDR_DIR加了一个-I前缀,然后再添加到BLD_LDFLAGS的后面,用在gcc选项上,作用是指定头文件目录

SRC_FILES := $(shell find $(SRC_DIR) -not -path "*/demos/*.c" -name "*.c")#这里是按照SRC_DIR中的路径去搜索名字中带.c的文件,但是要去掉SRC_DIR中带*/demos/*.c条目
OBJ_FILES := $(SRC_FILES:.c=.o)#把SRC_FILES中的.c换成.o,然后赋值给OBJ_FILES
OBJ_FILES := $(addprefix $(OUT_DIR)/,$(OBJ_FILES))#在OBJ_FILES中加output/前缀

PROG_TARGET := $(subst _,-,$(patsubst %.c,%,$(wildcard demos/*_demo.c)))#wildcard以demos/*_demo.c为模板输出,*代表任意,patsubst是筛选替换,把第一次的输出中包含.c结尾的去掉.c,subst是替换,把第二次输出条目中的_替换为-

all: prepare $(PROG_TARGET)#all是目标,它依赖于:后面的两个项目,这两个项目在下面都做了定义

prepare:
	$(Q)mkdir -p output  #prepare没有依赖,它的内容是依次创建output目录

$(PROG_TARGET): $(OBJ_FILES)  #PROG_TARGET的依赖是OBJ_FILES,上文都有定义
	$(Q)echo "+ Linking $(OUT_DIR)/$(notdir $@) ..."
#echo是打印输出提示信息或者结果,这里输出编译最终的文件,其中$@代表目标(aim),也就是PROG_TARGET
	$(Q)mkdir -p $(dir $@)
#这里是创建路径,也就是demos
	$(Q)$(CC) -o $@ \   #编译命令,后面是编译参数,-o代表指定输出的名字,名字包括$@和后面的patsubst生成的.o文件
	    $(patsubst $(OUT_DIR)/%,%,$(addsuffix .c,$(subst $(notdir $@),$(subst -,_,$(notdir $@)),$@))) \
#上面这句中addsuffix第二个参数其实就把-换回了_,addsuffix加了.c的尾缀,patsubst是去掉(OUT_DIR)/
	    $(BLD_CFLAGS) $^ $(BLD_LDFLAGS)
#上面这句加了头文件,依赖,最后还添加了链接库
	$(Q)mv $@ $(OUT_DIR)
#上面这句是移动输出文件到output文件夹里

#下面的这个定义并没有执行,因为Makefile文件中多个gcc命令的时候,只执行第一个。
$(OUT_DIR)/%.o: %.c
	$(Q)echo ": Compiling $< ..."
	$(Q)mkdir -p $(OUT_DIR)/$(dir $<)
	$(Q)$(CC) -o $@ -c $< $(BLD_CFLAGS)

#下面的clean可以通过make clean执行,清理生成的文件
clean:
	$(Q)rm -rf $(OUT_DIR)

为了看懂上面的Makefile,我看了好多博客,有几个比较详细推荐的,可以给大家参考一下:

linux编程入门(六)-编写Makefile文件 :https://www.jianshu.com/p/442e71755643

Makefile选项CFLAGS,LDFLAGS,LIBS:https://www.cnblogs.com/fire909090/p/11160219.html

一文入门makefile:https://zhuanlan.zhihu.com/p/56489231

以上,等等,感谢网友们的无私奉献!

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Makefile是一种用来构建和管理程序的工具,它通过一个文本文件来指导编译器如何去编译、链接程序。理解并掌握Makefile的使用可以提高程序的编译效率和可维护性。下面是关于Makefile入门到精通的解释: 入门阶段: 在初学者阶段,需要掌握Makefile的基本语法和规则。学习如何编写一个简单的Makefile,并且能够使用Makefile来管理和编译一个简单的程序。掌握Makefile的目标、依赖关系、命令和变量的使用。 进阶阶段: 在进阶阶段,需要了解更多的Makefile的高级特性和技巧。学习如何使用条件语句、循环语句和函数来编写更灵活和复杂的Makefile。了解如何使用Makefile来管理多个源文件和目录结构。 精通阶段: 在精通阶段,需要深入理解Makefile背后的原理和机制。了解Makefile的工作原理,包括依赖关系的自动推导、文件更新的判断和并行编译等。还需要掌握一些高级的技巧,例如使用Makefile来实现代码自动生成、跨平台编译和项目的自动化构建等。 实践阶段: 在实践阶段,需要应用所学的知识来解决实际的编译和构建问题。学会分析和优化Makefile,以提高构建过程的效率和可维护性。实践中可能还需要了解如何与其他构建工具和版本控制系统进行集成,以及如何处理复杂的项目依赖关系。 总之,掌握Makefile需要从入门到精通经过一定的学习和实践过程。通过不断的学习和实践,逐渐提高对Makefile的理解和应用能力,才能真正驾驭Makefile并充分发挥其作用。 ### 回答2: Makefile是一种用于自动化编译和构建软件的脚本文件。它是基于依赖关系的构建工具,通过定义文件依赖关系和编译规则,可以自动检测源代码的变化并重新编译相关文件,从而提高软件开发的效率。 要学习Makefile,首先需要了解Makefile的基本语法和规则。Makefile由多个规则组成,每个规则包含目标文件、依赖文件和命令。目标文件是生成的文件,依赖文件是生成目标文件所需的源文件或其他目标文件,命令是生成目标文件的具体步骤。 在Makefile中,可以定义变量来存储常用的路径或编译选项,这样可以方便地在多个规则中复用。还可以使用条件判断、循环和函数等高级语法来实现更复杂的功能。 经常使用的命令有make、make clean和make install。make命令用于编译源代码并生成目标文件,如果源文件有更新,make会自动重新编译相关文件。make clean命令用于清理生成的目标文件和临时文件,make install命令用于安装生成的可执行文件或库文件到指定位置。 学习Makefile还需要掌握一些常用的编译规则和选项。例如,可以通过定义编译规则来指定编译器、编译选项和链接选项。可以使用特殊变量$@表示目标文件,$^表示所有的依赖文件,$<表示第一个依赖文件。还可以使用通配符和模式匹配来处理多个文件或目录。 除了基本的语法和规则,还可以学习一些高级的技巧和技术,例如使用配置文件、自动化测试、并行编译等。通过不断实践和积累经验,可以逐渐提高对Makefile的掌握程度,从入门到精通。 总结来说,要从入门到精通Makefile,需要掌握基本的语法和规则,学习常用的命令和选项,并通过实际项目的练习来加深理解和提高技能水平。 ### 回答3: makefile是一种用于自动化构建和管理项目的工具。它可以根据一组规则,自动推断出需要重新编译的文件,并且根据这些规则自动执行相应的指令,从而简化了项目的构建流程和维护工作。 首先,我们需要了解makefile的基本语法和组成部分。makefile由一系列规则组成,每个规则包含一个目标、依赖关系和执行的指令。目标是需要生成的文件,依赖关系是该文件生成所依赖的文件,指令则是实际执行的操作。 其次,学习makefile中的变量。变量可以用于存储常用的路径、命令等信息。使用变量可以简化项目配置和维护,提高可维护性。 然后,理解makefile中的模式规则。模式规则是一种通用的规则,可以根据目标和依赖的模式,推断出需要执行的指令。使用模式规则可以减少重复的规则定义,提高makefile的灵活性。 接下来,学习条件判断和循环控制。条件判断可以根据不同的情况选择执行不同的指令,循环控制可以重复执行某些指令。这些功能可以使makefile更加灵活和自动化。 最后,掌握makefile中的常用函数和命令。makefile提供了一系列内置函数和命令,用于处理文本、路径、文件等操作。熟练掌握这些函数和命令,可以提高makefile的处理能力和效率。 总结而言,要精通makefile需要掌握其基本语法、规则定义、变量使用、模式规则、条件判断、循环控制、内置函数和命令等知识。通过实践和不断学习,掌握这些内容后,就可以灵活运用makefile来构建和管理项目,提高开发效率和代码质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值