Xiaowo

I Lay My Love On You~

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

[我的笔记,仅限自己看懂=.=,也会随着我对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.

阅读更多
版权声明:本文为博主原创文章,欢迎转载欢迎传播,注不注明出处随你,只要对更多人有所帮助就行。 https://blog.csdn.net/puppylpg/article/details/51470746
文章标签: makefile
个人分类: linux C/C++
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