linux小记:makefile(随使用程度持续更新)

原创 2016年05月21日 15:40:25

[我的笔记,仅限自己看懂=.=,也会随着我对makefile的需要程度和认知程度乱序更新]

格式

makefile的格式:

target : prerequisites 
  command  //任意的shell 命令

注意这个command可以是任意的shell命令

也就是说,如果

clean:
    echo "I love you"

当你在命令行中make clean的时候,只会显示I love you;而对于下面的makefile:

xixi:
    rm *.o

当在命令行中输入make xixi的时候,会执行rm *.o操作,删除所有的.o文件,起到我们心中所认为的clean的作用。

生成多个可执行程序

现在我们想生成两个完全不相依赖的程序:myServer和myClient。规则已经在makefile中写好,如下:

# Generated automatically from Makefile.in by configure.
CC=g++
CFLAGS=-g -I/usr/local/openssl/include/  -Wall
LD=-L/usr/local/openssl/lib  -lssl -lcrypto -ldl -lpthread
DISTDIR=Test

DIST=common.cpp \
    common.h \
    HttpProtocol.cpp \
    HttpProtocol.h \
    myServer.cpp \

myClient: myClient.c
    gcc -g -o myClient myClient.c -lssl -lcrypto -ldl
myServer: common.o myServer.o HttpProtocol.o
    $(CC) common.o myServer.o HttpProtocol.o -o myServer $(LD)
HttpProtocol.o: HttpProtocol.cpp
    g++ -g -c HttpProtocol.cpp
common.o: common.cpp
    g++ -g -c common.cpp
myServer.o: myServer.cpp
    g++ -g -c myServer.cpp

clean:  
    rm *.o
cleanAll:
    rm *.o myClient myServer

如果我们在命令行中输入make

lgl@pArch ~/tmp/SSL $ make
gcc -g -o myClient myClient.c -lssl -lcrypto -ldl
lgl@pArch ~/tmp/SSL $ 

只生成了myClient一个程序,而myServer完全没动静。这是因为makefile以最上面的目标文件为最终的目标。那么我们最终的目标就是myClient,生成myClient的先决条件(prerequisite)只需要myClient.c就够了,所以即使写好了myServer的生成规则,但是对于makefile来说,它认为这跟生成myClient有什么关系吗?并没有。那自然就不管了。
(插句广告,根据上面的知识,我们可以使用make myClientmake myServer分别生成myClient或myServer)
所以如果我们要生成两个目标程序,我们应该这样写:

# Generated automatically from Makefile.in by configure.
CC=g++
CFLAGS=-g -I/usr/local/openssl/include/  -Wall
LD=-L/usr/local/openssl/lib  -lssl -lcrypto -ldl -lpthread
DISTDIR=Test

DIST=common.cpp \
    common.h \
    HttpProtocol.cpp \
    HttpProtocol.h \
    myServer.cpp \

liuhaibo: myClient myServer #This decides the compiling order

myClient: myClient.c
    gcc -g -o myClient myClient.c -lssl -lcrypto -ldl
myServer: common.o myServer.o HttpProtocol.o
    $(CC) common.o myServer.o HttpProtocol.o -o myServer $(LD)
HttpProtocol.o: HttpProtocol.cpp
    g++ -g -c HttpProtocol.cpp
common.o: common.cpp
    g++ -g -c common.cpp
myServer.o: myServer.cpp
    g++ -g -c myServer.cpp

clean:  
    rm *.o
cleanAll:
    rm *.o myClient myServer

这样在make的时候就成功生成了myClient和myServer,为什么呢?

因为我们最终的目标是liuhaibo,而liuhaibo需要两个先决条件,myClient和myServer,所以makefile自然得先生成这两个先觉条件,于是myClient和myServer就被下面相应的规则生成出来了。然后你可能会奇怪在结束之后只有myClient和myServer,并没有生成liuhaibo这个文件啊!此时好好想想makefile的规则,然后再看我们新添加的这句话:

liuhaibo: myClient myServer 

target: liuhaibo
prerequisites: myClient和myServer
command: 无
所以并没有相应的shell命令,于是也就没有执行任何东西啦。
我们还可以来个更明显的现象,给它添加一个shell命令:

liuhaibo: myClient myServer
    touch "newFile_`date`"

