undefined reference to typeinfo for CmpInst

Hi all,

I am having some some trouble with LLVM 3.8... I built it with GCC 4.8.2 with cmake and no special CXX/C flags. That means in case of GCC that RTTI is switched on, I believe.

However, building my MCJIT application against the just built LLVM and linking results in:

libqdp.a(qdp_llvm.o):(.rodata._ZTIN4llvm8FCmpInstE[_ZTIN4llvm8FCmpInstE]+0x10): undefined reference to `typeinfo for llvm::CmpInst'
libqdp.a(qdp_jit_util.o):(.rodata._ZTIN4llvm16ExtractValueInstE[_ZTIN4llvm16ExtractValueInstE]+0x10): undefined reference to `typeinfo for llvm::UnaryInstruction'
libqdp.a(qdp_jit_util.o):(.rodata._ZTIN4llvm15InsertValueInstE[_ZTIN4llvm15InsertValueInstE]+0x10): undefined reference to `typeinfo for llvm::Instruction'
collect2: error: ld returned 1 exit status

I searched for this and there seem to be two common causes for this

1) There are virtual functions declared but never defined (I don't think that's the case, since LLVM has nightly tests)

2) Something's wrong with the RTTI settings.

I greped the LLVM source and it seems typeinfo is never used, so I though it's a good idea to build LLVM with RTTI switched off:

However, building LLVM with RTTI switched off (see build script below) results during the build in

/usr/bin/ld: ../../lib/libLLVMX86CodeGen.a(X86AsmPrinter.cpp.o): relocation R_X86_64_32S against `.rodata' can not be used when making a shared object; recompile with -fPIC
../../lib/libLLVMX86CodeGen.a: could not read symbols: Bad value
collect2: error: ld returned 1 exit status

I am not sure how to proceed from here..

Thanks,
Frank

SRC=$HOME/svn/llvm-3.8

CMAKE_BUILD_TYPE="Debug"
CMAKE_INSTALL_PREFIX="$HOME/toolchain/install/llvm-3.8"
LLVM_TARGETS_TO_BUILD="X86"

CXX="/dist/gcc-4.8.2/bin/g++"
CC="/dist/gcc-4.8.2/bin/gcc"

#-DBUILD_SHARED_LIBS="ON" \

cmake -G "Unix Makefiles" \
-DCMAKE_CXX_FLAGS="-fno-rtti" \
-DCMAKE_C_FLAGS="-fno-rtti" \
-DCMAKE_CXX_COMPILER=$CXX \
-DCMAKE_C_COMPILER=$CC \
-DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE \
-DCMAKE_INSTALL_PREFIX=$CMAKE_INSTALL_PREFIX \
-DLLVM_TARGETS_TO_BUILD=$LLVM_TARGETS_TO_BUILD \
$SRC

Solved. Recompiling LLVM with "-fno-rtti -fPIC" and building my application with "-fno-rtti" solved the issue.

As a result of this experiment I conclude that the LLVM library cannot be used in applications that make use of RTTI. I guess that's a bug.

Frank

Solved. Recompiling LLVM with "-fno-rtti -fPIC" and building my
application with "-fno-rtti" solved the issue.

LLVM should already set -fno-rtti by default. I think re-compiling your app
with -fno-rtti is what fixed the undefined typeinfo symbol errors.

It looks like you are linking LLVM static libs into a shared library, so
you also needed to build LLVM with -fPIC. The documented way of doing this
is to pass -DLLVM_ENABLE_PIC=ON to cmake.

As a result of this experiment I conclude that the LLVM library cannot be
used in applications that make use of RTTI. I guess that's a bug.

You can enable RTTI by passing -DLLVM_ENABLE_RTTI=ON to cmake. This is
documented here:
http://llvm.org/docs/CMake.html#llvm-specific-variables

It sounds like the real bug is "make the build documentation less
confusing". Sorry about that. =/

Hello,

I encountered a similar problem with the following classes: ICmpInst,
GetElementPtrInst and PHINode.

I noticed that there were no anchor functions, and the fact that I was using
RTTI in my project and LLVM disabled it, caused vtables and type infos of those
classes to be emitted in multiple translation units.

Since the LLVM Coding Standards require a `Virtual Method Anchor for Classes in
Headers` (http://llvm.org/docs/CodingStandards.html#provide-a-virtual-method-anchor-for-classes-in-headers),
I added the missing anchors to those classes (r255538).

Here is a similar patch for the classes that you mentioned:
http://reviews.llvm.org/D17467.

Cheers,

Hi Frank,

I am building LLVM 3.7.1 with RTTI and it works fine. I am using the following flags:

         cmake \
             -DCMAKE_BUILD_TYPE=Release \
             -DCMAKE_INSTALL_PREFIX=$(LLVM_DST) \
             -DLLVM_BUILD_TOOLS=OFF \
             -DLLVM_ENABLE_ASSERTIONS=ON \
             -DLLVM_ENABLE_RTTI=ON \
             -DLLVM_ENABLE_WERROR=ON \
             -DLLVM_REQUIRES_RTTI=ON \
             -DLLVM_TARGETS_TO_BUILD="X86" \
             -DLLVM_TARGET_ARCH="X86" \
             $(LLVM_SVN)

You apparently need to both use LLVM_ENABLE_RTTI=ON and LLVM_REQUIRES_RTTI=ON.

Cheers
Morten