makefile教程

2023-05-16

Makefile是一种用于构建软件项目的自动化工具,通过定义一系列规则和依赖关系,可以自动化构建、编译、测试和安装软件项目。在本篇教程中,我将介绍如何编写一个简单的Makefile,并解释Makefile中的常用语法和规则。

什么是Makefile

Makefile是一个文本文件,其中包含了一系列规则和命令,用于指定如何构建一个软件项目。Makefile通常用于编译和链接程序,并可以在多个平台和编译器之间移植代码。Makefile的语法比较简单,可以通过GNU make程序执行,通常在Linux和Unix系统中已经预装。

Makefile的基本结构

Makefile由一系列规则组成,每个规则包含一个目标(target)、依赖关系(dependencies)和命令(commands)。一个简单的Makefile如下:

target: dependencies
    commands

其中,target表示要构建的目标文件或执行的命令,dependencies表示目标文件所依赖的文件或命令的先决条件,commands表示生成目标文件或执行命令所需要的命令。

示例

下面是一个简单的示例Makefile,用于构建一个hello程序:

CC=gcc
CFLAGS=-Wall -g

hello: hello.o
	$(CC) $(CFLAGS) -o hello hello.o

hello.o: hello.c
	$(CC) $(CFLAGS) -c hello.c

clean:
	rm -f *.o hello

在这个Makefile中,我们定义了三个规则:

  • hello规则表示构建一个名为hello的可执行程序,它依赖于hello.o目标文件。命令是使用gcc编译器链接hello.o目标文件并生成hello可执行文件。
  • hello.o规则表示生成hello.o目标文件,它依赖于hello.c源文件。命令是使用gcc编译器编译hello.c源文件并生成hello.o目标文件。
  • clean规则表示删除所有生成的目标文件和可执行文件。命令是使用rm命令删除所有.o和可执行文件。

Makefile常用语法

变量

在Makefile中,可以使用变量来存储常用的命令、选项、文件名等信息,以便在Makefile中重复使用。变量以$开头,例如$(CC)表示使用C编译器。下面是一个定义变量的例子:

CC=gcc
CFLAGS=-Wall -g

在这个例子中,我们定义了两个变量:CC和CFLAGS。CC表示C编译器的名称,CFLAGS表示编译选项。

目标模式

目标模式表示一类目标文件的命名模式,例如%.o表示所有以.o结尾的目标文件。目标模式可以方便地批量处理多个目标文件,例如下面是一个使用目标模式的例子:

SRCS = main.c foo.c bar.c
OBJS = $(SRCS:.c=.o)

prog: $(OBJS)
	gcc -o $@ $(OBJS)

%.o: %.c
	gcc -c $< -o $@

在这个例子中,我们定义了两个变量:SRCS表示所有源文件,OBJS表示所有目标文件。利用目标模式,我们将所有的.c文件替换成了.o文件,从而定义了所有的目标文件。

prog规则中,我们依赖于所有的目标文件,使用gcc链接所有目标文件生成可执行文件。

%.o规则中,我们使用目标模式来表示所有的目标文件,依赖于对应的源文件,使用gcc编译对应的源文件生成目标文件。

函数

Makefile支持一些函数,用于操作变量或文件名等信息。下面是一些常用的函数:

  • $(wildcard pattern):查找符合模式pattern的文件,返回文件列表。
  • $(patsubst pattern,replacement,text):替换文本中符合模式pattern的部分为replacement。
  • $(notdir names):去掉路径,只返回文件名部分。
  • $(basename names):去掉扩展名,只返回文件名部分。
  • $(dir names):返回路径部分。

下面是一个使用函数的例子:

SRCS = src/main.c src/foo.c src/bar.c
OBJS = $(patsubst src/%.c, obj/%.o, $(SRCS))

prog: $(OBJS)
	gcc -o $@ $(OBJS)

obj/%.o: src/%.c
	gcc -c $< -o $@

clean:
	rm -f $(OBJS)

# Get the number of source files
numsrcs:
	@echo "Number of source files: $(words $(SRCS))"

