• make与makefile


    目录

    一、make的默认目标文件与自动推导

    二、不能连续make的原因

    执行原理

    touch

    .PHONY伪目标

      make指令不回显

    makefile多文件管理 

    简写依赖方法

    三、回车与换行

    四、缓冲区


    一、make的默认目标文件与自动推导

    假设这是一个makefile文件,make的时候默认生成第一行的目标文件 ,make会自动推导makefile中的依赖关系,推导过程是一个栈式结构。

    1. hello:hello.o
    2. gcc hello.o -o hello
    3. hello.o:hello.s
    4. gcc -c hello.s -o hello.o
    5. hello.s:hello.i
    6. gcc -S hello.i -o hello.s
    7. hello.i:hello.c
    8. gcc -E hello.c -o hello.i

    即使我们打乱了下面六行的顺序,结果还是相同,最终编译出来的任然是hello

    1. hello:hello.o
    2. gcc hello.o -o hello
    3. hello.o:hello.s
    4. gcc -c hello.s -o hello.o
    5. hello.i:hello.c
    6. gcc -E hello.c -o hello.i
    7. hello.s:hello.i
    8. gcc -S hello.i -o hello.s

    而如果hello.s为目标文件,那么程序编译到hello.s就会结束了

    1. hello.s:hello.i
    2.     gcc -S hello.i -o hello.s
    3.  hello.i:hello.c
    4.      gcc -E hello.c -o hello.i
    5.  hello.o:hello.s
    6.      gcc -c hello.s -o hello.o
    7.  hello:hello.o
    8.      gcc hello.o -o hello  

    二、不能连续make的原因

    在进行make操作时,我们不能连续make,因为如果源文件已经被编译过了,并且源文件没有被修改,那我们就没有必要编了,这样子可以提高效率。

    执行原理

    因为一定是先有源文件再有可执行文件的,所以一般而言,源文件的最早修改时间是要比可执行文件早的

    如果源文件被修改过,历史上还有可执行文件,那么源文件的最近修改时间一定比可执行文件晚

    我们可以使用stat 文件名  来查询文件的时间问题

    access 为最近访问时间,但是由于我们不管是进行文件的 内容或者属性修改都会进行访问,因此access会在多次被访问之后才会更新一次

    modify则是文件内容被修改的最近一次时间

    change是文件属性被修改的最近一次时间,包括文件名,文件大小,文件创建日期,文件的权限等等

    值得注意的是因为修改文件内容时,绝大多数时候文件的大小都会改变,因此modify改变大部分情况change也都会改变,而修改文件属性时则不会改变modify

    touch

    我们如果使用touch 文件名  ,那么 access,modifiy,change都会改变到当前时刻,我们也可以使用选项单个修改

    -m 修改modify,但是同时change也会改变

    -a改变access

    而make是否执行依赖关系,比较的是modify

    .PHONY伪目标

    那如果我想让对应的依赖关系总是被执行呢?

    我们可以在依赖关系前面添加.PHONY:,即为伪目标。添加.PHONY:后依赖关系总是会被执行。我们一般会在clean 的前面添加

    1. mytest.exe : mycode.c //依赖关系
    2. gcc -o mytest.exe mycode.c //这行的开头要求是一个tab 这行称为依赖方法
    3. .PHONY: clean
    4. clean:
    5. rm -f mytest.exe

      make指令不回显

    执行make 和make clean 时依赖方法会进行回显

    我们可以在依赖方法前带上@

    1. mytest.exe : mycode.c
    2. @gcc -o mytest.exe mycode.c

    makefile多文件管理 

    makefile 还支持多文件管理,例如

    1. processbar: processbar.c main.c //如果.h文件与这两个文件在同一目录下,那么gcc是能自己找到.文件的
    2. gcc -o $@ $^

    (假设这个项目由processbar.h ,processbar.c,main.c组成)

    简写依赖方法

    特殊符号$@可以表示依赖关系冒号左边的文件,$^可以表示冒号右边的文件

    1. mytest.exe : mycode.c
    2. gcc -o $@ $^
    3. mytest.exe : mycode.c main.c
    4. gcc -o $@ $^

    三、回车与换行

    回车指的是将光标移动到改行的开头

    换行指的是将光标移动到下一行

    四、缓冲区

    缓冲区就是c语言维护的一段内存

    我们编译并运行代码1

    1. #include
    2. int main()
    3. {
    4. printf("hello Makefile!\n");
    5. sleep(3);
    6. return 0;
    7. }

    会观察到程序会先打印,再停顿三秒

    而当我们编译并运行代码2

    1. #include
    2. int main()
    3. {
    4. printf("hello Makefile!");
    5. sleep(3);
    6. return 0;
    7. }

    我们会看到,程序会先停顿三秒,再输出。

    这难道是代码执行顺序改变了吗?其实知识因为去掉\n后,printf输出的内容被存到缓冲区内

    当我们执行代码3时

    1. #include
    2. int main()
    3. {
    4. printf("hello Makefile!");
    5. fflush(stdout);
    6. sleep(3);
    7. return 0;
    8. }

    效果又会同代码1一样了,这时候因为我们使用fflush刷新了stdout,stdout是标准输出流,即显示器

  • 相关阅读:
    智能计算之蚁群算法(ACO)介绍
    开源与区块链:去中心化的未来
    Vue基础(复习)
    优维科技低代码开发平台在券商系统的落地实践
    SpringBoot配置文件(学习笔记)
    7.4 条件变量示例
    从 LinkedHashMap 源码到手撕 LRU 缓存
    Kafka、ActiveMQ、RabbitMQ、RocketMQ 的区别
    Haproxy+Nginx搭建负载均衡集群
    网络安全--安全认证、IPSEC技术
  • 原文地址:https://blog.csdn.net/myhhhhhhhh/article/details/139872028