【问题标题】:Clang Linking error: undefined reference to function calls added by LLVM passClang 链接错误:对 LLVM 传递添加的函数调用的未定义引用
【发布时间】:2017-01-14 13:17:43
【问题描述】:

所以我正在关注本教程https://www.cs.cornell.edu/~asampson/blog/llvm.html 通过添加对外部函数(在 rtlib.c 中为 logop)的调用来检测程序。但与本教程不同的是,我试图检测一个更大的代码库,即 masstree:https://github.com/kohler/masstree-beta。

所以按照 masstree 的指示,我首先运行 ./configure,然后编辑生成的 Makefile 以使用 clang(而不是 gcc/g++)并运行我的通行证。我还在masstree 源文件中添加了rtlib.c,以便它与其余masstree 源文件一起转换为rtlib.o。这是修改后的 Makefile 的相关部分,我的更改用箭头突出显示(我还添加了 $(rtlib) 以将其与其他 .o 文件链接以生成可执行文件):

AR = ar
rtlib = rtlib.o  <===
CC2 = clang -w -v -Xclang -load -Xclang  /.../llvm-3.4/Release+Asserts/lib/SkeletonPass.so `llvm-config --cflags` 
CXX2 = clang++ -v -w -Xclang -load -Xclang /.../llvm-3.4/Release+Asserts/lib/SkeletonPass.so -std=c++11 `llvm-config --cppflags --libs --cflags --cxxflags core --ldflags` <===
CC = clang -v <===
CXX = clang++ -v -std=c++11 <===
CPPFLAGS = 
CXXFLAGS = -g -W -Wall -O3
DEPSDIR := .deps
DEPCFLAGS = -MD -MF $(DEPSDIR)/$*.d -MP
ifeq ($(strip $(MEMMGR)), )
  MEMMGR = 
endif
ifneq ($(strip $(KEYSWAP)), )
  CPPFLAGS += -DKEYSWAP
endif
ifneq ($(strip $(NOPREFETCH)), )
  CPPFLAGS += -DNOPREFETCH
endif
ifneq ($(strip $(NOSUPERPAGE)), )
  CPPFLAGS += -DNOSUPERPAGE
endif
LIBS =  -lpthread -lm
LDFLAGS = 

all: test_atomics mtd mtclient mttest

%.o: %.c config.h $(DEPSDIR)/stamp
    $(CXX2) $(CPPFLAGS) $(CXXFLAGS) $(DEPCFLAGS) -include config.h -c -o $@ $<

%.o: %.cc config.h $(DEPSDIR)/stamp
    $(CXX2) $(CPPFLAGS) $(CXXFLAGS) $(DEPCFLAGS) -include config.h -c -o $@ $<

%.S: %.o
    objdump -S $< > $@

libjson.a: json.o string.o straccum.o str.o msgpack.o \
    clp.o kvrandom.o compiler.o memdebug.o kvthread.o
    @/bin/rm -f $@
    $(AR) cru $@ $^

KVTREES = query_masstree.o \
    value_string.o value_array.o value_versioned_array.o \
    string_slice.o

mtd: mtd.o log.o checkpoint.o file.o misc.o $(rtlib) $(KVTREES) \
    kvio.o libjson.a
    $(CXX) $(CXXFLAGS) -o $@ $^ $(MEMMGR) $(LDFLAGS) $(LIBS)

mtclient: mtclient.o misc.o testrunner.o kvio.o $(rtlib) libjson.a
    $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS)

mttest: mttest.o misc.o checkpoint.o $(rtlib) $(KVTREES) testrunner.o \
    kvio.o libjson.a
    $(CXX) $(CXXFLAGS) -o $@ $^ $(MEMMGR) $(LDFLAGS) $(LIBS)

test_string: test_string.o string.o $(rtlib) straccum.o compiler.o
    $(CXX) $(CXXFLAGS) -o $@ $^ $(MEMMGR) $(LDFLAGS) $(LIBS)

test_atomics: test_atomics.o string.o straccum.o kvrandom.o $(rtlib) \
    json.o compiler.o kvio.o
    $(CXX) $(CXXFLAGS) -o $@ $^ $(MEMMGR) $(LDFLAGS) $(LIBS)

jsontest: jsontest.o string.o straccum.o json.o compiler.o $(rtlib)
    $(CXX) $(CXXFLAGS) -o $@ $^ $(MEMMGR) $(LDFLAGS) $(LIBS)

msgpacktest: msgpacktest.o string.o straccum.o json.o compiler.o msgpack.o $(rtlib)
    $(CXX) $(CXXFLAGS) -o $@ $^ $(MEMMGR) $(LDFLAGS) $(LIBS)

scantest: scantest.o compiler.o misc.o $(rtlib) $(KVTREES) libjson.a
    $(CXX) $(CXXFLAGS) -o $@ $^ $(MEMMGR) $(LDFLAGS) $(LIBS)

我使用 CC2 和 CXX2 生成检测的 .o 文件,而 CC 和 CXX 将它们链接到可执行文件中。这是我运行 make 时遇到的错误:

mtd.o:在函数main': /home/.../masstree-beta-master/mtd.cc:730: undefined reference tologop' /home/.../masstree-beta-master/mtd.cc:730:未定义对logop' /home/.../masstree-beta-master/mtd.cc:732: undefined reference tologop'的引用 /home/.../masstree-beta-master/mtd.cc:732:未定义对logop' /home/.../masstree-beta-master/mtd.cc:736: undefined reference tologop'的引用 mtd.o:/home/.../masstree-beta-master/mtd.cc:736:更多未定义的“logop”引用如下 clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用) make: *** [mtd] 错误 1。

关于为什么对我的函数 logop(在 rtlib.c 中)的引用未定义,即使我在链接部分添加 rtlib.o 以生成可执行文件有什么想法吗?

非常感谢!

【问题讨论】:

  • 可能的想法: 1)将rtlib.o放在目标文件的末尾进行链接。 2) 使用 C++ 编译器构建 rtlib.o。 3) 检查 rtlib.o 是否正在导出函数 (objdump -t)。 4) 检查 mtd.o 中的符号是否与 rtlib.o 中导出的符号匹配。
  • 感谢您的回复!我使用 objdump -S 检查了 mtd.o,但找不到对我的外部函数 logop(int, int, char) 的调用。这让我感到困惑,因为我认为错误 undefined reference to logop' 意味着插入了函数调用,但链接器找不到函数 logop 的定义,而且第 730 和 732 行等是我希望插入 logop 的行。跨度>
  • @Brian,我上次发表评论后有什么想法吗?
  • 预链接,程序集可能没有对外部函数的调用,因为它的地址尚不清楚。相反,有通用的调用说明:callq 14(在我的快速测试中将变为 gets())。我可以看到,使用 objdump -t,在获取的目标文件中有一个未定义的符号。
  • @Brian,我现在实际上正在考虑分解链接过程并将 mtd.o 链接到 rtlib.o 以首先制作 mtd-intermediate.o 然后链接 mtd-intermediate.o 和其他需要的.o 文件以使 mtd 可执行。

标签: makefile llvm clang++ llvm-clang llvm-ir


【解决方案1】:

导出的符号不一样。我使用nm --format sysv *file.o* 进行了检查,以确保从 rtlib.o 导出的符号以及使用它们的位置是相同的。

【讨论】:

    猜你喜欢
    • 2017-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-02
    • 1970-01-01
    • 1970-01-01
    • 2017-11-27
    • 2023-03-29
    相关资源
    最近更新 更多