Linux 自动化构建工具 make/Makefile

VS中有一键编译+自动运行,Linux也给我们提供了对应的编译方式,虽然不及VS那么便捷,但是相比于手动输入 gcc -o add add.c ,我们一句make就可以搞定

Makefile是一个文件,能够存放上述 gcc -o add add.c 这种编译指令

make是一个命令工具,能够解释Makefile中的指令

要如何编译.c文件,关键就在于Makefile是怎么写的,下面我们主要介绍这两者的使用


目录

一、Makefile的基本格式

二、 单个文件的编译

1、写法一:逐个生成.i、.s、.o文件,最后再生成 test执行文件

2、 写法二:一步到位,直接通过 test.c 生成 test 执行文件(推荐)

3、 Makefile自动清理

三、多个文件的编译(同一目录下)

四、多个文件的编译(不同目录下)

五、一次生成多个运行文件

1、常规写法尝试及其不可行的原因

2、改进


一、Makefile的基本格式

# target —— 需要生成的目标文件
# dependency —— 生成目标文件所需的依赖文件
# command —— 命令执行语句
target: dependency 
    command            #command 前面必须要有一个制表位(Tab键)

#例子
test.o : test.c
    gcc -o test.o test.c
    

注意:command 前面必须要有一个制表位(Tab键),否则编译错误为:*** missing separator 

二、 单个文件的编译

假设我们要编译这么一个test.c文件,我们希望编译生成一个名为test的可执行文件

我们在test.c所在目录下创建一个Makefile文件,这里有两种编译写法

1、写法一:逐个生成.i、.s、.o文件,最后再生成 test执行文件

先一步步向下分析,需要什么依赖文件,然后再一步步生成

编写好以后,我们只需要在命令行输入make,系统就会帮我们自动编译了,同时会生成每一步产生的文件按

2、 写法二:一步到位,直接通过 test.c 生成 test 执行文件(推荐)

Makefile中要写的内容如下

第一行:确定好依赖文件和目标文件。也就是要用依赖文件来生成目标文件

第二行:编译指令。

                $@ 指向第一行的目标文件,表示目标文件test

                $^ 指向第一行的依赖文件,表示依赖文件test.c

                -std 表示采用的C++标准

接下来我们只需要在命令行输入make,系统就会帮我们编译了,编译成功以后,当前目录下就会多出一个test 执行文件

3、 Makefile自动清理

我们每次开始编译之前,我们最好先清理一下之前生成的执行文件,手动输入 rm test 有点太麻烦了,Makefile只要写入下面的内容,就会自动帮我们清理了

如果我们还希望移除生成的.o 、.s、.i文件,那么第6行只要换成

rm -f test test.o test.s test.i

 一般我们make的时候,系统会自动调用,当然也可以手动调用,如

 我们会发现之前的test执行文件不见了

三、多个文件的编译(同一目录下)

现在我们有三个文件,分别是test.c、sub.c、sub.h,而且我们要在test.c中调用sub.h中的函数

 Makefile中的内容如下:

test执行文件 要依赖 多个文件生成的 .o文件,现在没有 .o文件,所以需要重新生成 .o文件

当前路径下有多个.c文件,我们逐个去写的话,就是

test.o:test.c
    gcc -c $@ $^
sub.o:sub.c
    gcc -c $@ $^

但是这样写太复杂了,我们可以选择下面这种写法

%.o: %.c
    gcc -c $<

%.o:表示目标文件是 .o文件

%.c:表示依赖文件是当前路径下的 .c文件,可以看作是一个集合中放着 test.c  sub.c

$< :   展开%.c ,逐个生成对应的 .o文件,比如test.c就会生成对应的test.o、sub.c就会生成对应的

        sub.o

现在我们来运行一下

四、多个文件的编译(不同目录下)

现在我们有三个文件,test.c、sub.h、sub.c,但是其中sub.h、sub.c在其目录func_dir 下

 

 Makefile的内容如下:

 现在我们来运行一下试试

五、一次生成多个运行文件

1、常规写法尝试及其不可行的原因

=========================常规写法尝试=========================

上面的都是一个main函数文件 + 一堆函数文件的编译,但是有的时候,比如不同进程间通信时,我们可能需要一次生成两个运行文件,如果我们按照常规的思路来写,会怎么样?

测试结果如下,我们发现只生成了一个运行文件,很显然无法按照常规的写法来写

=========================原因分析=========================

Makefile自动构建结束会生成运行文件,默认只生成最开始的一个,我们写的时候,server的生成放在client的前面,server就是最开始的哪一个,所以Makefile就只生成了 server

2、改进

Makefile既然生成server以后,就不会继续生成下一个运行文件,那么我们就要在这之前就告诉Makefile,我希望生成两个运行文件(因为Makefile是自顶向下运行的,不会上来就去执行gcc指令)

 然后我们再来看一下测试结果,现在就能一次生成两个运行文件了

猜你喜欢

转载自blog.csdn.net/challenglistic/article/details/124249349#comments_28042031