【版权声明:转载请保留源:blog.csdn.net/gentleliu。Mail:shallnew at 163 dot com】

    上创建的文件夹谈及。没有生产目标文件到相应的文件夹,在这里,我们给与相应的文件夹中的目标文件。的目标文件会直接生成到相应文件夹。我们先给库文件目标和可运行文件目标加上路径。例如以下:

lib : $(OBJDIR) $(LIBDIR)/$(SRC_LIB)

bin : $(OBJDIR) $(BINDIR)/$(SRC_BIN)

$(OBJDIR) :
>---@echo " MKDIR $(notdir $@)..."
>---@mkdir -p $@ ifneq ($(SRC_BIN),)
$(BINDIR)/$(SRC_BIN) : $(SRC_OBJ)
>---$(CC) -o $@ $^ $(LDFLAGS)
endif ifneq ($(SRC_LIB),)
$(LIBDIR)/$(SRC_LIB) : $(SRC_OBJ)
>---$(AR) rcs $@ $^
>---cp $@ $(SRC_BASE)/libs
endif

此时再运行make,完毕后查看build文件夹树:

build/
└── unix_dbg
├── bin
│ └── target_bin
├── lib
│ ├── libipc.a
│ └── libtools.a
└── obj
├── ipc
├── main
└── tools

能够看到,生成的目标是在相应文件夹下。

我们乘胜追击,把.o文件也将其改动了。我们之前的每一个模块Makefile大致是这样写的:

SRC_BASE = ../..                                                                             

