手动建立makefile简单实例解析!

手动建立makefile简单实例解析 假设我们有一个程序由5个文件组成,源代码如下:/*main.c*/#include "mytool1.h"#include "mytool2.h"int main(){        mytool1_print("hello mytool1!");        mytool2_print("hello mytool2!");        return 0;}  /*my 阅读详情

假设我们有一个程序由5个文件组成,源代码如下:

/*main.c*/

#include 
"mytool1.h"
#include 
"mytool2.h"

int main()
{
        mytool1_print(
"hello mytool1!");
        mytool2_print(
"hello mytool2!");
        
return 0;
}

  

/*mytool1.c*/

#include 
"mytool1.h"
#include 
<stdio.h>

void mytool1_print(char *print_str)
{
        printf(
"This is mytool1 print : %s ",print_str);
}

 

/*mytool1.h*/

#ifndef _MYTOOL_1_H
#define _MYTOOL_1_H
        
void mytool1_print(char *print_str);
#endif

 

/*mytool2.c*/

#include 
"mytool2.h"
#include 
<stdio.h>

void mytool2_print(char *print_str)
{
        printf(
"This is mytool2 print : %s ",print_str);
}

 

/*mytool2.h*/

#ifndef _MYTOOL_2_H
#define _MYTOOL_2_H
        
void mytool2_print(char *print_str);
#endif

    首先了解一下make和Makefile。GNU make是一个工程管理器,它可以管理较多的文件。我所使用的RedHat 9.0的make版本为GNU Make version 3.79.1。使用make的最大好处就是实现了“自动化编译”。如果有一个上百个文件的代码构成的项目,其中一个或者几个文件进行了修改,make就能够自动识别更新了的文件代码,不需要输入冗长的命令行就可以完成最后的编译工作。make执行时,自动寻找Makefile(makefile)文件,然后执行编译工作。所以我们需要编写Makefile文件,这样可以提高实际项目的工作效率。

    在一个Makefile中通常包含下面内容:

1、需要由make工具创建的目标体(target),通常是目标文件或可执行文件。
2、要创建的目标体所依赖的文件(dependency_file)。
3、创建每个目标体时需要运行的命令(command)。

格式如下:

 target:dependency_files
<TAB>command

target:规则的目标。通常是程序中间或者最后需要生成的文件名,可以是.o文件、也可以是最后的可执行程序的文件名。另外,目标也可以是一个make执行的动作的名称,如目标“clean”,这样的目标称为“伪目标”。

dependency_files:规则的依赖。生成规则目标所需要的文件名列表。通常一个目标依赖于一个或者多个文件。


command:规则的命令行。是make程序所有执行的动作(任意的shell命令或者可在shell下执行的程序)。一个规则可以有多个命令行,每一条命令占一行。注意:每一个命令行必须以[Tab]字符开始,[Tab]字符告诉make此行是一个命令行。make按照命令完成相应的动作。这也是书写Makefile中容易产生,而且比较隐蔽的错误。命令就是在任何一个目标的依赖文件发生变化后重建目标的动作描述。一个目标可以没有依赖而只有动作(指定的命令)。比如Makefile中的目标“clean”,此目标没有依赖,只有命令。它所指定的命令用来删除make过程产生的中间文件(清理工作)。


在Makefile中“规则”就是描述在什么情况下、如何重建规则的目标文件,通常规则中包括了目标的依赖关系(目标的依赖文件)和重建目标的命令。make执行重建目标的命令,来创建或者重建规则的目标(此目标文件也可以是触发这个规则的上一个规则中的依赖文件)。规则包含了目标和依赖的关系以及更新目标所要求的命令。
Makefile中可以包含除规则以外的部分。一个最简单的Makefile可能只包含规则描述。规则在有些Makefile中可能看起来非常复杂,但是无论规则的书写是多么的复杂,它都符合规则的基本格式。

