使用带有检查器的 Makefile 构建 clang 时出现链接器错误



我在链接阶段遇到了问题。

我想做什么?

我正在尝试添加一个检查器来叮当响。我从源代码构建了LLVM和libc ++(是的,在构建后的libcxx测试期间,某些测试失败了)。为了识别libc++库,我将以下代码添加到Clang的根目录Makefile中。

CXX.Flags += -stdlib=libc++
CXX.Flags += -std=c++11
CXX.Flags += -nostdinc++
CXX.Flags += -I/path/to/my/own/c++library/libcxx/include
LD.Flags += -L/path/to/my/own/c++library/libcxx/lib

链接器问题浮出水面如下。

Undefined symbols for architecture x86_64:
"std::__1::__shared_weak_count::__get_deleter(std::type_info const&) const", referenced from:
      vtable for std::__1::__shared_ptr_p-traits<char> >& std::__1::operator<<<std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*) in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<<<char, std::__1::char_traits<char>, std::__1::allocator<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
      std::__1::regex_traits<char>::__init() in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
  "std::__1::ios_base::getloc() const", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<<<std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*) in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<<<char, std::__1::char_traits<char>, std::__1::allocator<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
  "std::__1::__get_classname(char const*, bool)", referenced from:
      unsigned int std::__1::regex_traits<char>::__lookup_classname<char const*>(char const*, char const*, bool, char) const in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
  "std::__1::__shared_weak_count::__add_shared()", referenced from:
      std::__1::basic_regex<char, std::__1::regex_traits<char> >::basic_regex(std::__1::basic_regex<char, std::__1::regex_traits<char> > const&) in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
  "std::__1::__shared_weak_count::__release_shared()", referenced from:
      std::__1::shared_ptr<std::__1::__empty_state<char> >::~shared_ptr() in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
  "std::__1::__shared_weak_count::~__shared_weak_count()", referenced from:
      std::__1::__shared_ptr_pointer<std::__1::__empty_state<char>*, std::__1::default_delete<std::__1::__empty_state<char> >, std::__1::allocator<std::__1::__empty_state<char> > >::~__shared_ptr_pointer() in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
  "std::__1::__get_collation_name(char const*)", referenced from:
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > std::__1::regex_traits<char>::__lookup_collatename<char const*>(char const*, char const*, char) const in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > std::__1::regex_traits<char>::__lookup_collatename<char*>(char*, char*, char) const in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
  "std::__1::cout", referenced from:
      (anonymous namespace)::ObjCSelfInitChecker::checkPreStmt(clang::ObjCStringLiteral const*, clang::ento::CheckerContext&) const in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
  "std::__1::ctype<char>::id", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<<<std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*) in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<<<char, std::__1::char_traits<char>, std::__1::allocator<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
      std::__1::regex_traits<char>::__init() in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
  "std::__1::locale::locale(std::__1::locale const&)", referenced from:
      std::__1::basic_regex<char, std::__1::regex_traits<char> >::__start_matching_list(bool) in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
      std::__1::regex_traits<char>::regex_traits(std::__1::regex_traits<char> const&) in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
  "std::__1::locale::locale()", referenced from:
      std::__1::regex_traits<char>::regex_traits() in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
  "std::__1::locale::~locale()", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<<<std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*) in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
      std::__1::regex_traits<char>::~regex_traits() in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<<<char, std::__1::char_traits<char>, std::__1::allocator<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
      std::__1::basic_regex<char, std::__1::regex_traits<char> >::__start_matching_list(bool) in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
  "std::__1::collate<char>::id", referenced from:
      std::__1::regex_traits<char>::__init() in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
  "std::__1::ios_base::clear(unsigned int)", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<<<std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*) in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
      std::__1::basic_ostream<char, std::__1::char_traits<char> >::put(char) in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
      std::__1::basic_ostream<char, std::__1::char_traits<char> >::flush() in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
      std::__1::basic_ostream<char, std::__1::char_traits<char> >::sentry::~sentry() in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<<<char, std::__1::char_traits<char>, std::__1::allocator<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
  "vtable for std::__1::__shared_count", referenced from:
      std::__1::shared_ptr<std::__1::__empty_state<char> >::shared_ptr<std::__1::__empty_state<char>, void>(std::__1::__empty_state<char>*) in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for std::__1::__shared_weak_count", referenced from:
      std::__1::shared_ptr<std::__1::__empty_state<char> >::shared_ptr<std::__1::__empty_state<char>, void>(std::__1::__empty_state<char>*) in libclangStaticAnalyzerCheckers.a(ObjCSelfInitChecker.o)
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [/Users/msecurity/Documents/Deepak/Eclipse/clang_build/build/Debug+Asserts/bin/clang] Error 1
make[1]: *** [driver/.makeall] Error 2
make: *** [all] Error 1

我按照链接器的建议使用 -v 选项查看链接器调用,并得到以下输出。

