makefile学习1

本文深入探讨Makefile的实用技巧,包括波浪线符号的意义、wildcard函数的应用、伪目标的正确使用及其注意事项,并通过实际案例展示如何高效地利用Makefile进行文件清理。

 

~代表的是当前用户的主目录

root下, ~应该是/root

root@ubuntu:/home/zhangbin# echo ~/bin

/root/bin

《GNU makefile中文手册》:
例如“~/bin”代表“/home/username/bin/” (当前用户
宿主目录下的 bin目录) 。波浪线之后跟一个单词(~word),代表由这个“word”所指
定的用户的宿主目录。例如“~john/bin”就是代表用户john 的宿主目录下的 bin目录。  
在一些系统中(像 MS-DOS 和 MS-Windows),用户没有各自的宿主目录,此情
况下可通过设置环境变量“HOME”来模拟。
==============
Makefile中,单独写上
 print: *.c
然后
root@ubuntu:/home/zhangbin/code# vi Makefile
root@ubuntu:/home/zhangbin/code# make
make: Nothing to be done for `print'.
root@ubuntu:/home/zhangbin/code# make print
make: Nothing to be done for `print'.
=================
                                       函数wildcard
变量定义中使用的通配符不会被统配处理(因此在变量定义中不能使用通配符,否
则在某些情况下会出现非预期的结果,下一小节将会详细讨论) 。在 Makefile 有这样一
个变量定义:“objects = *.o”。它表示变量“objects”的值是字符串“*.o”(并不是期
望的空格分开的.o文件列表)。当需要变量“objects”代表所有.o文件列表示,需要使
用函数“wildcard”(objects = $(wildcar *.o))。 
====================
                                       伪目标的必要性。

但是如果在当前工作目录下存在文件“clean” ,情况就不一样了,同样我们输入

“make clean”,由于这个规则没有任何依赖文件,所以目标被认为是最新的而不去执

行规则所定义的命令,因此命令“rm”将不会被执行。这并不是我们的初衷。为了解

决这个问题,我们需要将目标“clean”声明为伪目标。将一个目标声明为伪目标的方

法是将它作为特殊目标.PHONY”的依赖。如下: 

 

.PHONY : clean 

 

这样目标“clean”就被声明为一个伪目标,无论在当前目录下是否存在“clean”这个

文件。我们输入“make clean”之后。“rm”命令都会被执行。而且,当一个目标被声

明为伪目标后,make在执行此规则时不会去试图去查找隐含规则来创建它。这样也提

高了 make的执行效率,同时也不用担心由于目标和文件名重名而使我们的期望失败。

在书写伪目标规则时,首先需要声明目标是一个伪目标,之后才是伪目标的规则定义。

目标“clean”的完整书写格式应该如下: 

.PHONY: clean   #首先声明目标是一个伪目标

clean:                #伪目标的规则定义

rm *.o temp 

 

然后我自己写了一个:

 

  1 .PHONY :clean

  2 clean:

  3      rm *.o temp

root@ubuntu:/home/zhangbin/code/testDLP# make clean

rm *.o temp

rm: cannot remove `*.o': No such file or directory

rm: cannot remove `temp': No such file or directory

make: *** [clean] Error 1

 

===

改成这样:

  1 .PHONY :clean

  2 clean:

  3      rm *.yuv temp

