首页 > 其他分享 >15-makefile

15-makefile

时间:2024-12-25 22:30:54浏览次数:6  
标签:15 CC make makefile 编译 fun main

一、Makefile的概述

1.认识make

  1. make 是一个命令,是个可执行程序,用来解析 Makefile 文件的命令;
  2. linux 环境下,这个命令存放在 /usr/bin/ 目录下;
  3. 当用户输入 make 指令时,系统会自动寻找 makefile、Makefile、GNUmakefile 中任何一个,根据该文件中的指令编译工程。

2.什么是makefile

  1. makefile 是一个编译指令的脚本,里面记录了一条条编译指令,用于描述程序的编译规则;
  2. Makefile 文件里面的编译指令是根据我们自己写的程序,编写的编译规则。

3.makeflie与gcc的对比

  1. 用 gcc 编译的时候,我们要在后面跟上要编译的文件名,如:

    gcc main.c func.c
    

    文件量和代码量较少的时候,用这种方式编译还比较方便,但如果整体项目很多,文件很多的时候,编译起来就比较困难,而且还容易漏掉一些文件。没人能保证自己的代码一次运行成功,会反复编译,调试,那每次调试都需要输入很长的 gcc 命令。遇到后期追加功能的时候,时间长了,也忘记项目用到了哪些文件了,对后期工作也会造成困扰;

  2. 而在 makeflie 里面提前写好了编译指令,只是在编写 makefile 文件的时候需要花费时间,但后面重复编译每次只需要 make 指令调用编译就行了,简化了编译过程。同时后期即使追加功能,以前的编译的文件指令都保存在 makefile 文件里了,也不用担心忘记需要编译哪些文件;

  3. gcc 编译很大项目的时候,编译时间会很长,如果对代码进行了修改再编译,即使没有修改代码的文件,也要一起重新编译一次,又得消耗很长的时间;

  4. makefile 只会对修改过的代码文件重新编译,其它未修改的直接使用以前编译好的可执行文件,除了第一次编译需要花费较长时间外,后面编译都比较快。因此,make 不仅简化了编译步骤,还节省编译时间,提高编译效率。

二、makefile的语法规则

1.makefile语法规则

1.1语法

先创建一个 makefile 文件,在文件里面写命令:

目标:依赖文件列表
	命令列表 // 命令列表前有缩进
  • gcc 编译
gcc main.c -o main
  1. 目标:通常是要产生的可执行文件名,如上面的 main;
  2. 依赖文件:是用来输入从而产生目标的文件,一个目标通常有一个或多个依赖文件,如上面的 main.c;
  3. 命令:make 执行的动作,一个规则可以含几个命令,有多个命令时,每个命令占一行,如上面的gcc main.c -o main
  • 注意: makefile 文件里面写的是脚本,要严格遵守脚本的语法规则,有时候多一个少一个空格都可能造成错误。

1.2makefile编译演示

先创建 makefile 文件,在文件里写入如下命令:

main:main.c func.c
	gcc main.c func.c -o main

接着在 linux 终端输入make命令即可实现编译。

  • 注意:上面只是演示 makefile 命令的语法,和真正的 makefile 实现的功能差远了。这里的 make 只会执行第一个目标的语句,如果下方还有其它语句不会执行。

1.3make命令格式

1.3.1自定义 makefile 文件名
make -f 自定义文件名
  • 在终端输入 make 命令时默认在工作目录中寻找名为 GNUmakefile、makefile、Makefile 的文件作为 makefile 输入文件,但如果我们不按照上面的文件名命名,而是修改为自定义的文件名,那么就需要在 make 命令后面加上我们自定义的文件名,如:
make -f my_makefile

但一般不建议这样做。

1.3.2make后跟其它目标

前面说到,make 执行第一个目标的语句后,后面目标的语句就不会执行了,那要执行后面目标的语句,我们可以指定目标:

make 目标
  • 例如:makefile
main:main.c func.c
	gcc main.c func.c -o main
clean:
	rm main.c

可以通过输入:终端输入make clean,来执行指定的语句。

1.3.3复杂版makefile
main:main.o fun.o
	gcc main.o fun.o -o main
