原创博文,转载请标明出处--周学伟http://www.cnblogs.com/zxouxuewei/

一般情况下,Makefile都会有一个clean目标,用于清除编译过程中产生的二进制文件。我们在第一节的Makefile就用到了这个 clean目标,该目标没有任何依赖文件,并且该目标对应的命令执行后不会生产clean文件。

像这种特点目标,它的规则所定义的命令不是去创建文件,而仅仅通过make指定目标来执行一些特定系统命令或其依赖为目标的规则(如all),称为伪目标。

一个Makefile一般都不会只有一个伪目标,如果按Makefile的“潜规则”以及其约定俗成的名字来说的话,在较大的项目的Makefile中比较常用的为目标有这些:

all:执行主要的编译工作,通常用作缺省目标,放在最前面。

Install:执行编译后的安装工作,把可执行文件、配置文件、文档等分别拷到不同的安装目录。

clean:删除编译生成的二进制文件。

distclean:删除除源文件之外的所有中间生成文件,如配置文件,文档等。

tags:为vim等编辑器生成tags文件。

help:打印当前Makefile的帮助信息,比如有哪些目标可以有make指定去执行。

make处理Makefile时,首先读取所有规则,建立关系依赖图。然后从缺省目标(第一个目标)或指定的目标开始执行。像clean,tags 这样的目标一般不会作为缺省目标,也不会跟缺省目标有任何依赖关系,所以 make 无法生成它的依赖关系和决定它是否要执行。所以要执行这样的目标时,必须要显示的指定make该目标。就像前面我们清楚便已产生的中间二进制文件一样,需 要显示执行命令:make clean。

伪目标也可以作为默认目标(如all),并且可以为其指定依赖文件。

我们先将version 1.0的Makefile完善下,我们可以加入帮助信息,tags等功能。

    # A common Makefile for c programs, version 1.1  

    # Copyright (C) 2014 shallnew \at 163 \dot com  

    CFLAGS += -g -Wall -Werror -O2
CPPFLAGS += -I. -I./inc
LDFLAGS += -lpthread # SRC_OBJ = $(patsubst %.c, %.o, $(wildcard *.c))
SRC_FILES = $(wildcard *.c)
SRC_OBJ = $(SRC_FILES:.c=.o)
SRC_BIN = target_bin all : $(SRC_BIN) $(SRC_BIN) : $(SRC_OBJ)
>---$(CC) -o $@ $^ $(LDFLAGS) obj : $(SRC_OBJ) tags:
>---ctags -R help:
>---@echo "===============A common Makefile for cprograms=============="
>---@echo "Copyright (C) 2014 liuy0711 \at 163 \dotcom"
>---@echo "The following targets are support:"
>---@echo
>---@echo " all - (==make) compile and link"
>---@echo " obj - just compile, without link"
>---@echo " clean - clean target"
>---@echo " distclean - clean target and otherinformation"
>---@echo " tags - create ctags for vim editor"
>---@echo " help - print help information"
>---@echo
>---@echo "To make a target, do 'make [target]'"
>---@echo "========================= Version 1.1=======================" # clean target
clean:
>---$(RM) $(SRC_OBJ) $(SRC_BIN) $(SRC_BIN).exe distclean:
>---$(RM) $(SRC_OBJ) $(SRC_BIN) $(SRC_BIN).exe tags *~
 

make会把执行的命令打印在屏幕上,如果我们不想把命令打印在屏幕上,只显示命令结果时,直接在命令前面加上符号“@”就可以实现。如上面 help目标一样,只显示命令结果。一般我们会在make时都会输出“Compiling xxx.c…”,不输出编译时的命令。我们在后面写Makefile时可以模仿。

如果当前目录下存在一个和伪目标同名的文件时(如clean),此时如果执行命令make clean后出现如下结果:

    # touch clean
