makefile从入门到实战 第一章 认识makefile(一)

Makefile详解——从入门到精通 转自ChinaUnix,作者gunguymadman,陈皓。链接地址:http://www.chinaunix.net/jh/23/408225.html 陈皓 优快云 博客:http://blog.youkuaiyun.com/haoel/article/details/2886 http://blog.youkuaiyun.com/ruglcc/article/deta... 阅读详情

一、makefile入门

1、相关概念介绍

(1)一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定哪些文件需要先编译、哪些文件需要后编译、哪些文件需要重新编译,甚至需要进行更复杂的功能操作。

(2)“make”是一个命令工具,它解释makefile中的指令,在Makefile文件中描述了整个工程所有文件的编译顺序、编译规则。

2、入门的第一个Makefile(makefile基础语法)

(1)makefile的基本语法:

<目标>:<依赖1> <依赖2>……

Tab @<命令1>

Tab @<命令2>

……

①目标:一般是指要编译的目标,也可以是一个动作,它由程序员自行命名。

②依赖:指执行当前目标所要依赖的先项(或者说前置条件),包括执行其它目标、某个具体文件或库等;一个目标可以有多个依赖,也可以没有依赖,如果没有则不写,如果有多个依赖则用空格分割。

③命令:该目标下需要执行的具体命令,可以没有,也可以有若干条,如果有多条命令,则每条命令写一行;命令前加“@”会抑制命令本身的打印(就是把命令的原文内容打印出来),一般不需要加。

(2)第一个Makefile示例:

a:b c
	echo "hello A_world"
	ls ./    #列出当前目录下的文件

b:
	echo "hello B_world"

c:
	echo "hello C_world"

        目标a依赖目标b和目标c,那么在执行目标a时,需要先执行目标b和目标c(目标b和目标c的执行顺序不固定),再执行目标a

3、make命令工具常用选项

(1)make命令工具的格式:

make [-f filename] [other options] [target]

(2)make默认在当前目录中按顺序依次寻找名为GUNmakefile、makefile、Makefile的文件作为输入文件(仅有一个输入文件,找到即进行编译,不是三个都读取一遍),如果不写参数(指定执行的目标),则make执行输入文件中的第一个目标,如果第一个目标有依赖,则会先执行其所依赖的目标,再执行它。

    make        # 不写参数,自动读上面三个文件之一,然后执行第一个目标
    make b      # 手动指定目标b,只执行输入文件中的目标b

(3)常用选项(可叠加):

①“-f filename”:make默认只寻找名为GNUmakefile、makefile、Makefile的文件,如果是自定义的脚本名字(如build.mk),则需要加上该参数。

    make -f build.mk

②“-n”:空跑、预览指令,不会真实运行,多用于调试,检查Makefile中的指令是否写错。

    make -n

③“-s”:只执行命令,但不显示具体命令,作用和“@”一样,只不过“@”是屏蔽单行指令打印。

    make -s

④“-C”:指定Makefile所在的目录(如./src)。

    make -C ./src

⑤“-v”:查看make工具的版本号。

    make -v

⑥“-w”:多级工程跨目录编译时,打印执行前和执行后的所在路径。

    make -w

4、程序编译流程

(1)以gcc为例,gcc命令能够直接从源代码生成目标可执行文件,其格式如下所示。需要注意的是,gcc是C编译器,如果要编译C++源码,则需要加“-lstdc++”。

    gcc main.c
    gcc -lstdc++ main.cpp

(2)一条gcc命令其实是分4步进行编译的:

①预处理:展开#include,替换#define宏,删除注释,如果是编译.c文件则输出.i文件,如果是编译.cpp文件则输出.ii文件。

    gcc -E main.c > main.i
    gcc -E main.cpp > main.ii

②编译:经过语法分析、词法分析、语义分析和符号会中,把C/C++代码转换成汇编代码,结果保存在.s文件中。

    gcc -S main.i
    gcc -S main.ii

③汇编:把汇编代码转换为二进制/机器指令,结果保存在.o文件中。

    gcc -c main.s

④链接:把多个.o文件合并(C++的链接还需要合并标准库libstdc++.so),以及符号表的重定位,生成可执行程序。

    gcc main.o
    gcc main.o -lstdc++

