Linux基础----Makefile(1)

2023-05-16

前言

刚开始学习Linux,这些那真的是新知识,由于感觉将来FPGA的学习会越来越靠近软件的方向发展,所以觉得有必要好好地学习一下嵌入式的东西,因此有必要把学习的过程记录下来,方便自己将来查看。


1. Makefile 3要素数

Makefile的三个要素是 目标、依赖、命令,一个Makefile里面这三个是最基本的东西。

目标最终期望生成的文件
依赖生成目标文件所用到的一些依赖的文件或者依赖的目标
命令每个目标或依赖下面需要执行的一些命令

一个最简单的Makefile的例子如下:

.PHONY:targetb

target_a: target_b target_c
        echo "target_a"

target_b: 
        echo "target_b"

target_c: 
        echo "target_c"                          

在终端中执行这个Makefile的时候,输出的结果如下。
在这里插入图片描述
从这个最简单的例子,就能够看出Makefile最基本的一个执行的过程。首先,最终希望生成的目标是arget_a, 由于这个目标依赖于目标target_btarget_c, 因此,make工具会先去生成这些依赖的目标,所以会一次去生成 target_btarget_c 。因此可以在终端中看到,打印信息,首先打印的是 target_b 的打印信息,然后是target_c的打印信息,最后是target_a 的打印信息。


2. 基本的Makefile管理

2.1 基本的框架

使用make工具进行工程的管理的时候,需要了解基本的语法。对于我这种新手,那还是简简单单地来。两个简单地例子,来帮助自己记忆。
在工程文件夹下有三个文件,分别是 main.c, mp3.c, Makefile. 完成的功能就是最简单的打印信息的功能。其中文件内容如下:

mp3.c
#include<stdio.h>

void play()
{
	printf("play music! \r\n");
}

void stop()
{
	printf("stop music! \r\n");
}

main.c
#include <stdio.h>

int main()
{
	play();
	stop();
	return 0;
}

Makefile
mp3:main.o mp3.o
	gcc  main.o mp3.o -o mp3

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

mp3.o:
	gcc -c mp3.c -o mp3.o

.PHONY:clean


clean:
	rm mp3

在这里插入图片描述
Makefile 的基本实现就是:最终的可执行文件 mp3 依赖于 mp3.cmain.o,这样能够避免直接对源文件进行依赖,在编译的时候,能够加快效率,因为Make工具会去检测当前的这些文件是否有发生改变。这样最终的可执行文件只依赖于 .o文件,若其中的某一个源文件发生了变化,只需要去更新对应的.o文件就可以。
在终端中执行make命令之后,就能得到最终的可执行程序。
在这里插入图片描述

2.2 Makefile中的变量

2.2.1 系统变量

在Makefile中常用的系统变量有系统的编译器,汇编器,make工具等等,由于初学,因此也就先记住这三个就完事儿了。

$(CC)	# 编译器
$(AS) 	# 汇编器
$(MAKE) # make工具

2.2.2 用户变量及其赋值方式

用户自己的变量很好理解,就是在等号左边的变量,可以使用等号来进行赋值,但是在赋值的时候,得小心了,对用户自定义得变量得赋值有几种方式。

赋值方式含义
=延时赋值, 延时赋值得结果,不是立刻赋值给变量的
若一个变量给另一个变量赋值,那么被赋值的变量的
结果就是等号右边变量的结果,若右边的变量值发生
变化,左边被赋值的变量也会发生变化
:=立即赋值, 将值赋值给变量
?=空赋值 , 只有当变量还没有被赋值的时候才会对其进行赋值
+=追加赋值, 在变量原来值得后面追加

这几种赋值得方式得要注意,还挺麻烦的,举个简单的例子:

A?=123	# 空赋值,若变量A没赋值,那么将123赋值给A
B=$(A) 	# 延时赋值,当前A的值赋值给B
C:=$(A) # 立即赋值,将A的值赋值给C
A+=456 	# 追加赋值, 在A原来的值的后面添加456

.PHONY:all

all:
	# system var
	echo "$(CC)"
	echo "$(AS)"
	echo "$(MAKE)"

	# user var
	echo "$(A)"
	echo "$(B)" # 打印当前B的值(为追加赋值后的A的值)
	echo "$(C)" # 打印C的值(为未追加赋值的A的值)