main.o:main.c
	gcc -c main.c -o main.o
fun.o:fun.c
	gcc -c fun.c -o fun.o
clean:
	rm main *.o
  • 说明:
    1. 当终端输入 make 命令时,会执行 makefile 文件里的第一条命令,但发现依赖的main.o fun.o文件不存在,会执行下面的命令,先生成main.o fun.o再执行第一条的命令;
    2. *.o里面的 * 是通配符,这里表示所有以 .o结尾的文件;
    3. clean:为假想目标,只有目标,没有依赖。

三、makefile的变量

makefile 变量类似于 C 语言中的宏,当 makefile 被 make 工具解析时,其中的变量会被展开。变量一般用于:保存文件名列表、保存文件目录列表、保存编译器名、保存编译参数、保存编译的输出等。

1.自定义变量

  • 定义格式
变量名=变量值
  • 说明

    1. 注意,等号两边没有空格,应该严格遵循脚本语言的语法编写;
    2. makefile 变量名可以以数字开头,区分大小写;
    3. 变量一般都在 makefile 的头部定义,几乎可在 makefile 的任何地方使用;
    4. 如果需要读取变量的值,需要在变量名前加上美元符号 , , ,(变量名)或${变量名};
    5. 自定义变量的作用,主要是为了方便切换不同编译方式,方便指定生成的可执行文件名等,如果一个字符在命令中出现多次,就可以通过变量来代替,如:
    CC=gcc
    EXEC=main
    
    $(EXEC):main.o fun.o
    	$(CC) main.o fun.o -o $(EXEC)
    main.o:main.c
    	$(CC) -c main.c -o main.o
    fun.o:fun.c
    	$(CC) -c fun.c -o fun.o
    clean:
    	rm $(EXEC) *.o
    

2.系统环境变量

make 工具会拷贝系统的环境变量并将其设置为 makefile 的变量,在 makefile 中可直接读取或修改拷贝后的变量,读取环境变量的方法和前面读取自定义变量的方法相同,如:

CC=gcc
EXEC=main

$(EXEC):main.o fun.o
	$(CC) main.o fun.o -o $(EXEC)
main.o:main.c
	$(CC) -c main.c -o main.o
fun.o:fun.c
	$(CC) -c fun.c -o fun.o
clean:
	rm $(EXEC) *.o
    echo $(PWD) // PWD 是一个环境变量   
  • 说明:
    1. echo 相当于C语言里的 printf,将内容输出到终端;
    2. 我们除了可以使用系统的环境变量,还可以自己导出环境变量:export NUM=100
    3. 自己导出的环境变量只在当前终端有效,不会影响系统的环境变量。

3.预定义环境变量

预定义环境变量即 makefile 定义好的环境变量。

  1. $@ 当前命令的目标名
  2. $< 当前命令依赖文件列表中的第一个文件
  3. $^ 当前命令依赖文件列表,带有除去重复文件的功能
  4. AR 归档维护程序的程序名,默认值为 ar
  5. ARFLAGS 归档维护程序的选项
  6. AS 汇编程序的名称,默认值为 as
  7. ASFLAGS 汇编程序的选项
  8. CC C 编译器的名称,默认值为 cc
  9. CFLAGS C 编译器的选项
  10. CPP C 预编译器的名称,默认值为$(CC) -E
  11. CPPFLAGS C 预编译的选项
  12. CXX C++编译器的名称,默认值为 g++
  13. CXXFLAGS C++编译器的选项

较常用的是前三个,对上面命令的升级版:

CC=gcc
EXEC=main

$(EXEC):main.o fun.o
	$(CC) $^ -o $@
main.o:main.c
	$(CC) -c $< -o $@
fun.o:fun.c
	$(CC) -c $< -o $@
clean:
	rm $(EXEC) *.o
    echo $(PWD)

上面的代码可以发现,7、8行代码重复,因此可以合并,使用通配符 %:

CC=gcc
EXEC=main
OBJ=main.o fun.o // 将依赖文件通过自定义变量保存    

$(EXEC):$(OBJ)
	$(CC) $^ -o $@
