【Linux】Linux下的自动化构建工具——make/makefile

2023-11-18


需要云服务器等云产品来学习Linux的同学可以移步/-->腾讯云<--/-->阿里云<--/-->华为云<--/官网,轻量型云服务器低至112元/年,新用户首次下单享超低折扣。 


目录

一、make和makefile的区别

二、makefile的原理

1、make的原理详解

2、临时文件的清理

3、文件的三个时间

三、makefile的推导规则

四、实现一个进度条

1、缓冲区问题

2、实现倒计时程序

3、进度条的实现


一、make和makefile的区别

make是一个命令,makefile是一个文件。

二、makefile的原理

1、makefile的原理详解

每次生成可执行文件时需要输入一长串的gcc········指令是不是感觉很麻烦?makefile存在的意义是为了项目的构建。需要表明依赖关系和依赖方法。

2、临时文件的清理

mycode:mycode.c
	gcc mycode.c -o mycode -g
.PHONY:clean                                                                                               
clean:
	rm -f mycode

-g代表可被调试。 

mycode:mycode.c
	gcc -o $@ $^
.PHONY:clean                                                                                               
clean:
	rm -f mycode

$@代表生成的目标文件mycode,$^代表依赖文件mycode.c 。

.PHONY表示被该关键字修饰的对象是一个伪目标。(该伪目标总是可被执行)

我们在编写完makefile后,make一下,就能生成对应的可执行程序。如果依赖的文件列表没有发生修改,gcc通过判断mycode.c的Modify time早于mycode的Modify time,说明依赖文件列表没有修改,那么再次make将会失败;反之,重新编译将会成功。

不过多次make clean却不会失败,因为clean被.PHONY修饰,变成了一个伪目标,所以clean总是可被执行。

.c位于不同目录写法,生成.o文件:

obj=mycode.o add.o sub.o
mycode:$(obj)
    gcc -o $@ $^
%.o:%.c          
    gcc -c $<
%.o:./test_lib/%.c
    gcc -c $<
.PHONY:clean
clean:
    rm -f *.o mycode删掉所有.o和mycode

%是通配符,%.o表示将当前目录下的.o目标文件全部展开。

$<表示将%.c展开,一个一个进行编译,上方代码没有指明-o,将会形成同名.o。

3、文件的三个时间

[root@VM-4-11-centos ~]# stat 106/test.c
  File: ‘106/test.c’
  Size: 0         	Blocks: 0          IO Block: 4096   regular empty file
Device: fd01h/64769d	Inode: 658416      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2022-09-17 21:13:21.098656019 +0800//最近访问
Modify: 2022-09-17 21:13:21.098656019 +0800//最近修改
Change: 2022-09-17 21:13:21.098656019 +0800//最近改动
 Birth: -

1、读取文件时,Access time被改变,而Modify、Change time不会被改变(为防止文件被频繁访问修改Access time,优化为多次访问才修改一次该时间)

2、修改文件时,三个时间都会被改变

3、修改属性时,Change time被改变,而Access、Modify time不会被改变

三、makefile的推导规则

makefile会自己逐步寻找依赖文件列表,如果没找到对于依赖文件,将会继续向下寻找该依赖文件的依赖方法。

四、实现一个进度条

1、缓冲区问题

#include <stdio.h>    
#include <unistd.h>    
int main()    
{    
    printf("hello world\n");//如果这里没有\n,程序将会在3秒后执行打印
    //fflush(stdout);//fflush会立即刷新缓冲区
    sleep(3);    
    return 0;    
}   

因为\n才会刷新缓冲区(\r等不会),这个程序printf执行完之后,将会休眠3秒,如果没有\n或者fflush手动刷新缓冲区,hello world将会存放至缓冲区,程序结束后才执行打印。

2、实现倒计时程序

#include <stdio.h>    
#include <unistd.h>    
int main()    
{    
    int cnt=10;    
    while(cnt)    
    {    
        printf("%2d\r",cnt);//2d控制刷新两位,\r表示回车                                                                                   
        fflush(stdout);//手动刷新缓冲区   
        sleep(1);    
        --cnt;    
    }    
    return 0;    
}  

能够实现从10到计时的程序。

3、进度条的实现