首先进行直接执行make命令,可以看到,最开始A没有赋值,所以将A赋值为123,然后分别对BC 赋值,然后再对A进行追加赋值,从最后打印结果来看,A的值就是最初的123 然后加上追加的456,B由于是延时赋值,所以它的值,是当前A的值,也即是123 456。C由于是立即赋值,所以其结果是赋值的时候的A的值,也就是123。
在这里插入图片描述

2.2.3自动化变量

自动化变量常用的也就三个

$< # 表示目标的第一个依赖
$^ # 表示所有的依赖
$@ # 表示生成的目标
all: targeta targetb
        echo "$<" # $< 表示第一个依赖文件
        echo "$^" # $^ 表示全部的依赖文件
        echo "$@" # $@ 表示目标

targeta:

targetb:

在这里插入图片描述

2.3 对基本框架进行修改

有了上面的基本的概念之后,就可以对之间的最基础的makefile进行修改,从而是Makefile的灵活性提高。

CC=gcc # 指定编译器GCC
TARGET=mp3 # 最终的目标
OBJS=main.o mp3.o # 重定位文件

$(TARGET):$(OBJS)
        $(CC) $^  -o $@ 	# 将所有的.o生成最终的可执行文件

main.o:
        $(CC) -c main.c -o main.o

mp3.o:
        $(CC) -c mp3.c -o mp3.o

.PHONY:clean


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

Linux基础----Makefile(1) 的相关文章

  • 将环境变量从 Makefile 导出到用户态环境

    我正在研究如何从 Makefile 环境变量导出以在用户环境中公开 因此应该可以从用户 shell 访问从 Makefile 导出这些变量 我努力了make s export https www gnu org software make
  • 为什么我收到的数据包数据大小大于mss?

    我在两台 PC 上使用 ifconfig ethX mtu 300 修改了 MTU 并使用 netperf 测试网络 我用 WireShark 嗅探了 SYN 数据包中的 MSS 260 但我得到了一些大于 260 的数据包 为什么 嗅探器
  • 在 Mac OS X 上构建 Linux 内核

    我正在做一个修改Linux内核的项目 我有一台桌面 Linux 机器 在上面构建内核没有问题 不过 我要去旅行 我想在途中工作 我只有一台 MacBook 当我尝试构建 Linux 内核时 它抱怨说elf h was not found 我
  • Elasticsearch 无法写入日志文件

    我想激活 elasticsearch 的日志 当我运行 elasticsearch 二进制文件时 我意识到我在日志记录方面遇到问题 无法加载配置 这是输出 sudo usr share elasticsearch bin elasticse
  • awk 子串单个字符

    这是columns txt aaa bbb 3 ccc ddd 2 eee fff 1 3 3 g 3 hhh i jjj 3 kkk ll 3 mm nn oo 3 我可以找到第二列以 b 开头的行 awk if substr 2 1 1
  • MinGW Make 抛出“系统找不到指定的路径。”错误

    我正在尝试在 Windows 7 上使用 cmake 生成一个 c 项目 在实际创建项目之前 cmake 会对您的工具链进行快速测试 我正在使用 MinGW 这就是我的问题所在 Cmake 触发 make 构建 最终失败并返回 系统找不到指
  • 如何制作一个makefile只用于编译一些java文件?

    我有三个java文件 名为A java B java C java A将创建对象B B将创建对象C 但我以前从未构建过makefile 有谁可以帮我构建一个 makefile 来编译这三个 java 文件吗 我应该使用什么工具来制作 mak
  • 强制卸载 NFS 安装目录 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案
  • Linux 中的无缓冲 I/O

    我正在写入大量的数据 这些数据数周内都不会再次读取 由于我的程序运行 机器上的可用内存量 显示为 空闲 或 顶部 很快下降 我的内存量应用程序使用量不会增加 其他进程使用的内存量也不会增加 这让我相信内存正在被文件系统缓存消耗 因为我不打算
  • 如何通过替换为空页映射来取消映射 mmap 文件

    Linux 用户空间有没有办法用空页面 映射自 dev null 或者可能是一个空页面 重复映射到从文件映射的页面的顶部 对于上下文 我想找到这个 JDK bug 的修复 https bugs openjdk java net browse
  • 如何使用 bash 锁定文件

    我有一个任务从远程服务器同步目录 rsync av email protected cdn cgi l email protection srv data srv data 为了使其定期运行并避免脚本 reEnter 问题 我使用 rsyn
  • 如何在 Linux 中编写文本模式 GUI? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 当我编写脚本 程序时 我经常想弹出一个简单的文本 gui 来提示输入 我该怎么做 例如 来自 Shel
  • 如何在bash中使用jq从变量中包含的json中提取值

    我正在编写一个 bash 脚本 其中存储了一个 json 值 现在我想使用 Jq 提取该 json 中的值 使用的代码是 json val code lyz1To6ZTWClDHSiaeXyxg redirect to http examp
  • 无法从 jenkins 作为后台进程运行 nohup 命令

    更新 根据下面的讨论 我编辑了我的答案以获得更准确的描述 我正在尝试从詹金斯运行 nohup 命令 完整的命令是 nohup java jar home jar server process 0 35 jar prod gt gt var
  • 从 Python 调用 PARI/GP

    我想打电话PARI GP http pari math u bordeaux fr dochtml gpman html仅从Python计算函数nextprime n 对于不同的n是我定义的 不幸的是我无法得到帕里蟒蛇 http code
  • 如何有效截断文件头?

    大家都知道truncate file size 函数 通过截断文件尾部将文件大小更改为给定大小 但是如何做同样的事情 只截断文件的尾部和头部呢 通常 您必须重写整个文件 最简单的方法是跳过前几个字节 将其他所有内容复制到临时文件中 并在完成
  • nslookup 报告“无法解析 '(null)': 名称无法解析”,尽管它成功解析了 DNS 名称

    我在 ubuntu 上 并且正在运行 docker 默认桥接网络 我有 Zookeeper kafka 的容器化版本 以及我编写的与 kafka 对话的应用程序 I do a docker exec it
  • arm64和armhf有什么区别?

    Raspberry Pi Type 3 具有 64 位 CPU 但其架构不是arm64 but armhf 有什么区别arm64 and armhf armhf代表 arm hard float 是给定的名称Debian 端口 https
  • Discord.net 无法在 Linux 上运行

    我正在尝试让在 Linux VPS 上运行的 Discord net 中编码的不和谐机器人 我通过单声道运行 但我不断收到此错误 Unhandled Exception System Exception Connection lost at
  • 如何在 Linux shell 中将十六进制转换为 ASCII 字符?

    假设我有一个字符串5a 这是 ASCII 字母的十六进制表示Z 我需要找到一个 Linux shell 命令 它将接受一个十六进制字符串并输出该十六进制字符串代表的 ASCII 字符 所以如果我这样做 echo 5a command im