5、makefile中的变量

(1)自动系统变量:

①自动系统变量只在“<目标>:<依赖>”下的命令中生效,不用手动赋值,使用方法比如:

app:main.c func.c test.c
	$(CC) $^ -o $@

②自动系统变量的符号:

符号

释义

上例目标app中的自动系统变量含义

$@

当前目标的目标名

$@ = app

$<

当前目标的第一个依赖

$< = main.c

$^

当前目标的所有依赖(空格分隔),重复的将去除

$^ = main.c func.c test.c

$+

当前目标的所有依赖(空格分隔),重复的也不去除

$+ = main.c func.c test.c

$?

比目标新(时间戳比目标文件晚的依赖文件)

$?只列出最近修改过的源文件(更新时间比目标文件晚的依赖文件)

$*

当前目标去掉后缀的名字

如果当前目标名为“main.o”,则$* = main

(2)系统内置常量:

①make工具出厂自带全局变量,“make -p”可以查看全部系统内置常量及默认值。

②常用的系统内置常量:

常量名

释义

默认值

AS

汇编程序的名称

as

CC

C编译器的名称

cc

CPP

C预编译器的名称

cc -E

CXX

C++编译器的名称

g++

RM

文件删除程序名

rm -f

(3)自定义变量:

①自定义变量由程序员自行定义,可用于简化代码、方便统一修改编译参数(作用有点类似于C语言中的#define)。

②自定义变量定义格式(特别说明,尖括号不是语法的一部分):

<变量名> = <变量值>

③自定义变量调用格式(特别说明,尖括号不是语法的一部分):

$(<变量名>)

${<变量名>}

④自定义变量定义和使用举例:

# 自定义变量
CC = gcc            	# 指定编译器
CFLAGS = -g -Wall   	# 编译参数:g调试、Wall告警
SRC = main.c func.c
OBJ = main.o func.o
TARGET = app

$(TARGET):$(OBJ)
	$(CC) $(OBJ) -o $(TARGET) $(CFLAGS)
%.o:%.c
	$(CC) -c $< -o $@ $(CFLAGS)
clean:
	rm -rf $(OBJ) $(TARGET)

6、makefile的运行流程和伪目标

(1)make的时间戳原理(编译时间最小化):

        比如在Linux中,每个文件都有一个“修改时间”,即文件内容最后一次被改动的时间

        make会将目标文件和其任意一个依赖文件的时间比对,如果依赖文件更新时间更晚,则需要重新编译;目标的依赖仍然是一个目标,它也要和自己所依赖的文件做更新时间比对,如果依赖文件更新时间更晚,则也需要重新编译,以此递归下去,直到目标没有依赖,则判断目标文件是否存在,若存在则不需要重新编译,否则需要生成目标文件

(2)伪目标:

①如果目录中有与makefile中目标同名的文件,比如“clean”,而它正好没有任何依赖,那么“make clean”会判定clean文件已经是最新的文件,不会执行clean这个目标,为了避免这种情况,凡是只做动作、不生成与目标名同名文件的目标,都声明为伪目标,这样makefile就不会判断目标是否存在对应的文件以及是否需要更新。

②伪目标的声明方式:

.PHONY: <目标名>

③伪目标声明举例:

.PHONY: clean
clean:
	rm -rf *.o app

7、模式匹配

(1)模式匹配:

①“%”是通配符,可以代表任意一串文件名(作用类似于模糊搜索)。

②举例:

.PHONY:clean show

OBJ= sub.o multi.o calc.o add.o
TARGET=calc

$(TARGET):$(OBJ)
	$(CXX) $^ -o $@

%.o:%.cpp
	$(CXX) -c $^ -o $@

clean:
	$(RM) *.o $(TARGET)

        遇到sub.o,自动匹配依赖sub.cpp;遇到add.o,自动匹配依赖add.cpp

        再配合自动系统变量——$< = %.cpp、$@ = %.o,可不用将目标和依赖关系逐个列出

(2)两个Make内置函数:

①wildcard函数:可以获取当前目录中所有指定后缀的文件。

SRC := $(wildcard ./*.cpp)
# SRC = a.cpp b.cpp main.cpp   当前目录中有a.cpp、b.cpp、main.cpp

②patsubst函数:对被指定变量中的文件名做批量替换(被指定的变量不会改变,该函数是返回替换后的文件名),常用于替换后缀。

SRC=$(wildcard ./*.cpp)
OBJ=$(patsubst %.cpp,%.o,$(SRC))
# SRC:a.cpp b.cpp → OBJ:a.o b.o   当前目录中有a.cpp、b.cpp

(4)使用以上两个内置函数,可以对模式匹配中的举例进行优化,定义变量OBJ时可以不用再一一列出当前目录中的文件名。

.PHONY:clean show

OBJ=$(patsubst %.cpp,%.o,$(wildcard ./*.cpp))
TARGET=calc

$(TARGET):$(OBJ)
	$(CXX) $^ -o $@

%.o:%.cpp
	$(CXX) -c $^ -o $@

clean:
	$(RM) *.o $(TARGET)
《Makefile 进阶之路一》 这里有你对Makefile所有的畅想 make在执行这个规则所定义的命令之前,首先处理目标“edit”的所有的依赖文件(例子中的那些.o 文件)的更新规则(以这些.o 文件为目标的规则)。这些.o 文件所在的规则之所以会被执行,是因为这些.o 文件出现在“终极目标”的依赖列表中。在 Makefile 中一个规则的目标如果不是“终极目标”所依赖的(或者“终极目标”的依赖文件所依赖的),那么这个规则将不会被执行,除非明确指定执行这个规则(可以通过 make 的命令行指定重建目标,那么这个目标所在的规则就会被执行,例如 “make clean”)。 阅读详情

相关推荐

Revit实战:从零到一,手把手教你用族(Family)搭建一个完整的水闸BIM模型

本文详细介绍了如何使用Revit的族(Family)功能从零开始构建一个完整的水闸BIM模型。通过参数化族设计,实现闸门开度调整自动关联流量计算等智能化功能,提升水利工程BIM模型的工程价值和应用效率。文章涵盖族库规划、核心构件创建、高级技巧及BIM数据深度应用,为水利工程数字化提供实用指南。

weixin_28738165的博客 261

Makefile入门一、helloworld

Makefile入门一、helloworld1、了解gcc从源码到可执行文件的步骤2、Makefile的helloworld3、提到Makefile不得不了解gcc命令 1、了解gcc从源码到可执行文件的步骤 大体分为一下四个步骤 第一步、预处理阶段:处理源码中的预处理语句(总是以#打头,如#include、#if #elif #end #error、#pragma pack|comment等);...

hjxu2016的博客 3717

别再手动调参了!用MATLAB+改进PSO算法,5步搞定机械臂轨迹优化(附完整代码)

本文介绍如何利用MATLAB和改进PSO算法快速优化机械臂轨迹规划,仅需5步即可完成传统耗时的手动调参过程。通过混沌初始化、自适应权重等创新方法,改进PSO算法显著提升优化效率,实现全局最优解搜索,适用于工业自动化中的机械臂控制。文章包含完整MATLAB代码实现,帮助工程师轻松应用于实际生产场景。

weixin_29232121的博客 352

新手入门 Makefile:FPGA 项目实战教程(三)

本文介绍了使用Makefile自动化FPGA开发流程的实战教程,以LED闪烁项目为例。主要内容包括:1) 项目需求分析,设计25位计数器实现1Hz LED闪烁;2) 提供Verilog RTL代码和XDC约束文件示例;3) 详细讲解Makefile脚本编写,包含变量定义、构建目标和清理功能;4) 讲解配套的Tcl脚本,实现项目创建、文件添加、综合实现等自动化流程。该教程为FPGA开发者提供了从代码编写到自动化构建的完整解决方案,适用于Xilinx Vivado开发环境,特别适合需要提高开发效率的工程师。

现任某外企的算法工程师!专注于人工智能、嵌入式、FPGA、论文写作四大主题的教程和经验分享!辅导请➕v :sci666888999 2134

GameFramework框架详解之 框架总览

一.前言 目前市场上有很多优秀个开源框架,比如ET,GameFramework,DBFramework,StrangeIOC,Loxodon-Framework,KSFramework,xluaFramework等等。其中要说规范的话,不得不说GameFramework还是不错的,当然很多新手看到后会觉的有点复杂,写一个小小的功能,不得不套用一堆东西,继承一堆接口,感觉不知所措,不能随心所欲的去撸代码。其实这个框架就是为了约束新手的行为的,让我们面向接口编程,遵循“开闭”的设计原则来写代码,方便后期的扩

TxNet 2万+

【DRAM存储器六十二】DDR5介绍--引脚和基本功能简介

详述DDR5与DDR4的引脚区别和DDR5基本功能

highman110的博客 523

Makefile入门

Makefile入门

weixin_54859557的博客 1377

基于物联网设计的蜂箱智能监测系统设计

为解决传统养蜂业依赖人工、管理效率低下、干扰蜂群等问题,本项目设计并实现了一套基于物联网(IoT)的蜂箱智能监测系统。

679

新手入门 Makefile:FPGA 项目实战教程(一)

本文介绍了使用Makefile自动化FPGA开发流程的基础知识。主要内容包括:Makefile的概念及其在FPGA项目中的优势(自动化、版本控制友好、可重复性);环境准备(Vivado安装、GNU Make验证、环境变量设置);Makefile基础语法(规则结构、变量定义、自动变量、伪目标);以及推荐的FPGA项目目录结构(src/rtl、constraints、ip等标准化布局)。文章旨在帮助FPGA开发者通过Makefile实现高效的项目构建和管理,提高开发效率。

现任某外企的算法工程师!专注于人工智能、嵌入式、FPGA、论文写作四大主题的教程和经验分享!辅导请➕v :sci666888999 1636

基于摩尔线程 S80 显卡在 Ubuntu 系统下双卡交火部署 DeepSeek

curl -X POST -H "Content-Type: application/json" -d '{"prompt": "你的问题"}' http://localhost:11434/api/generate。curl -X POST -H "Content-Type: application/json" -d '{"prompt": "你的问题"}' http://localhost:11434/api/generate。- 为避免模型占用系统盘空间,可将模型存储路径修改到其他磁盘。

靡不有初,鲜克有终 1193

防护装备穿戴检查:基于YOLOv8与UI界面的深度学习应用

通过结合YOLOv8模型与UI界面,本系统实现了防护装备穿戴检查的自动化。该系统能够快速识别工作人员是否正确佩戴了所需的防护装备,帮助提高安全管理水平。未来,随着技术的发展,防护装备穿戴检查系统将在更多领域得到应用,如工业现场、建筑工地等,实现更加精确和高效的实时监控。

YOLO 353

新手入门Makefile:FPGA项目实战教程(二)

本文是FPGA项目实战教程系列的第二部分,重点介绍Makefile在FPGA开发中的实际应用。文章提供了一个完整的LED闪烁项目Makefile示例,包含项目创建、文件添加、综合、实现和生成比特流等关键步骤。同时详细讲解了Tcl脚本在Vivado中的重要作用,包括项目管理命令、文件管理命令、综合与实现命令等核心功能。教程还提供了一个完整的Tcl脚本示例,展示了从项目创建到比特流生成的全流程自动化实现方法,帮助开发者提高FPGA开发效率。

现任某外企的算法工程师!专注于人工智能、嵌入式、FPGA、论文写作四大主题的教程和经验分享!辅导请➕v :sci666888999 1408

2025年5月架构设计师论文真题回顾,附写作技巧、所涉知识点及参考范文(三)

本文主要回顾2025年上半年(2025-5-24)系统架构设计师考试下午论文的题目,同时附带写作技巧、所涉知识点及参考范文。试题三:多模型数据库及应用。

一几文的编程学习笔记。 629

Makefile 入门教程

Makefile 定义了软件开发过程中,项目工程编译链、链接的方法和规则。由 IDE 自动生成或者开发者手动书写。Unix(MAC OS、Solaris)和Linux(Red Hat、Ubuntu、SUSE)系统下由 make 命令调用当前目录下的 Makefile 文件,实现项目工程的自动化编译。Windows 环境开发人员,可能并未听说过 Makefile,但是时时刻刻在使用 Makefile 来完成程序的编译,因为开发者并不需要手动编写 Makefile,而是通过 IDE 自动生成。

Doublelv 的博客专栏。 9150

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

【makefile入门】makefile选项和makefile.buil

学习makefile的常用选项,并通过一个案例来学习makefile.build

jk_lovers的博客 2077

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Makefile的入门

Makefile中的变量赋值运算符有四种,分别是=、:=、?=和+=, $符号表示取变量的值,当变量名多于一= 表示延迟展开赋值即变量的值是在使用时才确定,可能会受到后面的赋值影响。例如,VAR_A = A,VAR_B = $(VAR_A) B,VAR_A = AA,那么最后VAR_B的值是AA B,而不是A B。:= 表示直接赋值,即变量的值是在定义时就确定,不会受到后面的赋值影响。例如,VAR_A := A,

qq_47944751的博客 797

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Makefile 快速入门

一文带你入门makefile

mx_jun的博客 1097

GUN Makefile入门

本文只要针对GNU Makefile前8章及进行了学习和整理。 目录 1. Makefile入门 什么是Makefile 为什么要使用Makefile 2. Makefile初级语法1 基本规则 宏定义(变量定义) 2-1. 定义宏的两种格式 2-2. Override宏 2-3. Target宏 VPATH 命令行前缀 3. Makefile初级语法2 Makefile执行顺序...

8318

makefile入门实战

本篇博客主要试介绍基础的Makefile使用,常用的变量和函数。看完后能理解makefile书写原理,自己写一些简单的makefile。

君莫笑lucky的博客 981

Makefile编写入门

参考:一篇由浅入深、很全面的博客: https://www.jianshu.com/p/442e71755643 此博客中的参考模板: #makefile模板 # 这句是链接时候的命令,在g++前面加入了@echo linking $@ # 这样在链接时候就会先输出linking xxx, # 这行直接写g++也是没有任何问题的 LINK = @echo lingking $@ &&am...

sinat_40408114的博客 400

一文入门Makefile

这是因为上面的%可以看成是任意的东西(类似于通配符中的*),当我们的目标的依赖不存在的时候,Makefile就会在规则中寻找是否目标的依赖和哪个规则的目标一致,找到就会执行这个规则中的命令。上面例子把目标文件直接赋值给了变量targetFile,我们在规则中可以使用$(targetFile)的方式取出test的这个值去使用,当然了上面只是简单地做个示范,我们还可以拿变量去装一些更复杂的东西,比如说一堆的文件(没错,一个变量能装的可不止一个文件,用空格隔开可以装多个)那么Makefile到底是做什么的呢?

m0_63235356的博客 1628

第一章:Makefile入门 - 为什么要用Makefile

Makefile是一个构建自动化工具的配置文件,它告诉make命令如何编译和链接你的程序。想象一下,你有一个包含几十个源文件的项目,每次修改后都要手动输入一堆编译命令,是不是很麻烦?在下一章,我们将学习Makefile的变量使用,让我们的Makefile更简洁、更强大!· recipe(配方):如何生成目标的命令(前面必须是TAB键,不是空格!· target(目标):要生成的文件名,比如program、main.o。· prerequisites(依赖):生成目标所需要的文件。

2402_88177300的博客 265

Makefile从入门到入门

makefile详解

qq_46514141的博客 833

makefile入门

这篇博客将从最简单的makefile讲起,通过不断升级,最后成为项目中常用的makefile文件。 文章目录入门效果预览语法浅析进阶再进阶终极版本题外话 入门 效果预览 1.一个最简单的输出"Hello world"的hello.c文件,内容如下: #include <stdio.h> int main() { printf("Hello world\n"); r...

weixin_43812622的博客 324
上一篇: 现代控制理论——专题 ADRC自抗扰控制
下一篇: makefile从入门到实战 第一章 认识makefile(二)
Zevalin爱灰灰
Zevalin爱灰灰 优质创作者: 嵌入式与硬件开发技术领域 优质创作者: 嵌入式与硬件开发技术领域
博客等级 码龄3年 7137粉丝 552原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zevalin爱灰灰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值