//.h文件    
#pragma once                                                                                               
#include <stdio.h>                                                          
#include <unistd.h>                                          
#include <string.h>                                                                                                                       
#define NUM 101                                                                      
#define STYLE '*'                                                                               
extern void processOn(); 
//.c文件
#include "process.h"                                                                                           
void processOn()    
{    
    int cnt=0;    
    char bar[NUM];    
    memset(bar,'\0',NUM);    
    char type[4]={'|','/','-','\\'};    
    while(cnt<=100)    
    {    
        //-100表示占据屏幕100个空间并左对齐,%%转义为%
        printf("[%-100s][%d%%][%c]\r",bar,cnt,type[cnt%4]);   
        bar[cnt++]=STYLE;    
        fflush(stdout);    
        usleep(50000);    
    }    
    printf("\n");    
} 

makefile中不用写头文件,编译器自己会去找。

<>查找方式:直接去库目录下查找,如果找不到,报编译错误;

""查找方式:先去代码所在的路径下查找,如果找不到,再去库目录下查找,如果找不到,报编译错误。

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

【Linux】Linux下的自动化构建工具——make/makefile 的相关文章

  • 在 Linux 上使用多处理时,TKinter 窗口不会出现

    我想生成另一个进程来异步显示错误消息 同时应用程序的其余部分继续 我正在使用multiprocessingPython 2 6 中的模块来创建进程 我试图用以下命令显示窗口TKinter 这段代码在Windows上运行良好 但在Linux上
  • 如何通过保持目录结构完整来同步路径中匹配模式的文件?

    我想将所有文件从服务器 A 复制到服务器 B 这些文件在不同级别的文件系统层次结构中具有相同的父目录名称 例如 var lib data sub1 sub2 commonname filetobecopied foo var lib dat
  • 如何授予 apache 使用 NTFS 分区上的目录的权限?

    我在一台带有 20GB 硬盘的旧机器上运行 Linux Lubutu 12 10 我有一个 1 TB 外部硬盘 上面有一个 NTFS 分区 在该分区上 有一个 www 目录 用于保存我的网页内容 它在启动时自动安装为 media t515
  • 多处理:仅使用物理核心?

    我有一个函数foo它消耗大量内存 我想并行运行多个实例 假设我有一个有 4 个物理核心的 CPU 每个核心有两个逻辑核心 我的系统有足够的内存来容纳 4 个实例foo并行但不是 8 个 此外 由于这 8 个核心中的 4 个是逻辑核心 我也不
  • jq中如何分组?

    这是 json 文档 name bucket1 clusterName cluster1 name bucket2 clusterName cluster1 name bucket3 clusterName cluster2 name bu
  • 查找哪些页面不再与写入时复制共享

    假设我在 Linux 中有一个进程 我从中fork 另一个相同的过程 后forking 因为原始进程将开始写入内存 Linux写时复制机制将为进程提供与分叉进程使用的不同的唯一物理内存页 在执行的某个时刻 我如何知道原始进程的哪些页面已被写
  • 我的线程图像生成应用程序如何将其数据传输到 GUI?

    Mandelbrot 生成器的缓慢多精度实现 线程化 使用 POSIX 线程 Gtk 图形用户界面 我有点失落了 这是我第一次尝试编写线程程序 我实际上并没有尝试转换它的单线程版本 只是尝试实现基本框架 到目前为止它是如何工作的简要描述 M
  • 如何确保应用程序在 Linux 上持续运行

    我试图确保脚本在开发服务器上保持运行 它会整理统计数据并提供网络服务 因此它应该会持续存在 但一天中有几次 它会因未知原因而消失 当我们注意到时 我们只需再次启动它 但这很麻烦 并且某些用户没有权限 或专有技术 来启动它 作为一名程序员 我
  • Gtk-ERROR **:检测到 GTK+ 2.x 符号

    我正在使用 gcc 编译我的 c 应用程序 并使用以下标志 gcc evis c pkg config cflags libs gtk 2 0 libs clutter gtk 1 0 libs gthread 2 0 Wall o evi
  • “make install”将库安装在 /usr/lib 而不是 /usr/lib64

    我正在尝试在 64 位 CentOS 7 2 上构建并安装一个库 为了这个目的我正在跑步 cmake DCMAKE BUILD TYPE Release DCMAKE INSTALL PREFIX usr DCMAKE C COMPILER
  • waitpid() 的作用是什么?

    有什么用waitpid 它通常用于等待特定进程完成 或者如果您使用特殊标志则更改状态 基于其进程 ID 也称为pid 它还可用于等待一组子进程中的任何一个 无论是来自特定进程组的子进程还是当前进程的任何子进程 See here http l
  • 如果在等待“read -s”时中断,在子进程中运行 bash 会破坏 tty 的标准输出吗?

    正如 Bakuriu 在评论中指出的那样 这基本上与BASH 输入期间按 Ctrl C 会中断当前终端 https stackoverflow com questions 31808863 bash ctrlc during input b
  • 确定我可以向文件句柄写入多少内容;将数据从一个 FH 复制到另一个 FH

    如何确定是否可以将给定数量的字节写入文件句柄 实际上是套接字 或者 如何 取消读取 我从其他文件句柄读取的数据 我想要类似的东西 n how much can I write w handle n read r handle buf n a
  • 快速像素绘图库

    我的应用程序以每像素的方式生成 动画 因此我需要有效地绘制它们 我尝试过不同的策略 库 但结果并不令人满意 尤其是在更高分辨率的情况下 这是我尝试过的 SDL 好的 但是慢 OpenGL 像素操作效率低下 xlib 更好 但仍然太慢 svg
  • Fortran gfortran linux 中的“分段错误(核心转储)”错误

    我正在创建一个程序 该程序将分析目录中的文件 fits 然后它将在另一个目录中创建另一个文件 txt 它只是一个转换器 当我尝试执行该程序 编译正常 时 它给了我一条错误消息 程序收到信号 SIGSEGV 分段错误 无效的内存引用 此错误的
  • 捕获实时流量时如何开启纳秒精度?

    如何告诉 libpcap v1 6 2 将纳秒值存储在struct pcap pkthdr ts tv usec 而不是微秒值 捕获实时数据包时 Note This question is similar to How to enable
  • 为什么C Clock()返回0

    我有这样的事情 clock t start end start clock something else end clock printf nClock cycles are d d n start end 我总是得到输出 时钟周期是 0
  • 在 unix 中编译 dhrystone 时出错

    我是使用基准测试和 makefile 的新手 我已经从下面的链接下载了 Dhrystone 基准测试 我正在尝试编译它 但我遇到了奇怪的错误 我尝试解决它 但没有成功 有人可以帮助我运行 dhrystone 基准测试吗 以下是我尝试编译的两
  • 使用 plistBuddy 获取值数组

    var keychain access groups declare a val usr libexec PlistBuddy c Print var sample plist echo val echo val 0 Ouput Array
  • Fedora dnf 更新不起作用?

    当我尝试使用 update 命令更新 Fedora 22 时 sudo dnf update 我收到以下错误 错误 无法同步存储库 更新 的缓存 无法准备内部镜像列表 Curl 错误 6 无法解析主机名 无法解析主机 mirrors fed