下面就可以写出第一个Makefile了。

main:main.o mytool1.o mytool2.o
        gcc 
-o main main.o mytool1.o mytool2.o
main.o:main.c mytool1.h mytool2.h
        gcc 
-c main.c
mytool1.o:mytool1.c mytool1.h
        gcc 
-c mytool1.c
mytool2.o:mytool2.c mytool2.h
        gcc 
-c mytool2.c

clean:
        rm 
-f *.o main

在shell提示符下输入make,执行显示:

gcc -c main.c
gcc 
-c mytool1.c
gcc 
-c mytool2.c
gcc 
-o main main.o mytool1.o mytool2.o

执行结果如下:

[armlinux@lqm makefile-easy]$ ./main
This 
is mytool1 print : hello mytool1!
This 
is mytool2 print : hello mytool2!

这只是最为初级的Makefile,现在来对这个Makefile进行改进。

改进一:使用变量

一般在书写Makefile时,各部分变量引用的格式如下:
1. make变量(Makefile中定义的或者是make的环境变量)的引用使用“$(VAR)”格式,无论“VAR”是单字符变量名还是多字符变量名。
2. 出现在规则命令行中shell变量(一般为执行命令过程中的临时变量,它不属于Makefile变量,而是一个shell变量)引用使用shell的“$tmp”格式。
3. 对出现在命令行中的make变量同样使用“$(CMDVAR)” 格式来引用。

OBJ=main.o mytool1.o mytool2.o

make:$(OBJ)
        gcc 
-o main $(OBJ)
main.o:main.c mytool1.h mytool2.h
        gcc 
-c main.c
mytool1.o:mytool1.c mytool1.h
        gcc 
-c mytool1.c
mytool2.o:mytool2.c mytool2.h
        gcc 
-c mytool2.c

clean:
        rm 
-f main $(OBJ)

改进二:使用自动推导

让make自动推导,只要make看到一个.o文件,它就会自动的把对应的.c文件加到依赖文件中,并且gcc -c  .c也会被推导出来,所以Makefile就简化了。

CC = gcc
OBJ 
= main.o mytool1.o mytool2.o

make: $(OBJ)
        $(CC) 
-o main $(OBJ)

main.o: mytool1.h mytool2.h
mytool1.o: mytool1.h
mytool2.o: mytool2.h

.PHONY: clean
clean:
        rm 
-f main $(OBJ)

改进三:自动变量($^  $<  $@)的应用

Makefile 有三个非常有用的变量,分别是$@、$^、$<。代表的意义分别是:
$@--目标文件,
$^--所有的依赖文件,
$<--第一个依赖文件。

CC = gcc
OBJ 
= main.o mytool1.o mytool2.o

main: $(OBJ)
        $(CC) 
-o $@ $^

main.o: main.c mytool1.h mytool2.h
        $(CC) 
-c $<
mytool1.o: mytool1.c mytool1.h
        $(CC) 
-c $<
mytool2.o: mytool2.c mytool2.h
        $(CC) 
-c $<

.PHONY: clean
clean:
        rm 
-f main $(OBJ)

     这些是最为初级的知识,现在至少可以减少编译时的工作量。细节方面的东西还需要在以后的工作和学习中不断的总结,不断的深化理解。可以 参考GNU Make手册,这里讲解的比较全面。


计算机组成原理(第三版)唐朔飞-第六章计算机的运算方法-课后习题(1-16) 阅读详情

相关推荐

io_uring vs epoll ,谁在网络编程领域更胜一筹?

简介:从定量分析的角度,通过量化 io_uring 和 epoll 两种编程框架下的相关操作的耗时,来分析二者的性能差异。 本文作者:王小光,「高性能存储技术SIG」核心成员。 背景 io_uring 在传统存储 io 场景已经证明其价值,但 io_uring 不仅支持传统存储 io,也支持网络 io。io_uring 社区有众多的开发者尝试将 io_uring 用于网络应用。我们之前也在《你认为 io_uring 只适用于存储 IO?大错特错!》中也探索过 io_uring 在网络场景的应用及其

