How to link llvm components, e.g. to use SmallVector?

The LLVM documentation discusses embedding LLVM in a project (which I plan to do for developing passes out of source):
https://llvm.org/docs/CMake.html#embedding-llvm-in-your-project

For linking libraries:

llvm_map_components_to_libnames(llvm_libs support core irreader)

# Link against LLVM libraries
target_link_libraries(simple-tool ${llvm_libs})

I’ve seen another example use the omnibus LLVM instead of the individual llvm_libs (which worked for me), but this is not always built (and if I’m reading docs correctly, the option to build this is called LLVM_BUILD_LLVM_DYLIB, which is turned off by default and not even available on Windows?).

In trying to build my project using the llvm_libs approach, I get errors such as:

undefined reference to `llvm::SmallVectorBase<unsigned int>::mallocForGrow(unsigned long, unsigned long, unsigned long&)'

I don’t see any documentation to find out what to link to use functionality such as LLVM’s data structures/the contents of ADT. I could perhaps write a script to iterate over these options and see if any work…

> llvm-config --components
aggressiveinstcombine all all-targets analysis asmparser asmprinter binaryformat bitreader bitstreamreader bitwriter cfguard codegen core coroutines coverage debuginfocodeview debuginfod debuginfodwarf debuginfogsym debuginfomsf debuginfopdb demangle dlltooldriver dwarflinker dwp engine executionengine extensions filecheck frontendopenacc frontendopenmp fuzzmutate globalisel instcombine instrumentation interfacestub interpreter ipo irreader jitlink libdriver lineeditor linker lto mc mca mcdisassembler mcjit mcparser mirparser native nativecodegen objcarcopts object objectyaml option orcjit orcshared orctargetprocess passes profiledata remarks runtimedyld scalaropts selectiondag support symbolize tablegen target textapi transformutils vectorize windowsmanifest x86 x86asmparser x86codegen x86desc x86disassembler x86info x86targetmca xray

Seems like core should have it?

> nm -g ~/.local/lib/libLLVMCore.a | grep mallocForGrow
                 U _ZN4llvm15SmallVectorBaseIjE13mallocForGrowEmmRm
                 U _ZN4llvm15SmallVectorBaseIjE13mallocForGrowEmmRm
                 U _ZN4llvm15SmallVectorBaseIjE13mallocForGrowEmmRm
                 U _ZN4llvm15SmallVectorBaseIjE13mallocForGrowEmmRm
                 U _ZN4llvm15SmallVectorBaseIjE13mallocForGrowEmmRm
                 U _ZN4llvm15SmallVectorBaseIjE13mallocForGrowEmmRm
                 U _ZN4llvm15SmallVectorBaseIjE13mallocForGrowEmmRm
                 U _ZN4llvm15SmallVectorBaseIjE13mallocForGrowEmmRm
                 U _ZN4llvm15SmallVectorBaseIjE13mallocForGrowEmmRm
                 U _ZN4llvm15SmallVectorBaseIjE13mallocForGrowEmmRm

However, adding core to the llvm_libs does not help.

Perhaps cmake is only looking for shared libraries? Not sure how to get it to look for static libraries.

The documentation explicitly recommends against building shared libraries of the components, and I don’t know cmake well enough to get it to look for the static libraries in a generic way, so for now I’ll just require libLLVM.

I also can’t really get LLVM built from source to work, and am having a hard time finding steps to do so.
I can compile trivial programs by adding flags

-I$(INSTALL_PREFIX)/include/c++/v1 -L$(INSTALL_PREFIX)/lib

but can’t get projects using cmake to actually work, e.g. adding these to the CXXFLAGS doesn’t help it find headers.

Everything “just works” if I use system libraries, but I have no idea how to libraries not installed by the package manager to actually work.
[EDIT: I got it to work, via adding linker paths, and disabling errors on unused command line arguments.]

Is there also a better place somewhere to ask for help?

g++ gave me a lot of warnings about std::move preventing copy elision, and removing the offending code did appear to improve performance in benchmarks.
clang++ gave no such warnings when I’d used it earlier, and I was curious how robust such optimizations are across compilers.

There is a difference in interpreting the C++ standard between GCC and Clang on copy-elision, depending on the version of the compilers one of them will warn one way and the other the other way unfortunately.

This is provided by the Support library.

2 Likes