在这个例子中,我们使用patsubst函数将所有的.c源文件替换成对应的.o目标文件,并将它们放到obj目录中。

clean规则中,我们使用$()将变量展开,然后使用rm命令删除所有.o文件。

numsrcs规则中,我们使用words函数获取SRCS变量中单词的数量,并使用echo命令输出结果。

总结

Makefile是一个非常强大的自动化工具,可以帮助我们构建、编译、测试和安装软件项目。在本篇教程中,我们介绍了Makefile的基本结构、常用语法和规则,并通过示例代码演示了如何编写一个简单的Makefile。掌握Makefile可以让我们更加高效地开发和维护软件项目,是每一个软件开发人员必须掌握的技能之一。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

makefile教程 的相关文章

  • MinGW C 编译器“无法编译简单的测试程序”

    我想将 MinGW 作为 C 编译器运行 MinGW 已从 Chocolatey 安装 调用是通过 CMake 从 gitlab runner 进行的 这失败了 cmake G MinGW Makefiles DCMAKE C COMPIL
  • 这些 g++“多重定义”错误是怎么回事?

    我正处于一个项目的早期阶段 请阅读 昨天刚刚开始 我正在设置我的初始 makefile 这非常简单 以下是该文件的完整内容 all main o resource o g o output exe main o resource o mai
  • 如何重新编译单个内核模块?

    通常内核源代码存储在 usr src linux 2 6 x 为了避免在修改模块的源代码时重新编译整个内核 如何重新编译该模块 切换到源代码树的根目录并运行以下命令 make modules SUBDIRS drivers the modu
  • C: main 未找到,但它在那里 |编译错误

    当我编译两个 c 文件 如下所示 时 我收到一个非常奇怪的错误 终端编译代码 gcc I o main c matrix c lblas lgfortran Error usr bin ld usr lib debug usr lib i3
  • 如何生成缺失的 #include 文件的列表

    背景 我正在开发一个大型 C 项目 其中包含多个可执行文件和库输出 以及一组工作 make 文件 即假设您拥有整个代码库 您可以输入 make 它将构建所有库和可执行文件 我的问题是我必须部分编译该项目 并且只需链接已为项目其他部分编译的库
  • 当我尝试使用“make”安装某些东西时,为什么我的权限被拒绝?

    我正在尝试安装一些东西 但它抛出了一个错误 Permission denied当我尝试跑步时make on it 我不太喜欢unix linux的通用规则 也不太喜欢用户权限 我最好的猜测是我登录的用户没有运行权限make命令 但希望这是其
  • rm -rf 与 -rm -rf

    在 Makefile 中 我读到 rm rf 而不是 rm rf Makefile 行开头的第一个 是什么意思 代表着make本身将忽略来自的任何错误代码rm In a makefile 如果任何命令失败 则make进程本身会停止处理 通过
  • GNU Make 获取父目标名称

    在gnu make中 有没有办法获取启动整个链的原始目标并将执行引导到当前配方 PHONY all clean common all common clean common common echo echo MAKECMDGOALS for
  • 使用 make 构建多个二进制文件

    我想创建一个 Makefile 在父目录中 来调用其他几个 Makefile 在子目录中 这样我就可以通过仅调用一个父 Makefile 来构建多个二进制文件 每个项目子目录一个 我的研究因在递归 Makefile 上找到大量内容而受到阻碍
  • Android.mk 包含其他项目

    说明 我的问题的目标是了解如何创建一个可以构建和运行的 Android mk makefile 如下所示的项目结构 Library is library on eclipse 数据 项目库 Project Interface 包含 1 个静
  • 有关如何部署 C++ 代码以在任何地方工作的提示

    我不是在谈论制作可移植代码 这更多的是一个分配问题 我有一个中型项目 它对常用库有几个依赖项 例如 openssl zlib 等 它在我的机器上编译得很好 现在是时候将它呈现给世界了 本质上是构建最好的工程 我想制作适用于 Windows
  • 使用 gnu make 正确构建 git 子模块

    我目前尝试编写一个 Makefile 来正确构建一个包含 git 子模块的项目 该子模块有自己的一组 makefile 并一次生成多个目标 包括一些库 该 Makefile 应具有以下属性 即使使用并行构建 也不要重建两次子模块 当子模块代
  • Readelf 报告程序是共享库而不是可执行文件

    使用独立的 Android NDK r10e 工具链 使用 toolchain x86 clang3 6 开关构建 出现这种奇怪的行为 交叉编译的环境变量已设置在运行makefile之前 SYSROOT指向Android工具链位置 CXX等
  • GNU Make “Abort trap: 6” 在 gcc 调用之后,但是单独执行时调用是有效的

    我正在使用 GNU Make 构建一个很多人都会使用的 C C 项目 makefile 尝试通用 因为该项目中有许多可选文件 每个用户通过 MATLAB 界面选择这些文件 然后通过命令行参数 make target OPTS XYZ 等 将
  • 错误:安装 ffi 时出错:错误:无法构建 gem 本机扩展

    我在 Mac 64 位系统中遇到此错误 并且机器上安装了 xcode Building native extensions This could take a while ERROR Error installing ffi ERROR F
  • 如果覆盖率低于一定百分比,则单元测试失败

    我制作了一个执行的 makefilego test cover 是否有可能失败make unit tests如果覆盖范围低于 X 则命令 我该怎么做呢 您可以使用TestMain在你的测试中做到这一点 TestMain 可以充当测试的自定义
  • GNU Make 与 patsubst:需要两次替换

    我需要在变量替换的替换中引用词干两次 O23 OROOTS ODIR overx 2wk 3wk mlb 我需要使用相同的词干执行两次替换 但是替换使用patsubst这只做第一个 我们怎样才能同时实现这两点呢 事实上 杰克几乎猜对了 fo
  • 从 Makefile 中的 C++FLAGS 中删除一个标志?

    我有一个 Makefile 其中包含另一个设置了很多默认值的 makefile 我无法编辑包含的 makefile 并且我想更改 makefile 中 C FLAGS 的值 即使它是在包含的 makefile 中设置的 具体来说 每当 de
  • 我怎样才能强制Make一直执行一个菜谱

    当前的 Makefile 有这样的内容 target1 lib1 a lib2 a target2 lib1 a lib3 a target3 lib3 a lib1 a MAKE C sub dir all 我想更改此 Makefile
  • @:(符号冒号)在 Makefile 中意味着什么?

    Makefile 中的以下内容有何作用 rule deps 我在制作手册中似乎找不到这个 它的意思是 不要在输出中回显此命令 所以这条规则是说 执行 shell 命令 并且不回显输出 当然是shell命令 是一个空操作 所以这就是说 什么都