随机推荐

  • AI 对抗超级细菌:麦克马斯特大学利用深度学习发现新型抗生素 abaucin

    内容一览 鲍曼不动杆菌是一种常见的医院获得性革兰氏阴性病原体 通常表现出多重耐药性 利用传统方法 发现抑制此菌的新型抗生素很困难 但利用机器学习可以快速探索化学空间 从而增加发现新型抗菌分子的可能性 近期 国际期刊 Nature Chemi
  • Java生成纳秒时间戳

    记一次生成高精度时间戳 类似与 net的时间戳 码着备忘 long timestamp System currentTimeMillis 1000000L System nanoTime 1000000L System currentTim
  • 函数的防抖与节流

    一 防抖与节流的联系 相同点 防抖 Debounce 和节流 Throttle 都是用来控制某个函数在一定时间内触发次数 两者都是为了减少触发频率 以便提高性能以及避免资源浪费 不同点 节流是第一个说了算 后续都会被节流阀屏蔽掉 防抖是最后
  • (小陈c语言)井字棋-初步实现以及改进方向

    作为小学上课偷偷和同桌在草稿本上玩的小游戏 井字棋 如今在电脑上也可以自己写出来玩 如图 不要惊讶 下面我们来看看怎么实现这个代码 正文开始 1 菜单界面 用多个printf 来打印即可 注意中间最好是空的不要连着字 void menu p
  • CVPR2020-RFANet-图像超分辨率新网络

    创新点都比较小 提升也很小 有种炒冷饭的感觉 论文地址 http openaccess thecvf com content CVPR 2020 papers Liu Residual Feature Aggregation Network
  • pycharm GIT 账号密码输入错误如何更改

    pycharm GIT 账号密码输入错误如何更改 第一次在pycharm中 输入git的账户或者密码出现错误 下一次pycharm系统会记住你输入错误的账户和密码 The requested URL returned error 500 只
  • python的日志logging模块使用总结

    文章转载与 http outofmemory cn code snippet 450 python rizhi logging module usage summary 1 简单的将日志打印到屏幕 import logging loggin
  • Android5——活动的生命周期方法

    1 活动的生命周期方法 onCreate 会在活动第一次被创建的时候使用 onStart 会在活动由不可见变为可见的时候调用 OnResume 会在活动准备好和用户进行交互的时候调用 此时的活动一定位于返回栈的栈顶 并且处于运行状态 onP
  • 简单两步解决Python的NLTK库DATA安装问题

    前言 本人使用Anaconda集成开发环境 已经安装有NLTK库 在使用NLTK最简单的分词功能时报错 查询错误 得知是没有安装NLTK的数据包 系统推荐使用以下命令 import nltk nltk download 用了之后弹出窗口 出
  • ROS 第四天 ROS中的关键组件

    1 Launch文件 通过XML文件实现多节点的配置和启动 可自动启动ROS Master
  • word文档中如何添加目录

    如果word文档的内容较多 结构复杂 那么在文档首页设置一个目录链接是非常有必要的 本文将介绍如何添加此目录 1 设置标题 在文档中选择将在目录中显示的内容 将之设置为 标题1 标题2 或 标题3 等 其中 标题1 代表一级标题 应为顶级目
  • 如何在 Java 中调用 MATLAB 代码

    文章目录 测评 完整源代码 运行环境 MATLAB R2022a Java 8 1 8 0 311 IntelliJ IDEA 2022 2 1 Ultimate Edition Maven 3 8 3 Windows 10 教育版 64位
  • ios 删除无用证书

    1 前往文件夹 Library MobileDevice Provisioning Profiles 然后可以删除里面的所有文件 然后就可以根据自己的需求重新下载了
  • STM32之_keil 编译内存大小解析

    Program Size Code 28784 RO data 6480 RW data 60 ZI data 3900 的含义 1 Code 程序所占用的FLASH大小 存储在FLASH 2 RO data Read only data
  • 简单的c++ UDP类 + 多线程 win32编程

    UdpClient h include Thread h class IUdpRecvCallback public virtual void OnRecv const char buf USHORT len const char from
  • 基恩士PLC KV8000+XH16EC总线控制,全ST程序实例

    基恩士PLC KV8000 XH16EC总线控制 全ST程序实例 本人自己开发全程序无加密 公司级框架 功能齐全 提供项目源码框架FB源码 触摸屏源码 需要一定ST基础才能看懂 重在分享编程思想 没用过该控制器的请慎拍 请使用11 10版本
  • 图像的二值化分割,otsu类间方差法

    二值化图像指图像中的每个像素只取两个离散的值之一 用数学公式表示为 公式中 f x y 表示一幅数字图像 X Y表示该图像中某像素的坐标值 T为 二值化的阈值 表示经过阈值运算后的二值化图像 这里0和1仅仅是一个抽象表示 并非实际像素值 它
  • python 实现百度关键字自动爬虫

    coding utf 8 In 3 import requests from lxml import etree import re from sqlalchemy import create engine engine create en
  • IDEA中快捷键大全

    Alt 回车 导入包 自动修正 Ctrl N 查找类 Ctrl Shift N 查找文件 Ctrl Alt L 格式化代码 Ctrl Alt O 优化导入的类和包 Alt Insert 生成代码 如get set方法 构造函数等 Ctrl
  • 【Linux】Linux下的自动化构建工具——make/makefile

    需要云服务器等云产品来学习Linux的同学可以移步 gt 腾讯云 lt gt 阿里云 lt gt 华为云 lt 官网 轻量型云服务器低至112元 年 新用户首次下单享超低折扣 目录 一 make和makefile的区别 二 makefile