Linux开发(4):使用Make工具编译文件,编写Makefile文件

        在学习开发Linux的过程中,我们时常需要编译繁多的C文件,而仅靠gcc编译器来进行编译,所执行的操作语句繁多,并且每次编译都要重新编译所有相关文件,占用系统内存较大,因此需要使用Make工具来进行批量的编译,类似于在visual studio中点击编译,系统自动将大量文件编译成程序一样。

        本文从以下几点介绍编写Makefile

                1.Make和Makefile的关系

                2.Makefile的基本格式

                3.使用特殊符号改造Makefile

                4.使用函数改造Makefile

        下载Make工具命令:sudo apt install make -y

一、Make和Makefile的关系

        使用Make工具时,在Linux中执行的语句为:sudo make

        语句执行时,make工具会在当前目录下寻找名称为Makefile或者makefile的文件,执行里面的语句去编译相应的文件,文件开头M或m大小写都可以

        如果不想起名为Makefile,使用命令:make -f 你的文件名

二、Makefile的基本格式

基本格式:
        targeta: targetc targetb  # 最终目标A:A的第一个依赖B A的第二个依赖C
                 ls               # 达成A所需要执行的语句/目标要执行的命令

         targetb:                 # 目标B:无依赖
                 touch hello.c    # 达成B执行的语句/目标要执行的命令

         targetc:                 # 目标C:无依赖
                 pwd              # 达成C执行的语句/目标要执行的命令

         clear:                   # 目标clear,用户自定义,可有可无
                 rm -f hello.c    # 达成clear执行的语句/目标要执行的命令

        第一个目标A是最终目标和默认目标,

        Make使用Makefile的过程:首先目的是达成A,为了生成A,需要B和C,达成B和C又分别需要执行相应的命令语句,执行完后最终生成A。

        

三、使用特殊符号$改造Makefile

        假设现在有多个C文件和头文件,分别为helloA.c,helloB.c,helloH.h,两个C文件都包含头文件helloH.h。

        编写Makefile编译

        Hello:helloA.c helloB.c

                        gcc -o Hello helloA.c helloB.c -I.

        clear:

                    rm -f *.o Hello

        # -I表示告诉编译器头文件所在的路径,I后面的.表示当前文件目录

        #-o后面生成的Hello文件名称和目标名称Hello一致,这样make再次执行时,如果Hello依赖的两个文件helloA.c和helloB.c没有修改过,则不会再重新编译生成Hello一遍

        

        

        

        以上的Makefile文件用特殊符号$改造后为

        Hello:helloA.c helloB.c

                        gcc -o $@ $^ -I.

        clear:

                    rm -f *.o Hello

改造后效果不变:

 改造规则:

$@

匹配目标文件

$%

与$@类似,但$%仅匹配“库”类型的目标文件

$<

依赖中的第一个目标文件

$^

所有的依赖目标,如果依赖中有重复的,只保留一份

$+

所有的依赖目标,即使依赖中有重复的也原样保留

$?

所有比目标要新的依赖目标

,四、使用函数改造Makefile

改造函数有以下三个:

notdir函数:去除文件路径中的目录部分

        $(notdir 文件名)

        例子:Build_dir = /home/xyq/linux/hello.c

                   File=$(notdir $(Build_dir))        // $() 表示取变量的值

        结果:File=hello.c

wildcard函数:获取文件列表,将其使用空格分开

        $(wildcard 匹配规则)

        例子:SRC_dir = source  //变量等于目录source

                   SRCS = $(wildcard $(SRC_dir)/*.c)               

        结果:SRCS = 目录source下的所有.c文件

patsubst函数:模式字符串替换

        $(patsubst 匹配规则, 替换规则, 输入的字符串)

        例子: INC_DIR = includes .                //变量等于头文件路径includes和当前路径 “.”                          CFLAGS = $(patsubst %, -I%, $(INC_DIR))

        结果:CFLAGS = INC_DIR包含的两个目录下的所有符合匹配规则“%”的文件,替换成   “-I%”规则的文件。比如includes目录,被替换后为:-Iincludes               

                    结合前面讲的-I表示编译器头文件所在的路径,这里就表示让变量等于头文件所在的路径,方便接下来编译器调用

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值