随机推荐

  • 3.1 IoC容器简介

    所有的IoC容器都需要实现接口BeanFactory xff0c 这是一个顶级的容器接口 BeanFactory接口源码 xff1a span class token comment span span class token commen
  • 3.2.1 通过扫描装配你的Bean

    对于扫描装配而言使用的注解是 64 Component和 64 ComponentScan 64 Component是标明哪个类被扫描进入IoC容器 xff0c 而 64 ComponentScan则是标明采用何种策略去扫描装配Bean 修
  • 3.5 使用属性文件

    可以采用默认为我们配置的application properties xff0c 也可以使用自定义的配置文件 引入属性文件依赖 span class token tag span class token tag span class tok
  • 3.6 条件装配Bean

    Bean初始化前 xff0c 对某些属性进行校验 xff0c 满足校验才去装配数据源 为了处理这样的场景 xff0c 需要用到 64 Conditional注解 xff0c 同时需要配合另外一个接口Condition xff08 org s
  • 3.7 Bean的作用域

    isSingleton方法如果返回true xff0c 则Bean在IoC容器中以单例存在 xff0c 这也是Spring IoC容器的默认值 xff1b 如果isPrototype方法返回true xff0c 则当我们每次获取Bean的时
  • 3.8 使用@Profile

    在企业开发的过程中 xff0c 项目往往要面临开发环境 测试环境 准生产环境和生产环境的切换 xff0c 每一套的上下文是不一样的 xff0c 它们有各自的数据库资源 Profile机制 xff1a 实现各个环境之间的切换 假设存在dev
  • 3.9 引入XML配置Bean

    注解 64 ImportResource xff1a 可以引入对应的XML文件 xff0c 用以加载Bean 有时候有些框架 xff08 如Dubbo xff0c Cat xff09 是基于Spring的XML方式进行开发的 xff0c 这
  • 第2章概述

    示例代码 xff1a span class token doctype span class token punctuation lt span span class token doctype tag DOCTYPE span span
  • 【无标题】

    简单接口HelloService span class token keyword public span span class token keyword interface span span class token class nam
  • 穷举法解华为bl锁

    穷举法解华为bl锁 python3代码测试截图 灵感来自于 xff1a https blog csdn net qq 40169767 article details 90481748 但是我不懂shell脚本 xff0c 那个脚本又运行不
  • 4.1.2 ProxyBean的实现

    代理 xff0c 可控制或增加对目标对象的访问 ProxyBean代码 xff1a span class token keyword package span span class token namespace com span clas
  • IDEA中打开.properties文件乱码

    问题 xff1a IDEA中打开 properties文件乱码 解决方法 xff1a 一 代开settings设置 二 搜索File Encodings 三 在Properties Files中选择编码格式为UTF 8 xff0c 注意一定
  • 怎么避免下载流氓软件,误下载后怎么处理

    经历复盘 xff1a 2022 1 20时 xff0c 为了下载SPSS时不小心下载了流氓软件 回过头来复盘一下 xff0c 一个是因为当时不小心点击了电信高速下载 xff0c 下载了一个P2P软件 点击安装的时候就感觉不太对劲 xff0c
  • eclipse查看不了源码怎么办

    问题 使用eclipse的过程中 xff0c 发现ctrl 43 鼠标左键 查看不了源码 解决方案 可以在弹出的提示框中添加源码的压缩包 xff0c 压缩包在你安装的jdk的根目录下 xff0c 如我的是C Application java
  • 关于if循环语句的四种写法

    if语句在java中起到判断语句的作用写法有四种 xff0c 如下 xff1a if if else if else if if else if else 例如 xff1a 一 xff1a if语句第一种写法 if 好处 xff1a 简单便
  • ROS学习——2编写简单的发布者和订阅者

    ros官网教程 xff1a 编写简单的发布者和订阅者 目录 c 43 43 版python版注意 c 43 43 版 在新建好的catkin ws工作空间下建立 cd catkin ws src 在该目录下创建自己的功能包 xff1a ca
  • ubuntu文件系统结构与磁盘管理

    一 根目录 xff1a Linux下 就是根目录 所有的目录都是由根目录衍生出来的 二 ubuntu 文件系统结构 xff1a 三 绝对路径和相对路径 xff1a 绝对路径 xff1a 从根目录 算起的路径 相对路径 xff1a 相对于目前
  • Framebuffer应用编程

    一 Framebuffer介绍 在Linux系统中通过Framebuffer xff08 帧缓冲 xff09 驱动程序来控制LCD Framebuffer就是一块内存 xff0c 里面保存着一帧图像 Framebuffer中保存着一帧图像的
  • Java编辑提示错误: 编码 GBK 的不可映射字符 (0x80)

    在DOS界面运行编译Java文件时提示错误 xff1a 编码 GBK 的不可映射字符 0x80 理解 xff1a java程序在编译的时候 xff0c 需要使用JDK开发工具包中的JAVAC EXE命令 xff0c 而JDK开发工具包是国际
  • makefile教程

    Makefile是一种用于构建软件项目的自动化工具 xff0c 通过定义一系列规则和依赖关系 xff0c 可以自动化构建 编译 测试和安装软件项目 在本篇教程中 xff0c 我将介绍如何编写一个简单的Makefile xff0c 并解释Ma