CFLAGS +=
CPPFLAGS += -I. -I./inc -I$(SRC_BASE)/include # SRC_OBJ = $(patsubst %.c, %.o, $(wildcard *.c))
SRC_FILES = $(wildcard src/*.c)
SRC_OBJ = $(SRC_FILES:.c=.o)
SRC_LIB = xx.a include $(SRC_BASE)/Makefile.rule

当中SRC_OBJ在此处给出,然后再在Makefile.rule中使用,此处的.o文件会在.c文件同样文件夹下生成。所以我们如今须要将.o文件加上路径。因为取得路径是在Makefile.rule里面,所以我们能够统一在Makefile.rule里面给变量SRC_OBJ赋值。大致例如以下:

SRC_OBJ = $(patsubst %.c, $(OBJDIR)/%.o, $(notdir $(SRC_FILES)))                                                                                                                          

    这里用到函数patsubst、notdir,关于函数会在后面讲到。这样.o文件作为目标生成之后就会生成到对应文件夹里面了。

    此时再编译:

# make
make[1]: Entering directory `/home/Myprojects/example_make/version-2.9/src/ipc'
make[1]: *** No rule to make target `../../build/unix_dbg/obj/ipc/ipc.o', needed by `../../build/unix_dbg/lib/libipc.a'. Stop.
make[1]: Leaving directory `/home/Myprojects/example_make/version-2.9/src/ipc'
make: *** [ipc] Error 2
#

发现出错了。而且是在生成目标文件ipc.o时没有成功,查看build文件夹树也没有生成.o文件。为什么会生成失败呢?

我们没有给出生成.o目标的规则,之前能够生成是由于make有通过隐含规则来自己主动推导的能力(这个之前有讲到,链接过去)。在我们没有改动之前,生成.o通过隐含规则来完毕:

%.o: %.c
# commands to execute (built-in):
>---$(COMPILE.c) $(OUTPUT_OPTION) $<

由于全部的.o目标符合该规则,所以会自己主动推导生成.o文件。我们如今在..o前面加上路径后没有符合生成.o的隐含模式规则了,所以就没有生成该文件,导致编译出错。那怎么办呢?没有隐含模式规则,我们能够自己写符合生成该目标的模式规则。

模式规则类似于普通规则。仅仅是在模式规则中。目标文件是一个带有模式字符“%”的文件,使用模式来匹配目标文件。在目标文件名称中“%”匹配的部分称为“茎”。使用模式规则时,目标文件匹配之后得到“茎”,依赖依据“茎”产生相应的依赖文件,这个依赖文件必须是存在的或者可被创建的。

所以。我们添加一条模式规则例如以下:

$(OBJDIR)/%.o : %.c
>---$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

该模式规则中目标文件是$(OBJDIR)/%.o。那么如今有了符合生成我们须要的.o文件的规则了,编译一下:

# make
make[1]: Entering directory `/home/Myprojects/example_make/version-2.9/src/ipc'
make[1]: *** No rule to make target `../../build/unix_dbg/obj/ipc/ipc.o', needed by `../../build/unix_dbg/lib/libipc.a'. Stop.
make[1]: Leaving directory `/home/Myprojects/example_make/version-2.9/src/ipc'
make: *** [ipc] Error 2
#

发现还是不正确,不是已经添加了模式规则了吗。为何还是没有生成.o文件。



我们这里先说说静态模式规则:

    一个规则中能够有多个目标,规则所定义的命令对全部的目标有效。一个具有多目标的规则相当于多个规则。 规则的命令对不同的目标的运行效果不同, 由于在规则的命令中可能使用了自己主动化变量 “$@” 。

多目标规则意味着全部的目标具有同样的依赖文件。

多目标通经常使用在下面两种情况:尽管在多目标的规则中, 能够依据不同的目标使用不同的命令 (在命令行中使用自己主动化变量 “$@” )。可是, 多目标的规则并不能做到依据目标文件自己主动改变依赖文件 (像上边样例中使用自己主动化变量“$@”改变规则的命令一样) 。

须要实现这个目的是,要用到make的静态模式。

静态模式规则是这样一个规则:规则存在多个目标。 而且不同的目标能够依据目标文件的名字来自己主动构造出依赖文件。静态模式规则比多目标规则更通用。 它不须要多个目标具有同样的依赖。

可是静态模式规则中的依赖文件必须是相类似的而不是全然同样

的。

静态模式规则语法例如以下:

<targets ...>: <target-pattern>: <prereq-patterns ...>
<commands>
....

比方以下是一个静态模式规则:

objects = foo.o bar.o

all: $(objects)

$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@

该规则描写叙述了全部的.o文件的依赖文件为相应的.c文件,对于目标“foo.o” ,取其茎“foo”替代相应的依赖模式“%.c”中的模式字符“%”之后可得到目标的依赖文件“foo.c”。

这就是目标“foo.o”的依赖关系“foo.o: foo.c”。规则的命令行描写叙述了怎样完毕由“foo.c”编译生成目标“foo.o” 。

命令行中“$<”和“$@”是自己主动化变量,“$<” 表示规则中的第一个依赖文件, “$@” 表示规则中的目标文件。上边的这个规则描写叙述了下面两个详细的规则:

foo.o : foo.c
>---$(CC) -c $(CFLAGS) foo.c -o foo.o
bar.o : bar.c
>---$(CC) -c $(CFLAGS) bar.c -o bar.o

(注:该演示样例与其相关描写叙述摘抄于互联网,描写叙述非常不错,预计比我讲的具体)



    那静态模式规则和普通的模式规则(非静态模式规则)有什么去差别呢?两者都是用目标模式和依赖模式来构建目标的规则中的文件依赖关系,两者不同的地方是 make 在运行时使用它们的时机。

静态模式规则仅仅能用在规则中明白指出的那些文件的重建过程中。不能用在除此之外的不论什么文件的重建过程中。而且它对指定的每个目标来说是唯一的。

假设一个目标存在于两个规则,而且这两个规则都定义了命令, make 运行时就会提示错误。

非静态模式规则可被用在不论什么和它相匹配的目标上。当一个目标文件同一时候符合多个目标模式时,make将会把第一个目标匹配的模式规则作为重建它的规则。



    那有没有想过假设我们指定了模式规则后,那还有隐含规则呢。那怎么选择运行哪一个模式规则呢?Makefile中明白指定的模式规则会覆盖隐含模式规则。就是说假设在Makefile中出现了一个对目标文件合适可用的模式规则,那么make就不会再为这个目标文件寻找其他隐含规则,而直接使用在Makefile中出现的这个规则。在使用时。明白规则永远优先于隐含规则。

我们继续说之前的那个问题。我们定义了模式规则后还是没有生成.o文件,我们如今将其改为静态规则再试试就看,例如以下:

$(SRC_OBJ) : $(OBJDIR)/%.o : %.c
>---$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

运行后:

# make
make[1]: Entering directory `/home/Myprojects/example_make/version-2.9/src/ipc'
make[1]: *** No rule to make target `ipc.c', needed by `../../build/unix_dbg/obj/ipc/ipc.o'. Stop.
make[1]: Leaving directory `/home/Myprojects/example_make/version-2.9/src/ipc'
make: *** [ipc] Error 2
#

发现提示没有文件ipc.c。这说明没有生成.o的原因是没有.c文件,我非常好奇的是为何使用非静态模式为何不提示呢?(还没搞懂,再研究研究,知道的能够给个提示哈~~)

    缺少依赖文件。为何没有*.c文件,细致想想我们的.o文件没有和.c文件在同一文件夹。在我们project中,将源码和二进制文件(.o 文件和可运行文件)安排在不同的文件夹来进行区分管理。这样的情况下,我们能够使用 make 提供的文件夹搜索依赖文件功能。该功能在下一节讲述,这一节说的够多了,有点累了。可惜终于还是没有给出一个可用的Makefile,在下一节将得到。

版权声明:本文博主原创文章。博客,未经同意不得转载。假设你认为你的实际物品,请点击以下“最佳”。

从头开始编写项目Makefile(八):型号规则的更多相关文章

  1. 从头开始写项目Makefile(十):make内嵌函数及make命令显示【转】

    转自:http://blog.csdn.net/shallnet/article/details/38314473#comments 版权声明:本文为博主原创文章,未经博主允许不得转载.如果您觉得文章 ...

  2. 从头开始编写一个Orchard网上商店模块(3) - 创建Orchard.Webshop模块项目

    原文地址:http://skywalkersoftwaredevelopment.net/blog/writing-an-orchard-webshop-module-from-scratch-par ...

  3. 从头开始编写一个Orchard网上商店模块(6) - 创建购物车服务和控制器

    原文地址: http://skywalkersoftwaredevelopment.net/blog/writing-an-orchard-webshop-module-from-scratch-pa ...

  4. 从头开始编写一个Orchard网上商店模块(5) - 创建和渲染ProductCatalog的内容类型

    原文地址: http://skywalkersoftwaredevelopment.net/blog/writing-an-orchard-webshop-module-from-scratch-pa ...

  5. 从头开始编写一个Orchard网上商店模块(4) - 创建ProductPart

    原文地址:http://skywalkersoftwaredevelopment.net/blog/writing-an-orchard-webshop-module-from-scratch-par ...

  6. 从头开始编写一个Orchard网上商店模块(2) - 配置您的Orchard开发环境

    原文地址:http://skywalkersoftwaredevelopment.net/blog/writing-an-orchard-webshop-module-from-scratch-par ...

  7. Drools文档(八) 规则语言参考

    规则语言参考 概述 Drools有一个"本地"的规则语言.这种格式在标点符号上非常轻,并且通过"扩展器"支持自然语言和领域特定的语言,使语言能够变形到您的问题领 ...

  8. Drools 7.4.1.Final参考手册(八) 规则语言参考

    规则语言参考 概述 Drools有一个“本地”的规则语言.这种格式在标点符号上非常轻,并且通过“扩展器”支持自然语言和领域特定的语言,使语言能够变形到您的问题领域.本章主要与本机规则格式一致.用于表示 ...

  9. 转:从头开始编写基于隐含马尔可夫模型HMM的中文分词器

    http://blog.csdn.net/guixunlong/article/details/8925990 从头开始编写基于隐含马尔可夫模型HMM的中文分词器之一 - 资源篇 首先感谢52nlp的 ...

随机推荐

  1. [Network]Wireless and Mobile

    Wireless 1 Introduction 1.1 Elements 1. Wireless Hosts Wireless does not mean mobility. 2. Base Stat ...

  2. 一款新型的智能家居WiFi选择方案——SimpleWiFi在无线智能家居中的应用

    一款新型的智能家居WiFi选择方案——SimpleWiFi在无线智能家居中的应用 先上图:     随着科学技术的不断发展,局域网也正逐渐向无线化,多网合一的方向发展,在这个多网合一快速发展过程中,带 ...

  3. hdu4521 小明系列的问题——小明序列(LIS变种 (段树+单点更新解决方案))

    链接: huangjing 题目:中文题目 思路: 1:这个题目假设去掉那个距离大于d的条件,那么必定是一个普通的LIS.可是加上那个条件后就变得复杂了.我用的线段树的解法. . .就是採用延迟更新的 ...

  4. 提领NULL指针

    通常之中导致程序崩溃的最重要的原因是试图取消引用NULL指针.正如在以前的文章中指出,智能指针RefCountPtr和ScopedPtr它提供了一个诊断的执行时间. 但,并不是所有的指针是所有的对象都 ...

  5. ArrayBlockingQueue和LinkedBlockingQueue的区别

    ArrayBlockingQueue和LinkedBlockingQueue的区别,得出结论如下: 1. 队列中锁的实现不同 ArrayBlockingQueue实现的队列中的锁是没有分离的,即生产和 ...

  6. 不可不知的DIP、IoC、DI以及IoC容器

    面向对象设计(OOD)有助于我们开发出高性能.易扩展以及易复用的程序.当中.OOD有一个重要的思想那就是依赖倒置原则(DIP),并由此引申出IoC.DI以及Ioc容器等概念. 本文首先用实例阐述四个概 ...

  7. Mac中如何写NTFS的移动硬盘

    Mac中如何写NTFS的移动硬盘 按 照网上的说法,简单的就是购买Paragon NTFS或者Tuxera NTFS之类的收费软件,不想花钱的就用NTFS-3G.作为一个开发人员,既然能够自己解决,当 ...

  8. JqGrid 显示表

    JqGrid 下表显示了前台图书馆.使用起来非常方便. 我在这里分享使用中遇到的问题及解决方案 ** 一.rowNum属性 ** 1.假设不设置,默认显示数是20,也就是说超过20以后的数据.不再显示 ...

  9. 【足迹C++primer】40、动态数组

    动态数组 C++语言定义了第二种new表达式语法.能够分配并初始化一个对象数组.标准库中包括 一个名为allocator的类.同意我们将分配和初始化分离. 12.2.1 new和数组 void fun ...

  10. oracle之spool详细使用总结(转)

    今天实际项目中用到了spool,发现网上好多内容不是很全,自己摸索了好半天,现在总结一下. 一.通过spool 命令,可以将select 数据库的内容写到文件中,通过在sqlplus设置一些参数,使得 ...