最近在学习CS106B,学习的过程中免不了要完成一些作业,在完成作业的时候用到了makefile,这个地方卡了我很久,感觉有必要写下来方便以后温习。
主要背景:师兄分享的CS106B课程相关的material还算比较详尽,在其readme文档中清晰地交代了材料各部分文件的作用,起初以为这样做起来会非常轻松,但是实操起来发现还是有许多坑的。
首先按照readme提示,用CS106文件下现有的makefile编译生成静态链接库cs106lib.a,如下图所示:
哇大佬写的makefile就是不一样,一个make下去乖乖的生成了.a文件,接下来按照reademe中的提示来写:
实际编写如下:
运行结果:
感觉自己受到了欺骗......经过百度&&Google后,了解了makefile的基本语法以及编译原理,原来makefile中基本语句是:
A : B
C
其中A是打算生成的target,B是生成target的依赖,C是实现由B生成A的执行语句。明白这一点后我发现PROG依赖的OBJS没有生成,这应该是问题所在,讲到这里顺便提一下编译的过程:首先是通过.cpp和.h生成一个.o,由.o生成可执行文件。于是修改语句为:
编译结果如下:
结果只生成了一个.o文件,没有想要的可执行文件生成,这只能是warning中的问题了,什么overriding recipe for target,我也是丈二和尚摸不着头脑,但是仔细比较输出的编译命令就大概可以看出端倪,只执行了g++ -wall -c -g work1.3.cpp。也就是说,只有最下面的那一句指令被执行了,上面的
$(PROG) : $(OBJS)
$(CC) $(LFLAGS) $(OBJS) $(LIB) -o $(PROG)
根本没有执行,思来想去很久决定看一下大佬写的makefile学习一下,也就是之前CS106文件夹中的makefile,其源码如下:
然后我就发现了为啥它的OBJS都是分开单列的,而我的非要写成OBJS = $(PROG).o,再次更改makefile如下:
编译结果如下:
再在目录中查找,果然生成了work1.3的可执行文件,啊哈我也是会写makefile的人嘞,插会腰。但是为什么会这样呢,我认为一般来讲OBJS里面一般不止一个.o文件,如果直接写$(OBJS),一旦里面需要生成很多.o,这个指令就会出错,既然大佬都是把.o一个一个掏出来写的,我为什么不也这样写呢,果然,仿写之后就成功了,又说明了看大佬的代码进步快呀!
网友评论