免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2280 | 回复: 2

[C++] 这个 Makefile 下的生成最终二进制文件输出的环节有点问题 [复制链接]

论坛徽章:
0
发表于 2016-05-18 09:49 |显示全部楼层
本帖最后由 fuyinyuezhang 于 2016-05-18 13:56 编辑

先看下目录结构:

  1. # tree
  2. .
  3. ├── bin
  4. ├── Makefile
  5. ├── objs
  6. └── src
  7.     ├── Httpkit.cpp
  8.     ├── Httpkit.h
  9.     └── main.cpp
复制代码
然后是 Makefile 。其中我重新定义了 %.o:%.cpp 的规则,这样可以把生成的动态链接库文件放到 objs 目录下。

  1. CXX             = g++
  2. CXXFLAGS        = -std=c++11 -Wall -Werror
  3. CFLAGS          = -lcurl -lcurlpp
  4. SRC_DIR         = ./src
  5. OBJS_DIR        = ./objs
  6. BIN_DIR         = ./bin

  7. vpath %.cpp     $(SRC_DIR)
  8. vpath %.h       $(SRC_DIR)
  9. vpath %.o       $(OBJS_DIR)

  10. %.o:            %.cpp
  11.         $(CXX) $(CXXFLAGS) -c -o $(OBJS_DIR)/$@ $^

  12. .PHONY:         default clean

  13. default:        HttpKit
  14. main.o:         main.cpp
  15. Httpkit.o:      Httpkit.cpp
  16. HttpKit:        main.o Httpkit.o
  17.         $(CXX) $(CXXFLAGS) $(CFLAGS) -o $(BIN_DIR)/$@ $^

  18. clean:
  19.         -rm -rf $(OBJS_DIR)/*
  20.         -rm -rf $(BIN_DIR)/*
复制代码
执行 make 的结果:

  1. g++ -std=c++11 -Wall -Werror -c -o ./objs/main.o ./src/main.cpp
  2. g++ -std=c++11 -Wall -Werror -c -o ./objs/Httpkit.o ./src/Httpkit.cpp
  3. g++ -std=c++11 -Wall -Werror -lcurl -lcurlpp -o ./bin/HttpKit main.o Httpkit.o  #注意这行
  4. g++: error: main.o: No such file or directory
  5. g++: error: Httpkit.o: No such file or directory
  6. Makefile:21: recipe for target 'HttpKit' failed
  7. make: *** [HttpKit] Error 1
复制代码
上面我标注释的这行输出,虽然自动推导展开了依赖参数,但是依赖的路径完全没有按照 vpath 进行补全。奇怪的是,上面两个生成动态链接库(.o 后缀的文件)的规则也是这样的写法,却完全正确地补全了!

但是,此时 objs 目录下已经有了两个 .o 文件,再执行 make ,直接只有一行输出:

  1. g++ -std=c++11 -Wall -Werror -lcurl -lcurlpp -o ./bin/HttpKit ./objs/main.o ./objs/Httpkit.o
复制代码
WTF ?!?!?!

现在我有两个问题:
1 ,究竟为什么第一次 make 无法按照 vpath 变量的值自动展开路径,第二次直接就可以了?
2 ,生成最终二进制文件的命令能否也定义成隐含规则自动推导(这个意义不大,但是主要还是学习下 Makefile ,并且最终二进制文件并没有后缀名)?

src.rar (1.63 KB, 下载次数: 7)

论坛徽章:
0
发表于 2016-05-18 23:59 |显示全部楼层
HttpKit:        main.o Httpkit.o

这个依赖关系有问题,.o文件被你生成到OBJS_DIR里面去了,你就不能依赖本目录下的OBJS_DIR
而且你要把HttpKit放到BIN_DIR,前面也要加上。

$(BIN_DIR)/HttpKit :   $(OBJS_DIR)/main.o $(OBJS_DIR)/Httpkit.o

论坛徽章:
6
2015年辞旧岁徽章
日期:2015-03-05 16:13:092015年迎新春徽章
日期:2015-03-05 16:13:092015小元宵徽章
日期:2015-03-06 15:58:1815-16赛季CBA联赛之浙江
日期:2016-11-05 14:38:4115-16赛季CBA联赛之新疆
日期:2016-11-11 18:38:06
发表于 2016-05-19 08:44 |显示全部楼层
用VPATH变量试试:

VPATH = $(SRC_DIR) : $(OBJS_DIR) : $(BIN_DIR)
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP