为什么"多个定义链接器错误"当nm只看到一个定义时

时间:2015-07-16 23:04:55

标签: c++ linker linker-errors

当将一些目标文件链接在一起时,我得到了一堆错误,如:

obj-ia32/ShadowRoutine.o: In function `InitializeMap(unsigned int*)':
ShadowRoutine.cpp:(.text+0x0): multiple definition of `InitializeMap(unsigned int*)'
obj-ia32/ShadowRoutine.o:ShadowRoutine.cpp:(.text+0x0): first defined here

使用以下编译和链接命令:

g++ -DBIGARRAY_MULTIPLIER=1 -Wall -Wno-unknown-pragmas -fno-stack-protector \
    -DTARGET_IA32 -DHOST_IA32 -DTARGET_LINUX  -I../../../source/include/pin \
    -I../../../source/include/pin/gen -I../../../extras/components/include \
    -I../../../extras/xed-ia32/include -I../../../source/tools/InstLib -O3 \
    -fomit-frame-pointer -fno-strict-aliasing -Wno-unused-variable \
    -Wno-unused-function -I. -Ishadow-memory -m32 -c \
    -o obj-ia32/ShadowRoutine.o ShadowRoutine.cpp
g++ -DBIGARRAY_MULTIPLIER=1 -Wall -Wno-unknown-pragmas -fno-stack-protector \
    -DTARGET_IA32 -DHOST_IA32 -DTARGET_LINUX  -I../../../source/include/pin \
    -I../../../source/include/pin/gen -I../../../extras/components/include \
    -I../../../extras/xed-ia32/include -I../../../source/tools/InstLib -O3 \
    -fomit-frame-pointer -fno-strict-aliasing -Wno-unused-variable \
    -Wno-unused-function -I. -Ishadow-memory -m32 -c \
    -o obj-ia32/Jikes.o Jikes.cpp
g++ -shared -Wl,--hash-style=sysv -Wl,-Bsymbolic \
    -Wl,--version-script=../../../source/include/pin/pintool.ver \
    -m32 -o obj-ia32/Jikes.so obj-ia32/ClientReq.o obj-ia32/Server.o \
    obj-ia32/ShadowRoutine.o obj-ia32/FncnMap.o obj-ia32/Trace.o \
    obj-ia32/Jikes.o obj-ia32/ClientReq.o obj-ia32/Server.o \
    obj-ia32/ShadowRoutine.o obj-ia32/FncnMap.o obj-ia32/Trace.o \
    -L../../../ia32/lib -L../../../ia32/lib-ext -L../../../ia32/runtime/glibc \
    -L../../../extras/xed-ia32/lib \
    -L/home/karl/r/git/pin/source/tools/Jikes/zmq/inst/lib \
    -lpin -lxed -lpindwarf -ldl -lzmq

InitializeMap只有Jikes.oShadowRoutine.o的唯一两个目标文件:

$ nm obj-ia32/Jikes.o  | grep InitializeMap
         U _Z13InitializeMapPj
$ nm obj-ia32/ShadowRoutine.o | grep InitializeMap
00000000 T _Z13InitializeMapPj
$ nm obj-ia32/* | grep InitializeMap
         U _Z13InitializeMapPj
00000000 T _Z13InitializeMapPj

那么为什么我会得到InitializeMap"的多个定义?如果只是"定义"在一个目标文件和" undefined"在使用extern

的唯一其他目标文件中

这是声明,定义和用法的样子:

$ grep -r InitializeMap *
Jikes.cpp:  if (rtn_name == "sysInitializeMap") {       RTN_INSERT_1(InitializeMap);
Binary file obj-ia32/Jikes.o matches
Binary file obj-ia32/ShadowRoutine.o matches
ShadowRoutine.cpp:VOID InitializeMap(ADDRINT *smID) { init_map(*(int*)smID); }
ShadowRoutine.hpp:VOID InitializeMap(ADDRINT *smID);

两个cpp文件#include "ShadowRoutine.hpp"

编辑:我的问题是为什么链接器命令(上面第二个代码片段中的第三个g ++命令)不起作用,即使nm表示该函数仅在ShadowRoutine.o的文本中定义Jikes.o中的 undefined

1 个答案:

答案 0 :(得分:4)

您在链接命令中列出了两次文件obj-ia32/ShadowRoutine.o