%.o:%.c
	$(CC) -c $< -o $@
clean:
	rm $(EXEC) $(OBJ)
    echo $(PWD)

标签:15,CC,make,makefile,编译,fun,main
From: https://blog.csdn.net/qq_63958145/article/details/144728561

相关文章

  • 《痞子衡嵌入式半月刊》 第 115 期
    痞子衡嵌入式半月刊:第115期这里分享嵌入式领域有用有趣的项目/工具以及一些热点新闻,农历年分二十四节气,希望在每个交节之日准时发布一期。本期刊是开源项目(GitHub:JayHeng/pzh-mcu-bi-weekly),欢迎提交issue,投稿或推荐你知道的嵌入式那些事儿。上期回顾:《痞子衡嵌入式半月......
  • # [THUSC2015] 异或运算
    P5795[THUSC2015]异或运算题目描述给定长度为\(n\)的数列\(X={x_1,x_2,...,x_n}\)和长度为\(m\)的数列\(Y={y_1,y_2,...,y_m}\),令矩阵\(A\)中第\(i\)行第\(j\)列的值\(A_{i,j}=x_i\\operatorname{xor}\y_j\),每次询问给定矩形区域\(i∈[u,d],j∈[l,r]\),找出第......
  • Hadoop YARN:调度性能优化实践15
     背景YARN作为Hadoop的资源管理系统,负责Hadoop集群上计算资源的管理和作业调度。美团的YARN以社区2.7.1版本为基础构建分支。目前在YARN上支撑离线业务、实时业务以及机器学习业务。离线业务主要运行的是HiveonMapReduce,SparkSQL为主的数据仓库作业。实时业务主要运行S......
  • Hadoop YARN:调度性能优化实践15
     背景YARN作为Hadoop的资源管理系统,负责Hadoop集群上计算资源的管理和作业调度。美团的YARN以社区2.7.1版本为基础构建分支。目前在YARN上支撑离线业务、实时业务以及机器学习业务。离线业务主要运行的是HiveonMapReduce,SparkSQL为主的数据仓库作业。实时业务主要运行S......
  • Week 15:“物品复活”软件开发总结
    软件工程课程总结:基于Tkinter的物品管理系统开发体会1.项目背景与功能概述在《软件工程》课程的学习中,我完成了一个基于Tkinter的物品管理系统的开发。该程序的主要功能包括物品的添加、编辑、删除、恢复,以及搜索管理等操作,同时提供了回收站功能以便用户可以管理已删除的物品。......
  • 《计算机组成及汇编语言原理》阅读笔记:p86-p115
    《计算机组成及汇编语言原理》学习第6天,p86-p115总结,总计20页。一、技术总结1.ifstatement2.loop在许多编程语言中,有类种循环:一种是在程序开头检测条件(testthecondition),另一种是在程序末尾检测条件。3.Collatzconjecture(考拉兹猜想)对于每一个正整数,如果它是......
  • Springboot旧教材交易系统a6151(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表用户,书籍类型,书籍信息开题报告内容一、研究背景随着高等教育的普及和校园生活的丰富多彩,学生们在学习和生活中积累了大量的旧教材。这些旧教材对于个人而言,可......
  • 【Linux】Linux开发利器:make与Makefile自动化构建详解
    Linux相关知识点可以通过点击以下链接进行学习一起加油!初识指令指令进阶权限管理yum包管理与vim编辑器GCC/G++编译器在现代软件开发中,自动化构建工具显得尤为重要,make和Makefile是Linux环境下的常用选择。它们通过定义规则和依赖关系,帮助开发者高效管理项目的构建过程。......
  • Linux工具使用指南:从apt管理、gcc编译到makefile构建与gdb调试
    文章目录前言......
  • .NET周刊【12月第3期 2024-12-15】
    国内文章重磅推出SdcbChats:一个全新的开源大语言模型前端https://www.cnblogs.com/sdcb/p/18597030/sdcb-chats-introSdcbChats是一个新推出的开源大语言模型前端,旨在提升用户交互体验,并填补市场上基于.NET的前端空白。它引入树状消息结构,允许用户方便地与模型互动并优化对......