随机推荐

  • MarkDown的语法

    使用MarkDoown时应该注意些什么呢 目录 一 添加标题 二 引用代码块 三 嵌入图片 1 本地图片 2 互联网图片 四 快捷键使用 五 分界线的使用 一 添加标题 在文字前加入相应数量的 一级标题 二级标题 三级标题 四级标题 五级标
  • python试爬李毅吧贴子标题,爬虫最初级

    注 xff1a 以下所有python代码均运行于2 7 0 最近想抓点数据存起来 xff0c 开始捣鼓python 爬虫技术以前没接触过 xff0c 这一回就当练手 xff0c 从零开始 xff0c 从最原始的方式开始 先定个小目标 xff
  • Activity的生命周期

    图来自百度百科 onCreate 启动activity时被调用 xff0c 用于进行初始化操作 xff08 加载布局 绑定事件等 xff09 xff0c 不应在onCreate 中做过多的不必要操作 xff0c 避免造成打开activity
  • Activity的启动模式

    以下为读书笔记 xff1a 实际项目中 xff0c 我们要通过特定的需求 xff0c 为每个活动指定恰当的启动模式 Android一共有4种启动模式 xff1a standard singleTop singleTask singleIns
  • PID参数 Ziegler-Nichols基于时域响应曲线的整定 反应曲线法

    PID控制器是工业过程控制中广泛采用的一种控制器 xff0c 其中 xff0c P I D分别为比例 xff08 Proportion xff09 积分 xff08 Integral xff09 微分 xff08 Differential
  • 郑学坚《微型计算机原理及应用》考点精讲 36讲

    链接 xff1a https pan baidu com s 12 vGBRrjOd UtO8P4e9bow 提取码 xff1a tqmp 当初考研时买的网课 xff0c 现在也用不着了 xff0c 赠与有缘人 书籍记录着别人多年时光总结出
  • 几种常用排序算法

    排序算法代码如下 xff1a void Sort Algorithm Bubble Sort int amp nums const int len bool haschange 61 true for int i 61 0 i lt len
  • 四旋翼姿态解算

    代码思路如下 xff1a 姿态解算 void IMU update float dT imu state st state float gyr VEC XYZ s32 acc VEC XYZ s16 mag val VEC XYZ imu
  • 树莓派4B-基于MCP2515的CAN通信过程记录篇

    本文主要记录使用树莓派4B xff0c 通过外接MCP2515模块来实现CAN通信 xff0c 使用基于Can utils实现CAN消息的收发 准备工作 xff1a 树莓派MCP2515模块杜邦线若干 知乎上一篇较为详细的参考 xff0c
  • nuxt踩坑集

    目录结构 assets 资源文件 用于组织未编译的静态资源如 LESS SASS或 JavaScript components 组件 layouts page 模板页面 xff0c 默认为 default vue可以在这个目录下创建全局页面
  • 记录个人在安装D435i驱动时出现的问题及解决方案

    目录 1 驱动安装 xff1a 2 启动Intel RealSense Viewer后报错No Frames Recevied 3 Record时报错Error opening file 1 驱动安装 xff1a 参考这篇博客 xff1a
  • 深度学习常见的优化算法

    文章目录 1 梯度下降算法 xff08 batch gradient descent BGD 2 随机梯度下降法 xff08 Stochastic gradient descent SGD 3 小批量梯度下降 Mini batch grad
  • vscode如何链接github

    1 首先安装配置好vscode xff1a https code visualstudio com download 然后下载git xff1a https git scm com download 根据自己的电脑选择相应的版本的下载就好了
  • 串口(uart)开发流程

    UART概述 UART全称 xff0c Universal Asynchronous Receiver and Transmitter UART xff0c 一般是每个单片机或开发板必备的一个功能模块 xff0c 可以用来调试 xff0c
  • *33.硬中断和软中断是什么?区别?

    1 硬中断 硬件中断 像磁盘 xff0c 网卡 xff0c 键盘 xff0c 时钟等 2 软中断 软件中断 进程产生 区别 xff1a xff08 产生机制 处理顺序 可否屏蔽 中断信号由来 xff09 1 软中断的发生的时间是由程序控制的
  • gazebo学习时遇到的问题(PX4篇)

    最近在研究如何使用UAV xff0c 由于是初学者 xff0c 不好直接上手实体无人机 xff0c 因此考虑通过在gazebo中模拟的方式进行一下无人机的简单使用模拟 xff0c 于是了解到了PX4这个东西 xff0c 他不仅支持固件写入
  • 阿里云服务器的搭建和部署(小白教程)

    阿里云服务器的搭建和部署 xff08 小白教程 xff09 一 购买服务器二 管理云服务器三 环境配置1 JDK的配置与下载2 tomcat的配置与下载3 MySQL的安装与配置 四 外网访问服务器 个人推荐阿里云 因为里面有一个大学生的云
  • 一篇带你搞懂Python3 中的 def __init__

    在学习python 100 days时 xff0c 在面向对象编程基础的那一块 xff0c 封装一个class时 xff0c 突然出现def init 的方法 xff0c 刚开始时 xff0c 对他的理解很模糊 xff0c 为什么定义一个类
  • 时间序列异常检测综述

    1 Introduction 时序异常检测几个可以运用的点 xff1a 1 欺诈检测 2 工业数据检测 简介一下 xff1a 异常检测很久之前就有了 最早可以追溯到 J Fox 1972 Outliers in Time Series Jo
  • Linux基础----Makefile(1)

    前言 刚开始学习Linux xff0c 这些那真的是新知识 xff0c 由于感觉将来FPGA的学习会越来越靠近软件的方向发展 xff0c 所以觉得有必要好好地学习一下嵌入式的东西 xff0c 因此有必要把学习的过程记录下来 xff0c 方便