阿里云云栖号 3035

linux 下c 编译和调试

hi,最近我在学习在linux下编写和调试c程序。现总结一下,和大家一起学习交流。 在linux下编写和调试c程序的环境搭建: 需要安装gcc编译器和gdb调试器。其中gcc编译器只能用rpm包或者用linux的安装盘里的gcc安装文件安装。查看是否安装gcc可用gcc -v来显示相关gcc信息,如显示如下内容: 则说明你的linux安装了gcc  同样用gdb -v来检测

bahutou, 嵌入式系统解决方案 4618

一文解读DeepSeek训练数据集

本文重点以DeepSeek为例,详细介绍预训练数据集相关内容。大语言模型LLM(如DeepSeek、ChatGPT、文心一言等)的“智慧”源于它们学习的海量数据集。简单来说,数据集就是模型的“知识库”,通常由互联网公开的文本、图片、视频等。这些数据需满足两个特点:规模大和多样性。规模大是指数据量可达千亿级词汇,让模型学习复杂规律;多样性则涵盖多领域(如科技、文学)、多语言、多形式(对话、新闻),帮助模型适应不同场景。例如,训练数据中既有百科知识,也有日常对话,模型才能既解答专业问题,又能闲聊。

u013891230的博客 7087

c语言编程ge,Linux下C语言编程基础知识

1.源程序的编译在Linux下面,如果要编译一个C语言源程序,我们要使用GNU的gcc编译器.下面我们以一个实例来说明如何使用gcc编译器.假设我们有下面一个非常简单的源程序(hello.c):int main(int argc,char **argv){printf(Hello Linuxn);}要编译这个程序,我们只要在命令行下执行:gcc -o hello hello.cgcc编译器就会为我...

weixin_32258195的博客 393

保姆级教程:用SNAP处理哨兵一号数据,5步搞定城区范围提取(附江西晋城案例)

本文提供了一份详细的保姆级教程,介绍如何使用SNAP软件处理哨兵一号数据,通过5个关键步骤快速提取城区范围。以江西晋城为例,教程涵盖数据准备、预处理、核心处理流程、自动化搭建及成果分析,帮助用户轻松掌握SNAP操作技巧,适用于城市规划、环境监测等领域。

weixin_32535389的博客 453

万字长文告诉新手如何学习Python图像处理(上篇完结 四十四) | 「Python」有奖征文

这篇文章是图像处理的最后一篇文章,后面我们将进入新的章节。图像处理文章主要讲解的图像处理方法包括图像几何运算、图像量化采样、图像点运算、图像形态学处理、图像增强、图像平滑、图像锐化、图像特效、图像分割、傅里叶变换与霍夫变换、图像分类等。个人感觉如果你是编程初学者、Python初学者或图像处理爱好者,这个系列真心适合你学习,并且这篇文章算是Python图像处理的学习路线,希望您喜欢。

杨秀璋的专栏 2万+

Makefile简单使用

此文章为学习韦东山嵌入式Linux教程学习所做笔记 gcc的编译器的使用 一个C/C++文件要经过预处理,编译,汇编和链接等四步才可以变成可执行文件 1.预处理 .c/.cpp xx-gcc -E -o hello.i hello.c 2.编译(cc1命令可以完成1.2两步) .i xx-gcc -S -o hello.s hello.i 3.汇编(as命令) .s xx-gcc -c -o hello.o hello.s 4.链接(collect2命令) .o xx.

weixin_43824344的博客 570

【RTD】AD7793两线式铂电阻PT100/PT1000应用

两线式RTD是低成本的检测方案,适用于检测精度不高、导线长度较短的场合。

只要思想不滑坡,想法总比问题多。 4258

5.Makefile简单使用实例

