[LLVMdev] Static linking of execution engine

Kaylor, Andrew
Wed, 22 May 2013 20:04:43 -0000

Hi Mario,

It turns out that this isn't a problem with the static constructor at all.

EngineBuilder::create() is calling dlopen (by way of
sys::DynamicLibrary::loadLibraryPermanently) with a zero argument to get a
handle the current module, which the default memory manager may later use for
external symbol resolution.  Because in your case the program is statically
linked, the call to dlopen fails (errno says the executable couldn't be
found in the dynamic linker's module load list).  When this happens
EngineBuilder::create() also fails.

In reality, the EngineBuilder code shouldn't be doing that.  If it is needed
at all the memory manager should be doing it.  If you comment out that call in
the EngineBuilder code, your test case will successfully create the JIT engine.
However, you might have subsequent problems with external symbol resolution.  In
that case, you would need to implement a memory manager that knew how to resolve
the missing symbols.

If you prefer not to modify the LLVM code, you can also work around this problem
by using ExecutionEngine::createJIT(), which does not make the dlopen check.  I
suspect that code path is not well tested, so there may be additional problems
if you do things that way.

-Andy

-----Original Message-----
From: Mario Schwalbe [mailto:m3o.s6e at googlemail.com]
Sent: Wednesday, May 22, 2013 11:30 AM
To: Kaylor, Andrew
Cc: Mario Schwalbe; LLVM Devel
Subject: Re: [LLVMdev] Static linking of execution engine

Am 22.05.13 19:32, schrieb Kaylor, Andrew:
> If you send me details about how you're building this I'll look
into it.

Thanks. I forgot to mention it's LLVM 3.2 on Ubuntu 12.10. The command line
is:

$ g++-4.7 ExecutionEngineTest.cpp $(llvm-config --cxxflags --ldflags --libs)
-lpthread -ldl $ g++-4.7 -static ExecutionEngineTest.cpp $(llvm-config
--cxxflags --ldflags --libs) -lpthread -ldl

The -lpthread -ldl is there explicitly because llvm-config prints them as part
of --ldflags before the dependent LLVM libs.

The first of the above commands works well. The second one does not.

ciao,
Mario