root@ubuntu:/home/zhangbin/code/testDLP# make clean
rm *.yuv temp
rm: cannot remove `temp': No such file or directory
make: *** [clean] Error 1
====
再改正这样:
  1 .PHONY :clean
  2 clean:
  3      rm *.yuv
root@ubuntu:/home/zhangbin/code/testDLP# make clean
rm *.yuv
rm: cannot remove `*.yuv': No such file or directory
make: *** [clean] Error 1
改成具体的文件也不行啊:
root@ubuntu:/home/zhangbin/code/testDLP# make clean
rm logo.yuv
rm: cannot remove `logo.yuv': No such file or directory
make: *** [clean] Error 1
=====
加上一个 -f (force强制),好像还真删除了。
  1 .PHONY :clean
  2 clean:
  3      rm -f logo.yuv
root@ubuntu:/home/zhangbin/code/testDLP# make clean
rm -f logo.yuv
root@ubuntu:/home/zhangbin/code/testDLP# ls
ao_alsa.c       avin_file.c  COPYING.LGPL       Makefile.linux  vd_rv.c
ao_dsound.c     avin_ha2.c   DawnLightPlayer.c  Makefile.mingw  vo_dx.c
ao_example.c    avinput.c    DLPGUI.pyw         my_pthread.c    vo_example.c
ao_oss.c        avinput.h    dlpnet.c           my_pthread.h    vo_fb.c
ao_sdl.c        avoutput.c   dlpnet.h           NOTE.TXT        vo_gl.c
AUTHORS         avoutput.h   GenNewFile.py      queue.c         vo_sdl.c
avdecode.c      Changelog    global.h           queue.h         vo_x11.c
avdecode.h      cmdutils.c   Makefile           README          楱榥鈧
avin_example.c  cmdutils.h   Makefile.debian    tags
======
我再删除一个:
root@ubuntu:/home/zhangbin/code/testDLP# vi Makefile
  1 .PHONY :clean
  2 clean:
  3      rm -f logo.yuv *.pyw
~                                   
之前
root@ubuntu:/home/zhangbin/code/testDLP# ls
ao_alsa.c       avin_file.c  COPYING.LGPL       Makefile.linux  vd_rv.c
ao_dsound.c     avin_ha2.c   DawnLightPlayer.c  Makefile.mingw  vo_dx.c
ao_example.c    avinput.c    DLPGUI.pyw         my_pthread.c    vo_example.c
ao_oss.c        avinput.h    dlpnet.c           my_pthread.h    vo_fb.c
ao_sdl.c        avoutput.c   dlpnet.h           NOTE.TXT        vo_gl.c
AUTHORS         avoutput.h   GenNewFile.py      queue.c         vo_sdl.c
avdecode.c      Changelog    global.h           queue.h         vo_x11.c
avdecode.h      cmdutils.c   Makefile           README          楱榥鈧
avin_example.c  cmdutils.h   Makefile.debian    tags
root@ubuntu:/home/zhangbin/code/testDLP# make clean
rm -f logo.yuv *.pyw
之后
root@ubuntu:/home/zhangbin/code/testDLP# ls
ao_alsa.c       avin_file.c  COPYING.LGPL       Makefile.mingw  vo_dx.c
ao_dsound.c     avin_ha2.c   DawnLightPlayer.c  my_pthread.c    vo_example.c
ao_example.c    avinput.c    dlpnet.c           my_pthread.h    vo_fb.c
ao_oss.c        avinput.h    dlpnet.h           NOTE.TXT        vo_gl.c
ao_sdl.c        avoutput.c   GenNewFile.py      queue.c         vo_sdl.c
AUTHORS         avoutput.h   global.h           queue.h         vo_x11.c
avdecode.c      Changelog    Makefile           README          楱榥鈧
avdecode.h      cmdutils.c   Makefile.debian    tags
avin_example.c  cmdutils.h   Makefile.linux     vd_rv.c
还果然真的被删除了。
参考:
通常在清除文件的伪目标所定义的命令中“rm”使用选项“–f”(--force)来防止在缺少删除文件时出错并退出,使“make clean”过程失败。
也可以在“rm”之前加上“-”来防止“rm”错误退出,这种方式时 make 会提示错误信息但不会退出。
为了不看到这些讨厌的信息,需要使用上述的第一种方式。 
另外 make存在一个内嵌隐含变量“RM”,它被定义为:“RM = rm –f” 。因此在书写“clean”规则的命令行时可以使用变量“$(RM)”来代替“rm”,这样可以免出现一些不必要的麻烦!这是我们推荐的用法。 
==================================================
在 Makefile 中,一个伪目标可以有自己的依赖(可以是一个或者多个文件、一个
或者多个伪目标) 。在一个目录下如果需要创建多个可执行程序,我们可以将所有程序
的重建规则在一个Makefile 中描述。因为 Makefile 中第一个目标是“终极目标” ,约定
的做法是使用一个称为“all”的伪目标来作为终极目标,它的依赖文件就是那些需要创
建的程序。下边就是一个例子: 
 
#sample Makefile 
all : prog1 prog2 prog3   #终极目标,是一个叫做all的伪目标,all的依赖文件,是那些需要创建的程序:prog123
.PHONY : all 
 
prog1 : prog1.o utils.o 
cc -o prog1 prog1.o utils.o 
 
prog2 : prog2.o 
cc -o prog2 prog2.o 
 
prog3 : prog3.o sort.o utils.o 
cc -o prog3 prog3.o sort.o utils.o 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

等风来不如迎风去

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值