目录 1.什么是Makefile? 2.Makefile引入 3.Makefile的基本规则 4.Makefile实例 5.Makefile简单语法 6.Makefile 函数      6.1.foreach 函数      6.2.过滤函数 -filter      6.3.获取匹配模式文件名函数— wildcard      6.4.模式替换函数— patsubst  ...

广源的博客 1万+

主题033:燃烧反应工程

燃烧反应工程(Combustion Reaction Engineering)是研究燃料与氧化剂发生剧烈氧化反应的科学,涉及化学反应动力学、流体力学、传热传质等多个学科。燃烧是人类利用能源的主要方式,广泛应用于发电、交通运输、工业加热等领域。燃烧反应通常通过自由基链式反应进行。链引发:RH+O2⟶R⋅+HO2⋅ RH + O_2 \longrightarrow R^\cdot + HO_2^\cdot RH+O2​⟶R⋅+HO2⋅​链传递:R⋅+O2⟶RO2⋅ R^\cdot + O_2 \longrigh

kkchenjj的博客 231

【制作100个Unity游戏之36】用unity从零开始实现类《开心消消乐》的三消类消除解压小游戏

Unity甜品消除游戏开发摘要 本文介绍了使用Unity开发甜品消除游戏的核心实现步骤: 冰块阵列生成 通过GlobalDef定义全局参数(9行7列网格) IceSpawner脚本动态生成网格化冰块阵列 添加Resolution脚本实现多分辨率适配 随机水果生成 创建FruitSpawner作为水果容器 FruitItem脚本管理水果属性(行列索引、类型) 支持动态创建水果精灵并设置位置 关键技术点 使用Instantiate动态生成预制体 通过localPosition精确控制网格布局 分辨率适配算法保持

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 1291

使用autotools建立Makefile简单实例解析

<br />本文中使用的实例仍为《手动建立makefile简单实例解析》中的5文件工程实例。<br />对于一个较大的项目而言,完全手动建立Makefile是一件费力而又容易出错的工作。autotools系列工具只需用户输入简单的目标文件、依 赖文件、文件目录等就可以比较轻松地生成Makefile了。现在Linux上的软件开发一般都是用autotools来制作Makefile。<br />autotools工具主要有:aclocal、autoscan、autoconf、autoheader、automak

anzhu_111的专栏 822

远程声控系统(MATLAB代码见优快云资源)

远程声控系统技术报告 一、题目要求 实现一个远程声音控制系统。首先采集不同的语音指示信号,进行适当压缩;然后通过噪声信道实现远程传输,远端接收后再通过适当计算识别出是何指示,最后送入一个处于未知状态、但能控/能观的控制系统,完成不同的控制动作。 二、问题分解与解决思路 2.1 系统设计 实验中以汉语数字语音1~9作为指令,数字语音“1”代表一号指令,数字语音“2”代表二号指令,依次类推。发送端发出语音“1”,发送端对应的数字语音文件为“1b.wav”,通过信源编码对语音进行压缩编码,然后进行信道编码并进行基

业精于勤,荒于嬉 5734

手动建立makefile简单实例解析(转载)

手动建立makefile简单实例解析(转载)  假设我们有一个程序由5个文件组成,源代码如下: [cpp] view plaincopyprint? /*main.c*/  #include "mytool1.h"   #include "mytool2.h"   int main()  {      mytool1_print("hello mytool

Plain的专栏 632

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

(MAKE)手动建立makefile简单实例解析

假设我们有一个程序由5个文件组成,源代码如下: /*main.c*/ #include "mytool1.h" #include "mytool2.h" int main() {          mytool1_print("hello mytool1!");          mytool2_print("hello mytool2!");         retu

杰哥的专栏 1037

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

上一篇: Linker Script,LMA,VMA
下一篇: uboot之start.s分析
小文兄弟
博客等级 码龄17年 28粉丝 18原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值