一个灵活通用的GNU makefile

Posted Sarkuya

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个灵活通用的GNU makefile相关的知识,希望对你有一定的参考价值。

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

让我们通过编译一个简单的使用自己开发的模块的C语言程序来看看GNU make到底有多灵活。


一、自定义模块math

首先是头文件math.h:

#ifndef math_h
#define math_h

int sum(int a, int b);

#endif /* math_h */

其实现math.c文件:

#include "math.h"

int sum(int a, int b) {
    return a + b;
}

二、主程序HelloMath

现在主程序HelloMath.c需要调用math模块的sum函数。

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

int main() {
    printf("Hello, Math!\\n");

    int a = sum(2, 5);
    printf("%d\\n", a);

    return 0;
}

三、主角makefile

MAINFILE := HelloMath
OBJDIR := bin
OBJS := $(addprefix $(OBJDIR)/, $(patsubst %.c, %.o, $(wildcard *.c)))
EXEFILE := ${OBJDIR}/${MAINFILE}


.PHONY : all
all : ${EXEFILE}
	${EXEFILE}


${EXEFILE} : ${OBJS}
	cc $^ -o $@

${OBJDIR}/%.o : %.c
	cc -MM $^
	cc -c $^ -o $@

${OBJS} : | ${OBJDIR}

${OBJDIR} :
	mkdir ${OBJDIR}


.PHONY : clean cleanobj cleanexe
clean :
	rm -r ${OBJDIR}

cleanobj :
	rm ${OBJDIR}/*.o

cleanexe :
	rm ${EXEFILE}

在当前目录下输入:

make

输出:

mkdir bin                                                                                                            
cc -MM HelloMath.c                                                                                                  
HelloMath.o: HelloMath.c math.h                                                                                    
cc -c HelloMath.c -o bin/HelloMath.o                                                                               
cc -MM math.c                                                                                                        
math.o: math.c math.h                                                                                                
cc -c math.c -o bin/math.o                                                                                           
cc bin/HelloMath.o bin/math.o -o bin/HelloMath                                                                     
bin/HelloMath                                                                                                       
Hello, Math!                                                                                                        
7

四、赏玩

这个makefile很灵活,它有以下特点:

  1. 所有的.c文件,无惧数量的多少,都能自动地编译为相应的.o文件。
  2. 这些生成的.o文件,统一放置在bin目录下。
  3. bin目录会根据需要时正确地创建,且其时间戳的改变不会影响正确地判断文件是否新近生成。
  4. 自动扫描.c文件中的#include语句,根据这些语句来自动生成相应的依赖关系,且自动排除标准库文件的引用及依赖。
  5. 通过引用内置自动变量,代码简洁美观,易于维护。
  6. 整个编译完成后,自动运行主程序,无需劳神在终端中手工运行。
  7. 三种清理方式,根据需要进行选择,以尽可能提高重新编译生成的速度。
  8. 复用性强,对另一个程序,只需将MAINFILE的值改为相应的主程序名称即可。其他均无需改变。

五、结语

GNU make使用起来很简单,输入一个make命令就可搞定日常编程需求。但不要被其表面上的简单欺骗了,它内部工作机制相对比较复杂。然而,复杂的目的就是为了让用户在使用时更加方便,这便是深出浅出的道理。完全掌握它需要我们花费不少的时间,以致于许多程序员都认为,这是一门披着朴素外表的编程语言。实际上,这个强大的工具值得我们花时间来好好研究,投入其中越多,我们就越轻松,不是吗?


六、参考文献

  1. GNU Make

以上是关于一个灵活通用的GNU makefile的主要内容,如果未能解决你的问题,请参考以下文章

使用带有 NMake 样式 Makefile 的 clang-cl 无法回显

运算类实现 及 GNU Makefile基本结构

一个简单的执行程序的GNU automake自动生成Makefile的方法及案例

GNU make 在 makefile 完成之前停止而没有错误

GNU autotools自动生成Makefile 介绍

《GNU_makefile》第五章——为规则书写命令