首页 > 其他分享 >Makefile简单学习

Makefile简单学习

时间:2024-12-20 10:58:57浏览次数:5  
标签:文件 gcc Makefile 目标 学习 add 简单 main

Makefile简单学习

什么是Makefile?

一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令.

为什么要使用Makefile?

就像前面提到的,一个工程的源文件可能不计其数,编写makefile,使用make命令来构建工程,会使原本复杂繁琐的工作简化许多,极大地提高了效率。

Makefile 基础结构

一个典型的 Makefile 由规则(rules)组成,每个规则描述了如何生成特定的目标文件。规则的一般格式如下:

target: dependencies...
    command1
    command2
    ...
  • target:目标文件,可以是可执行文件、库文件或中间目标(如 .o 文件)。通常,第一个目标被视为默认目标。
  • dependencies:依赖文件,列出生成目标所需的文件(通常是源文件或其他目标文件)。
  • command:命令行指令,告诉 make 如何从依赖文件生成目标文件。注意每条命令前必须有制表符(不是空格),这是 Makefile 的语法要求。

下面来看一个具体的例子:

首先建立三个文件

add.c文件

int add(int a, int b)
{
    return a + b;
}

fun.h文件

#ifndef FUN_H
#define FUN_H

#include <stdio.h>

int add(int a, int b);

#endif // FUN_H

main.c文件

#include "fun.h"

int main()
{
    int a = 12, b = 6, c;

    c = add(a, b);
    printf("%d\n", c);

    return 0;
}

makefile中的内容

add: main.o add.o
    gcc -o add main.o add.o

main.o: main.c fun.h
    gcc -c main.c

add.o: add.c
    gcc -c add.c

clean:
    rm -f main.o add.o add

使用过程可能碰到的错误

在我通过make命令后发生报错: Makefile:2:*** missing separator. Stop.

在这里插入图片描述

这个是编辑 makefile 时出现格式错误

使用vim编译器进入makefile文件中调整格式就好了

在这里插入图片描述

如果是正确的格式,命令行的颜色会不一样

注:紫色命令行的前面只用了一个(tab)

解决这个问题后再次使用make命令

在这里插入图片描述

使用成功

讲解

Makefile 基础结构

一个典型的 Makefile 由规则(rules)组成,每个规则描述了如何生成特定的目标文件。规则的一般格式如下:

target: dependencies...
    command1
    command2
    ...
  • target:目标文件,可以是可执行文件、库文件或中间目标(如 .o 文件)。通常,第一个目标被视为默认目标。
  • dependencies:依赖文件,列出生成目标所需的文件(通常是源文件或其他目标文件)。
  • command:命令行指令,告诉 make 如何从依赖文件生成目标文件。注意每条命令前必须有制表符(不是空格),这是 Makefile 的语法要求。

示例 Makefile 分析

我们来看一下你提供的 Makefile 并进行解释:

add: main.o add.o
    gcc -o add main.o add.o

main.o: main.c fun.h
    gcc -c main.c

add.o: add.c
    gcc -c add.c

clean:
    rm -f main.o add.o add
目标 add
add: main.o add.o
    gcc -o add main.o add.o
  • 这个规则说明了如何创建最终的可执行文件 add
  • 它依赖于两个对象文件 main.oadd.o
  • 如果这两个文件中的任何一个比 add 更新(即它们在最近被修改过),或者 add 不存在,那么就会运行后面的命令来创建 add
目标 main.o
main.o: main.c fun.h
    gcc -c main.c
  • 这个规则定义了如何创建 main.o
  • 它依赖于 main.cfun.h,这意味着如果 main.cfun.h 发生变化,main.o 就需要重新编译。
  • -c 选项告诉 GCC 只编译不链接,生成 .o 文件。
目标 add.o
add.o: add.c
    gcc -c add.c
  • 类似地,这个规则定义了如何创建 add.o
  • 它仅依赖于 add.c,因此如果 add.c 发生变化,add.o 需要重新编译。
特殊目标 clean
clean:
    rm -f main.o add.o add
  • clean 不是一个普通的目标,而是一种约定俗成的特殊目标,用来清理生成的文件。
  • 运行 make clean 会删除所有由构建过程生成的文件,包括目标文件和可执行文件,使项目回到初始状态。
  • -f 选项用于 rm 命令,表示即使文件不存在也不会报错。

