链接外部目标文件时遇multiple definition与undefined reference错误求助
解决YCSB-C编译链接错误的实操指南
看来你在整合YCSB-C和CCEH时卡在了最后一步的链接环节,这两个错误其实是C/C++编译中很常见的问题,我帮你拆解一下原因并给出具体的修复步骤:
问题根源解析
你遇到的两个错误本质上都是链接阶段的符号冲突/缺失:
xxhash多重定义:CCEH/util/hash.h里的xxhash函数是直接在头文件里写的实现,既没加static也没加inline。这样一来,只要有两个.cc文件(这里是cceh_store.cc和CCEH_MSB.cc)包含了这个头文件,编译后两个目标文件里都会有xxhash的完整定义,链接器就会报错说符号重复。kWriteLatencyInNS未定义引用:这个变量在persist.h里应该只是用extern做了声明,但没有在任何.cc文件里实际定义它的实体,所以链接器找不到这个变量的具体实现。
一步步修复
1. 搞定xxhash的多重定义
打开CCEH/util/hash.h,找到第236行左右的xxhash函数,给它加上static修饰:
static unsigned long xxhash(const void* input, unsigned long length, unsigned long seed) { // 原来的函数实现代码不动 }
加static后,每个编译单元(也就是每个.cc文件)会生成自己的xxhash局部版本,不会在链接时打架。如果你用的是C++11及以上的编译器,也可以用inline代替static,效果是一样的。
2. 补上kWriteLatencyInNS的定义
先打开CCEH/util/persist.h,看看kWriteLatencyInNS的声明——大概率是类似这样的:
extern unsigned long kWriteLatencyInNS;
extern只是告诉编译器“这个变量在别的地方定义了”,但我们得真的给它找个地方定义。推荐直接在CCEH/src/CCEH_MSB.cc的开头(所有头文件include之后)加一行:
unsigned long kWriteLatencyInNS = 0; // 初始值可以根据你的需求调整
这样链接器就能找到这个变量的实体了。
3. 重新编译并链接
按照顺序重新跑一遍编译流程,注意最后一步的链接命令要确保包含CCEH_MSB.o:
- 先编译CCEH的目标文件:
cd CCEH/ # 要么执行你的Makefile(3),要么直接跑原命令 g++ -std=c++17 -I./ -lpthread -O3 -c -o src/CCEH_MSB.o src/CCEH_MSB.cpp -DINPLACE - 编译YCSB-C的db模块:
cd ../YCSB-C/db/ g++-8 -std=c++14 -c -g -Wall -pthread -I../ -I../../CCEH cceh_store.cc -o cceh_store.o - 最后链接生成ycsbc:
如果之前的Makefile(2)没加cd ../ # 确保你的Makefile(2)里的链接命令包含了../CCEH/src/CCEH_MSB.o,比如类似这样: g++-8 -std=c++14 -g -Wall -pthread ycsb.cc db/cceh_store.o ../CCEH/src/CCEH_MSB.o -o ycsbc -lpthread../CCEH/src/CCEH_MSB.o,一定要补上,不然还是会有未定义引用的问题!
额外注意事项
- 确认所有
-I参数的路径是对的,保证头文件能被正确找到; - CCEH用的是C17,YCSB-C用的是C14,只要代码本身兼容就没问题,不用特意统一版本;
- 链接时别忘了加
-lpthread,毕竟用到了多线程相关的代码。
内容的提问来源于stack exchange,提问作者nsane
相关产品推荐
相关产品推荐