# make clean
make: `clean' is up to date.
#

这是因为clean文件没有依赖文件,make认为目标clean是最新的不会去执行规则对应的命令。为了解决这个问题,我们可以明确地将该目标声明为伪目标。将一个目标声明为伪目标需要将它作为特殊目标.PHONY”的依赖。如下:

.PHONY : clean

这条规则写在clean:规则的后面也行,也能起到声明clean是伪目标的作用

这样修改一下之前Makefile,将所有伪目标都作为.PHONY的依赖:

.PHONY : all obj tag help clean disclean
 

这样在当前目录下存在文件clean时执行:

    # make clean
rm -f debug.o ipc.o main.o timer.o tools.o target_bin target_bin.exe
#

最后,给出今天最终的Makefile:

        # A common Makefile for c programs, version 1.1
# Copyright (C) 2014 shallnew \at 163 \dot com CFLAGS += -g -Wall -Werror -O2
CPPFLAGS += -I. -I./inc
LDFLAGS += -lpthread # SRC_OBJ = $(patsubst %.c, %.o, $(wildcard *.c))
SRC_FILES = $(wildcard *.c)
SRC_OBJ = $(SRC_FILES:.c=.o)
SRC_BIN = target_bin all : $(SRC_BIN) $(SRC_BIN) : $(SRC_OBJ)
>---$(CC) -o $@ $^ $(LDFLAGS) obj : $(SRC_OBJ) tag:
>---ctags -R help:
>---@echo "===============A common Makefile for cprograms=============="
>---@echo "Copyright (C) 2014 liuy0711 \at 163 \dotcom"
>---@echo "The following targets are support:"
>---@echo
>---@echo " all - (==make) compile and link"
>---@echo " obj - just compile, without link"
>---@echo " clean - clean target"
>---@echo " distclean - clean target and other information"
>---@echo " tags - create ctags for vim editor"
>---@echo " help - print help information"
>---@echo
>---@echo "To make a target, do 'make [target]'"
>---@echo "========================= Version 1.1=======================" # clean target
clean:
>---$(RM) $(SRC_OBJ) $(SRC_BIN) $(SRC_BIN).exe distclean:
>---$(RM) $(SRC_OBJ) $(SRC_BIN) $(SRC_BIN).exe tags *~ .PHONY : all obj tag help clean disclean

Makefile--伪目标 (三)的更多相关文章

  1. Makefile 文件格式;makefile伪目标

    Makefile包含 目标文件.依赖文件.可运行命令三部分. 每部分的基本格式例如以下: test: prog.o  code.o gcc  -o  test   prog.o   code.o 当中 ...

  2. 第3课 - makefile伪目标的引入

    第3课 - makefile伪目标的引入 1. makefile 中的目标究竟是什么? (1)默认情况下,make 认为目标对应着一个文件  ==>  目标即文件名 (2)make 首先会检测目 ...

  3. Makefile伪目标

    https://www.zybuluo.com/lishuhuakai/note/210174 本节我们讨论一个Makefile中的一个重要的特殊目标:伪目标. 伪目标是这样一个目标:它不代表一个真正 ...

  4. Makefile 描述的是文件编译的相关规则,它的规则主要是两个部分组成,分别是依赖的关系和执行的命令 PHONY伪目标实践

    Makefile的工作流程 http://c.biancheng.net/view/7091.html Makefile文件是什么? 我们教程主要是讲的是 Makefile .很多 Linux(Uni ...

  5. Makefile的伪目标

    1.Makefile伪目标的格式: .PHONY : cleanclean: rm xxxx 2.Makefile伪目标的作用: 第一种情况: 如果我们需要书写这样的一个规则:规则所定义的命令不是去创 ...

  6. 第三篇 makefile的伪目标

    我们来思考一下makefile中的目标究竟是什么?实际上,在默认情况下:    1.make将makefile的目标认为是一个文件:    2.make解释器比较目标文件和依赖文件的新旧关系,决定是否 ...

  7. Makefile编写 三 伪目标的作用

    本节我们讨论一个Makefile中的一个重要的特殊目标:伪目标. 伪目标是这样一个目标:它不代表一个真正的文件名,在执行make时可以指定这个目标来执行其所在规则定义的命令,有时我们也可以将一个伪目标 ...

  8. makefile中伪目标的理解

    1. 我们知道Makefile中的语法是这样: target ... : prerequisites ... command - - 2. 假如编译两个文件可以这么写: a.o:a.c  gcc -c ...

  9. Makefile目标,伪目标,头文件自动依赖

    目标 即我们最终要生成的文件,make默认生成第一个目标,注意 makefile中tab和空格不是一回事,规则使用tab缩进,编辑器不要设置诸如"将tab替换为空格之类的选项",目 ...

  10. makefile中的伪目标

    伪目标就是总是被执行的目标,相对于目标来说,伪目标不会去考虑它的依赖的时间戳与自己时间戳的新旧关系,从而决定是否执行规则.伪目标格式: .PHONY:clean clean: -rm *.o 在mak ...

随机推荐

  1. csdn能不靠点谱啊

    以前的时候在csdn上有一个博客,那时经常出错,所以就不用了,后来在百度上开了个博客,后以空间升级了,升级之后,那叫一个垃圾,不用了,现在返回头来再用csdn,刚开始两天还好,没用两天又不行了,想在上 ...

  2. 深入理解Eureka - Eureka Client获取注册信息机制

    深入理解Eureka - Eureka Client获取注册信息机 Eureka Client提供了定时获取注册信息的机制.Eureka Client获取注册信息的所有逻辑都在DiscoveryCli ...

  3. Linux Jenkins配置Git

    1.卸载Centos自带的git1.7.1:通过git –version查看系统带的版本,Centos应该自带的是git版本是1.7.1 终端输入:yum remove git 2.安装所需软件包 终 ...

  4. mysql linux 区分大小写

    查看大小写区分 mysql> show variables like "%case%"; +------------------------+-------+ | Varia ...

  5. dp之最长递增、公共子序列总结

    1.最长递增子序列模板poj2533(时间复杂度O(n*n)) #include<iostream> #include<stdio.h> #include<string. ...

  6. 推荐10款纯css3实现的实用按钮

    在2014年的双11即将来临之季,爱编程小编为大家整理10款纯css3实现的按钮.希望这对坚守在前端的码农们有所帮助.亲,如果你有好的资源也可在本文留言,让从事编码的程序员们抱团.工作更轻松. No1 ...

  7. 一款基于css3非常实用的鼠标悬停特效

    今天给大家带来一款基于css3非常实用的鼠标悬停特效.这款特效,当鼠标经过时候一个半透明的遮罩层倒下来.效果很好,而且是纯css3实现的,代码很少,非常实用. 效果如下: 在线预览   源码下载 实现 ...

  8. 后台js返回验证登陆绕过

    思路: 程序员通过JS的返回数据来决定是否登陆成功.返回码为0000的时候表示登陆成功,将返回数据改为其登陆成功的即可. 具体过程: 后台登陆地址http://127.0.0.1/manager/ad ...

  9. c#利用反射Assembly 对类和成员属性进行操作

    protected static void test() { //获取程序集 Assembly assembly = System.Reflection.Assembly.GetExecutingAs ...

  10. VC++中动态链接库的显示加载和隐式加载的区别

    两种方法对于你的程序调用动态库时没有任何区别,只是你在编程时,步骤是不一样的.显式调用麻烦了点,但可以没有相应的lib库:隐式调用,使用起来比较 简单,有函数的声明(头文件.h)就可以了,但必须有li ...