Makefile 的其他重要特性

  • 变量:可以在 Makefile 中定义变量以存储常用的路径或命令。例如:

    CC = gcc
    CFLAGS = -Wall -g
    OBJS = main.o add.o
    
    add: $(OBJS)
        $(CC) -o add $(OBJS)
    
    %.o: %.c
        $(CC) $(CFLAGS) -c $< -o $@
    

    这里使用了变量 CC, CFLAGS, 和 OBJS 来简化命令,并且引入了模式规则(pattern rule)%.o: %.c,它告诉 make 如何根据 .c 文件创建相应的 .o 文件。

  • 隐式规则:GNU Make 支持许多隐式规则,这些规则允许你在没有显式指定规则的情况下自动处理常见的任务。例如,如果你有一个 .c 文件但没有为对应的 .o 文件编写规则,make 仍然知道如何编译它。

  • 函数:Make 提供了一些内置函数,如 $(wildcard *.c) 用于匹配文件名,$(patsubst %.c,%.o,$(SRCS)) 用于替换文件扩展名等。

  • 条件语句:可以使用 ifeq, ifneq, ifdef, 和 ifndef 来实现条件逻辑。

  • 包含其他 Makefile:可以使用 include 指令来包含其他的 Makefile 文件,这有助于组织大型项目的构建脚本。

提供了一些内置函数,如 $(wildcard *.c) 用于匹配文件名,$(patsubst %.c,%.o,$(SRCS)) 用于替换文件扩展名等。

  • 条件语句:可以使用 ifeq, ifneq, ifdef, 和 ifndef 来实现条件逻辑。

  • 包含其他 Makefile:可以使用 include 指令来包含其他的 Makefile 文件,这有助于组织大型项目的构建脚本。

通过理解和正确运用这些特性,你可以创建更加复杂和灵活的 Makefile,从而更高效地管理项目的构建过程。

标签:文件,gcc,Makefile,目标,学习,add,简单,main
From: https://blog.csdn.net/uifmlj/article/details/144596115

相关文章

  • 【Java学习笔记】多线程基础
    并行:同一时刻,多任务同时进行多任务分别进行一、线程相关概念1.程序是为完成特定任务、用某种语言编写的一组指令的集合。简单的说:就是我们写的代码2.进程(1)进程指的就是运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存空间。当我们使用迅......
  • 2024-2025-1 20241305 《计算机基础和程序设计》第十三周学习总结
    作业信息这个作业属于哪个课程2024-2025-1-计算机基础与程序设计](https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP)这个作业要求在哪里2024-2025-1计算机基础与程序设计第十三周作业这个作业的目标《C语言程序设计》第12章并完成云班课测试作业正文本......
  • 简单视频直播实现
    需求描述现在内网上有一个摄像头,上位机可以访问到该摄像头(上位机可以通过网线或wifi的形式连接到外网,但无公网ip),需要构建一个服务可以对该摄像头进行画面直播。解决方案根据需求,网络架构大致如下:Cam->PC->Server->Client其中关键问题就是打通PC->Server的联通其实列出上面的......
  • Excel制作星级评分图,只需简单几步!
    大家好,我是小鱼。    今天跟大家分享的是如何使用Excel制作星级评分图的方法技巧,告别单调数据,让你的数据报表瞬间高大上!如下图所示,这是根据员工评分通过简单的公式和条件格式制作星级评分图。一、星级评分图原理说明    我们还是以上图为例,客服员工的评分......
  • 深度可分离卷积原理分析回顾、代码实践与优缺点对比学习记录
    最近在项目开发中有需要用到轻量化相关的内容,那必定是绕不开深度可分离卷积的,这里记录自己的学习记录和实践内容。深度可分离卷积(DepthwiseSeparableConvolution)是一种轻量化的卷积操作,广泛应用于移动设备和嵌入式设备上的深度学习模型(如MobileNet和Xception)。它将标准......
  • Java学习,数组中查找指定元素
    Java中查找数组中的指定元素是一个常见的操作。数组中查找指定的元素,并返索引:publicclassFindElementInArray{  publicstaticvoidmain(String[]args){    int[]numbers={10,20,30,40,50};    inttarget=30;    intindex......
  • Java学习,数组是否相等
    Java中判断两个数组是否相等,不是直接的事情,数组对象之间的 equals()方法,并不会逐个比较数组元素,是比较数组对象的引用是否相同(即它们是否指向内存中同一个位置)。要判断两个数组,是否包含相同的元素并且顺序也相同。判断两个整数数组是否相等publicclassArrayEqualityChecke......
  • 【机器学习】数据分析之Pandas(一)
    pandas数据分析库第一部分介绍Python在数据处理和准备方面一直做得很好,但在数据分析和建模方面就差一些。pandas帮助填补了这一空白,使您能够在Python中执行整个数据分析工作流程,而不必切换到更特定于领域的语言,如R。与出色的jupyter工具包和其他库相结合,Python中用于进......
  • 深度学习-1218
    1.nn.functional今天学nn中一个很常用的模块:nn.functional,nn中的大多数layer,在functional中都有一个对应的函数。nn.functional中的函数和nn.Module的主要区别在于:用nn.Module实现的layer是一个特殊的类,都是由calsslayer(nn.Module)定义的,会自动提取可学习的参数。用nn.fu......
  • URP - 最简单的不受光(unlit)shader
     Shader"My/URP_Unlit"{Properties{_MainTex("Texture",2D)="white"{}}SubShader{Tags{"RenderPipeline"="UniversalPipeline"//这是用于URP的shader......