假设在 Linux 下我们有这样几个c文件和头文件,他们间的依赖关系如代码所示,那么我们如何编译呢?

hello.c

#include<stdio.h>
#include"print.h"
int main(void){
        printf("hello world\n");
        my_print();
        return 0;
}

print.c

#include<stdio.h>
#include"print.h"

void my_print(){
        printf("print in print.c\n");
}

print.h

void my_print();

一、 直接编译

gcc hello.c print.c -o hello

但是这样的一个缺点是当项目特别大的时候,无论 .c 文件相较于上一次编译的时候是否发生改变,下一次编译的时候都会再次编译一次,特别浪费时间,所有以有没有一个方法只编译改编过的源文件呢?这就是方法二利用 makefile 文件来自动编译

二、 通过 makefile 文件和 make 命令进行编译

makefile 文件的文件名必须为 makefile 或者 Makefile ,否则则需要 -f 参数指定文件

首先通过命令 gcc -MM hello.c print.c 来查看c文件间的依赖关系

heeeepin@DESKTOP-7CC5NOD:~$ gcc -MM hello.c print.c
hello.o: hello.c print.h
print.o: print.c print.h

可以看到,若要编译 hello 可执行文件,它依赖于 hello.o 和 print.o 这两个文件,而这两个文件有分别依赖于冒号后面的两个文件,所以我们依次对他们进行编译,就写成了 makefile 文件

另外 makefile 不仅可以编译文件,还可以执行一些其他命令,如删除编译环节产生的中间文件,对编译的可执行文件进行安装(linux下就是把可执行文件复制到 /bin/ 文件夹下)

hello: hello.o print.o
        gcc -o hello hello.o print.o

hello.o: hello.c print.h
        gcc -c hello.c

print.o: print.c print.h
        gcc -c print.c

clean:
        rm -f *.o

install: hello
        cp hello /usr/local/bin/
        chmod a+x /usr/local/bin/hello
        echo "installed in /usr/local/bin"

这样我们就可以执行 make 命令进行编译,编译完将产生 hello 的可执行文件

heeeepin@DESKTOP-7CC5NOD:~$ make
gcc -c hello.c
gcc -c print.c
gcc -o hello hello.o print.o

make clean 命令删除编译中间文件 .o 文件

heeeepin@DESKTOP-7CC5NOD:~$ make clean
rm -f *.o

make install 命令进行安装

root@DESKTOP-7CC5NOD:/home/heeeepin# make install
cp hello /usr/local/bin/
chmod a+x /usr/local/bin/hello
echo "installed in /usr/local/bin"
installed in /usr/local/bin

执行完一系列命令后,我们就可以执行 hello 命令,对编译结果进行输出了

heeeepin@DESKTOP-7CC5NOD:~$ hello
hello world
print in print.c

总结

这只是一个简单的 makefile 文件,代码很繁琐不具有一般性,如果要深入学习 makefile 的编写,还需要掌握变量的使用以及一些默认的规则

本文仅作一个抛砖引玉以及作者的备忘,如有错误欢迎指出

标签: makefile, make

已有 2 条评论

  1. 没Makefile敲gcc敲到爆炸

  2. 路过呀,其他的不懂。

添加新评论