调试Makefile的工具——remake

这两天在调试开源项目的一个Makefile,发现了remake这个工具(项目主页:http://bashdb.sourceforge.net/remake/),真的很好用。稍微大型点的开源项目,Makefile都很复杂,一旦出了错,很令人抓狂。而这个remake工具产生的输出能把整个编译过程的来龙去脉打印的很清楚。举例如下,一个简单的编译Linux模块的Makefile

ifneq ($(KERNELRELEASE),)
        obj-m := hello.o
else
        KDIR ?= /lib/modules/`uname -r`/build
default:
        $(MAKE) -C $(KDIR) M=$$PWD
endif

执行remake -x命令:

# remake -x
Reading makefiles...
Updating goal targets....
 File 'default' does not exist.
Must remake target 'default'.
Makefile:8: target 'default' does not exist
##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
remake -C /lib/modules/`uname -r`/build M=$PWD
##<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Reading makefiles...
Updating goal targets....
 File 'all' does not exist.
Must remake target 'all'.
remake[1]: Entering directory '/usr/src/linux-3.12.49-6-obj/x86_64/default'
Makefile:26: target 'all' does not exist
##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
remake -C ../../../linux-3.12.49-6 O=/usr/src/linux-3.12.49-6-obj/x86_64/default/.
##<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Reading makefiles...
Updating goal targets....
 File '_all' does not exist.
   File 'sub-make' does not exist.
     File 'FORCE' does not exist.
    Must remake target 'FORCE'.
    Successfully remade target file 'FORCE'.
  Must remake target 'sub-make'.
Makefile:195: update target 'sub-make' due to: FORCE
##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
echo "make[1]: Entering directory \`/usr/src/linux-3.12.49-6-obj/x86_64/default'"
##<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
make[1]: Entering directory `/usr/src/linux-3.12.49-6-obj/x86_64/default'
##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
remake -C /usr/src/linux-3.12.49-6-obj/x86_64/default \
KBUILD_SRC=/usr/src/linux-3.12.49-6 \
KBUILD_EXTMOD="/root/Documents/test" -f /usr/src/linux-3.12.49-6/Makefile \

##<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
......

可以看到,输出了非常详细的日志信息,很方便debug

 

Linux kernel 笔记 (22)——一个简单的模块Makefile

LDD3Compiling and Loading一节的编译模块的Makefile为例:

# If KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq ($(KERNELRELEASE),)
    obj-m := hello.o 

# Otherwise we were called directly from the command
# line; invoke the kernel build system.
else

    KERNELDIR ?= /lib/modules/$(shell uname -r)/build
    PWD  := $(shell pwd)

default:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

endif

当在命令行执行make命令时(当前工作目录即模块源文件所在目录),因为当前模块所在目录里没有定义KERNELRELEASE,所以执行else部分,即把KERNELDIRPWD变量赋值。

接下来执行“$(MAKE) -C $(KERNELDIR) M=$(PWD) modules”命令。-C选项的含义是把目录切换到KERNELDIR目录下,然后读取KERNELDIR目录下的MakefileM选项是在编译modules再切换回模块所在目录。此时由于KERNELRELEASE变量已经定义,即可以得知需要编译obj-m

参考资料:
Understanding a make file for making .ko files