于是:

lgl@pArch ~/tmp/SSL $ make
touch "newFile_`date`"
lgl@pArch ~/tmp/SSL $ make
touch "newFile_`date`"
lgl@pArch ~/tmp/SSL $ make
touch "newFile_`date`"
lgl@pArch ~/tmp/SSL $ ls newFile*  
'newFile_Sat May 21 15:14:51 CST 2016'
'newFile_Sat May 21 15:14:52 CST 2016'
'newFile_Sat May 21 15:14:53 CST 2016'

make一次,就运行一次touch "newFile_$(date)"一次,生成一个新文件。因为这条shell命令生成的是newFile_$(date),跟liuhaibo这个文件并没有关系,所以并没有生成liuhaibo这个文件。

当然啦,一般没人用liuhaibo这么逗比的名词的,一般大家都是用ALL或all,而且需要带上.PHONY,比如:

.PHONY: ALL
ALL: myClient myServer

.PHONY

A phony target is one that is not really the name of a file; rather it is just a name for a recipe to be executed when you make an explicit request. There are two reasons to use a phony target: to avoid a conflict with a file of the same name, and to improve performance.

If you write a rule whose recipe will not create the target file, the recipe will be executed every time the target comes up for remaking. Here is an example:

clean:
        rm *.o temp

Because the rm command does not create a file named clean, probably no such file will ever exist. Therefore, the rm command will be executed every time you say ‘make clean’.

In this example, the clean target will not work properly if a file named clean is ever created in this directory. Since it has no prerequisites, clean would always be considered up to date and its recipe would not be executed. To avoid this problem you can explicitly declare the target to be phony by making it a prerequisite of the special target .PHONY (see Special Built-in Target Names) as follows:

.PHONY: clean
clean:
        rm *.o temp

Once this is done, ‘make clean’ will run the recipe regardless of whether there is a file named clean.

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

hypertable使用小记,持续更新中。。。

Hypertable数据查询时的显示次序: 按rowkey升序显示;Cf按照表格创建时指定的次序显示;Cq按名称升序显示;value按照插入的次序倒序显示。   Cf索引和cq索引: cf索引:...

【持续更新中】makefile初阶使用心得

概述     简单的记录了一下,在使用makefile中遇到的一些问题。在之前记录一下 鸟哥书中的描述的make一些优点: 简化编译时所需要执行的命令若在编译完成之时,修改了某个源代码文件...

【持续更新】Android疑难杂症解决小记

在Android开发中,总会遇到许许多多的疑难杂症,各种google、baidu、StackOverFlow 上找答案,毕竟很多水答案混淆视听,本小记当中都是开发中遇到的坑和亲身实践的解决方案,如果有...

网页前端持续集成(2) - qunit+JSCoverage+PhantomJS使用小记

今年早些时候为公司项目做过一些网页前端程序的持续集成(CI),在过去的几个月中不断地给不同的人讲解过之后,我决定开一篇介绍一下。 公司项目是一个ASP.net的网站,其中核心是一些JavaScript...

Linux循序渐进学(更新程度:完毕)最给力的Linux入门视频教程

LAMP兄弟连价值2000元的Linux视频教程发布!知名Linux专家李明主讲!全套学习资料共享(视频教程+幻灯片+软件+代码示例+练习题+自测题)!循序渐进的讲解让你告别技术图书的纷繁复杂,无敌给...

Linux git使用方法杂记(持续更新...)

git使用方法杂记,查找某个文件某次修改记录

Linux内核中C和汇编使用技巧集锦 —— 持续更新

本文主要是用来存放Linux-3.1.1内核中有关C语言和汇编的使用技巧。在此所记录的一些技巧将会帮助有语言基础的童鞋写出更富艺术性和创造力的代码:-) 。需要注意的是,Linux内核采用GCC编译器...

linux系统下VIM使用小结(持续更新)

在ubuntu14.04下学习使用了vim,初次使用,学习了一些命令和实例,觉得学习起来太难,感觉只是将UI 一.linux内核源码

linux使用小记

由于之前一直使用windows做java开发,但是看一些招聘信息上会写在linux开发环境两年以上经验优先,而且公司有一部分从大公司来的开发全是清一色的ubuntu,所以为了提升一下自己的逼格,我打算...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)