"/usr/bin/ld" -demangle -dynamic -arch x86_64 -macosx_version_min 10.8.0 -o /path/to/onw/clang/build/Debug+Asserts/bin/clang -L/path/to/onw/clang//build/Debug+Asserts/lib -L/path/to/onw/clang/build/Debug+Asserts/lib -L/path/to/libc++/build/libcxx/lib -rpath @executable_path/../lib -sectcreate __TEXT __info_plist /path/to/onw/clang/build/tools/clang/tools/driver/Debug+Asserts/Info.plist /path/to/onw/clang/build/tools/clang/tools/driver/Debug+Asserts/cc1_main.o /path/to/onw/clang/build/tools/clang/tools/driver/Debug+Asserts/cc1as_main.o /path/to/onw/clang/build/tools/clang/tools/driver/Debug+Asserts/driver.o -lclangFrontendTool -lclangFrontend -lclangDriver -lclangSerialization -lclangCodeGen -lclangParse -lclangSema -lclangStaticAnalyzerFrontend -lclangStaticAnalyzerCheckers -lclangStaticAnalyzerCore -lclangARCMigrate -lclangRewriteFrontend -lclangRewriteCore -lclangAnalysis -lclangEdit -lclangAST -lclangBasic -lclangLex -lLLVMOption -lLLVMLinker -lLLVMIRReader -lLLVMipo -lLLVMVectorize -lLLVMInstrumentation -lLLVMBitWriter -lLLVMBitReader -lLLVMAsmParser -lLLVMR600CodeGen -lLLVMR600Desc -lLLVMR600Info -lLLVMR600AsmPrinter -lLLVMSystemZDisassembler -lLLVMSystemZCodeGen -lLLVMSystemZAsmParser -lLLVMSystemZDesc -lLLVMSystemZInfo -lLLVMSystemZAsmPrinter -lLLVMHexagonCodeGen -lLLVMHexagonAsmPrinter -lLLVMHexagonDesc -lLLVMHexagonInfo -lLLVMNVPTXCodeGen -lLLVMNVPTXDesc -lLLVMNVPTXInfo -lLLVMNVPTXAsmPrinter -lLLVMCppBackendCodeGen -lLLVMCppBackendInfo -lLLVMMSP430CodeGen -lLLVMMSP430Desc -lLLVMMSP430Info -lLLVMMSP430AsmPrinter -lLLVMXCoreDisassembler -lLLVMXCoreCodeGen -lLLVMXCoreDesc -lLLVMXCoreInfo -lLLVMXCoreAsmPrinter -lLLVMMipsDisassembler -lLLVMMipsCodeGen -lLLVMMipsAsmParser -lLLVMMipsDesc -lLLVMMipsInfo -lLLVMMipsAsmPrinter -lLLVMARMDisassembler -lLLVMARMCodeGen -lLLVMARMAsmParser -lLLVMARMDesc -lLLVMARMInfo -lLLVMARMAsmPrinter -lLLVMAArch64Disassembler -lLLVMAArch64CodeGen -lLLVMAArch64AsmParser -lLLVMAArch64Desc -lLLVMAArch64Info -lLLVMAArch64AsmPrinter -lLLVMAArch64Utils -lLLVMPowerPCCodeGen -lLLVMPowerPCAsmParser -lLLVMPowerPCDesc -lLLVMPowerPCInfo -lLLVMPowerPCAsmPrinter -lLLVMSparcCodeGen -lLLVMSparcDesc -lLLVMSparcInfo -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMMCParser -lLLVMCodeGen -lLLVMObjCARCOpts -lLLVMScalarOpts -lLLVMInstCombine -lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMX86Desc -lLLVMX86Info -lLLVMTarget -lLLVMX86AsmPrinter -lLLVMMC -lLLVMObject -lLLVMX86Utils -lLLVMCore -lLLVMSupport -lz -lpthread -lcurses -lm -lstdc++ -lSystem /usr/bin/../lib/clang/4.2/lib/darwin/libclang_rt.osx.a

观察到它使用的是我为其构建的 C++11 库,因为它是上述调用中 ld 的第 6 个选项。还有其他我应该照顾的选择吗?

试图用谷歌搜索是否有任何可用的解决方案,我发现这种缺少非内联虚拟函数的 vtable 条目的问题存在于早期版本的 llvm 中,使用最新版本可以帮助其他人。但是我已经在使用llvm最新版本。以下是 clang -v 输出

CLANG 版本 3.4 (中继 192102) (LLVM/中继 192100)目标:x86_64-苹果-达尔文12.3.0螺纹型号:磅

请指导我解决问题的可能方法。如果我需要分享更多详细信息,请告诉我。如果我以任何方式违反了任何约定或规范(这是我在 StackOverflow 上的第一个问题),我很抱歉,请告诉我。

请注意:我之前添加了一个检查器,它工作正常并实现了我的目的。当我尝试包含标准C++标头<regex>以扩展相同的检查器时,上述所有问题都引起了。

正如您在链接器 cmdline 中看到的,您正在尝试使用 libstdc++ (-lstdc++) 进行链接。因此,您将使用 libc++ 编译的对象与 libstdc++ 混合在一起。

问题已解决。使用以下配置选项编译LLVM帮助我解决了该问题。

../llvm/configure CXXFLAGS="-stdlib=libc++ -std=c++11" OBJCXXFLAGS="-stdlib=libc++ -std=c++11" LDFLAGS="-stdlib=libc++"

也许有一天它会帮助某人。谢谢大家。

最新更新