Make以及Makefile的编写

https://blog.csdn.net/weixin_38176039/article/details/80246141

 

Linux下GUN之GCC编译器

https://blog.csdn.net/weixin_42590177/article/details/88971115

 

makefile编写

https://blog.csdn.net/njys1/article/details/81413332

 

C++学习笔记1——安装GNU编译器,配置sublime,编译运行第一个程序

https://blog.csdn.net/qq_35221523/article/details/79441131

 

 

 

1概述:

能读懂, 编写makefile应该是每一个Linux程序猿都必须拥有的基本素质,因为makefile是大型的工程中绕不过去的,你能不能写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。

因为,makefile关系到了整个工程的编译规则:


如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。
如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程。
如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。
从上面的例子可以看出 , makefile是一个"自动化编译器",你只需要写好一个makefile, 然后执行一个make命令 , 整个工程就会自动按照规则编译了,极大提高了我们程序猿的效率。

2编写Makefile:

2.1 单文件Makefile:

//Makefile

test: test.o    #(test)是目标文件 (:)是依赖的文件或者命令   (test.o) 是test依赖的文件
    gcc -o test test.c 
 
.PHONY: clean   #(.PHONY)是伪目标标记, 伪目标标记后的命令,不会和目录下文件重复,\
                        也就是说clean如果没有伪目标标记的话,目录下有一个clean的文件\ 
                        make clean将不会正确执行! 
clean:
    rm -fr *.o test
引用一段百度百科结合我上面的例子,说明一下吧

1 冒号(:)左边的test是目标文件 , 目标文件依赖于冒号(:)右边, 

2 冒号右边即可以是文件test.o,也可以是目标,后面多文件多目录编译会讲到实例

3 第二行的gcc很明显是一个命令, 命令必须要以tab开头隔开 , Makefile里的命令可以是任何的shell命令

//test.c

#include <stdio.h>
 
int main(void) {
 
    printf("once_file_makefile ...\n");
    return 0;
}
运行结果:

2.2 多目录下Makefile编写

首先我建立一个Makefile的根目录如下图(1):

根目录下的Makefile如下:

CC := gcc
SUBDIR :=   d1\
            d2\
            test\
            obj#子目录文件夹
OBJS := d1.o d2.o test.o#生成目标文件所需的依赖
OBJS_DIR := obj#所有目标文件依赖的.o文件存放的目录
BIN := myapp#最终的目标文件
BIN_DIR := app#存放目标文件的目录
export CC OBJS OBJS_DIR BIN BIN_DIR#export关键字,导出CC等变量到子目录,让次级目录下的Makefile可以识别
all: CHECK_DIR $(SUBDIR) #分别执行CKECK_DIR和$(SUBDIR)两个依赖,这里的依赖是目标而不是文件
CHECK_DIR:
    @mkdir -p $(BIN_DIR) #创建存放目标文件的目录
$(SUBDIR): ECHO
    @make -C $@ #在所有的子目录下执行make 
ECHO:
    @echo start compile ...
 
.PHONY:clean
clean:
    @rm -fr $(OBJ)/*.o $(BIN_DIR)
d1/Makefile

../$(OBJS_DIR)/d1.o:d1.c #OBJS_DIR是从根目录通过export关键字传过来的变量\
                          也就等同于../obj/d1.o依赖于当前目录下d1.c
    $(CC) -c $^ -o $@ #gcc -c 依赖(d1.c) -o 目标(d1.o) $^表示所有依赖, $@表示目标
d2/Makefile

../$(OBJS_DIR)/d2.o: d2.c
    $(CC) -c $^ -o $@
test/Makefile

../$(OBJS_DIR)/test.o: test.c
    $(CC) -c $^ -o $@
obj/Makefile

../$(BIN_DIR)/$(BIN):$(OBJS)
    $(CC) -o $@ $^
include/include.h

// include/include.h
#ifndef __INCLUDE_H__
#define __INCLUDE_H__
 
#include <stdio.h>
 
#define DEBUG(f, arg...)    printf("file:[%s] " " line:[%d] :"f"\n",\
                            __FILE__, __LINE__, ##arg)
#endif //__INCLUDE_H__
 
d1/d1.c d2/d2.c test/test.c

// d1/d1.c
#include "../include/include.h"
 
void d2(void) {
    DEBUG("Massage from d2");
 
}
// d2/d2.c
#include "../include/include.h"
 
void d1(void) {
    DEBUG("Massage from d1");
 
}
// test/test.c
#include "../include/include.h"
 
int main(void) {
 
    d1();
    d2();
    return 0;
}

运行结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值