[LLVMdev] How to best add a dependency on libopagent.a/so?

Jeffrey Yasskin
2009-07-01T22:02:08Z

I'm adding OProfile support to the JIT (patch at
http://codereview.appspot.com/89041), and I'm running into trouble
with getting llvm-config to print the right things to let external
programs link.

For some background, oprofile installs an agent library into
<prefix>/lib/oprofile/libopagent.{a,so}. This isn't on the
loader's
default search path, even if <prefix>==/usr, so to link with the .so
we also need a -rpath flag to the linker. To avoid that, I'm
tentatively using the .a.

In configure, behind a --with-oprofile argument, I have:
  LIBS="$LIBS ${llvm_cv_oppath}/libopagent.a -lbfd -liberty -ldl"
This causes llvm-config to print:

$ ./Debug/bin/llvm-config --libs --ldflags --cxxflags
-L/usr/local/google/jyasskin/llvm/oprof/dbg/Debug/lib  -lpthread -lffi
-ldl -lm  /usr/local/lib/oprofile/libopagent.a -lbfd -liberty -ldl
-I/usr/local/google/jyasskin/llvm/oprof/dbg/../src/include  -D_DEBUG
-D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -g -fPIC
-Woverloaded-virtual
-lLLVMXCore -lLLVMSparcAsmPrinter -lLLVMSparcCodeGen
-lLLVMPowerPCAsmPrinter -lLLVMPowerPCCodeGen -lLLVMPIC16 -lLLVMMSP430
-lLLVMMSIL -lLLVMMipsAsmPrinter -lLLVMMipsCodeGen -lLLVMLinker
-lLLVMipo -lLLVMInterpreter -lLLVMInstrumentation -lLLVMIA64AsmPrinter
-lLLVMIA64CodeGen -lLLVMJIT -lLLVMExecutionEngine -lLLVMDebugger
-lLLVMCppBackend -lLLVMCellSPUAsmPrinter -lLLVMCellSPUCodeGen
-lLLVMCBackend -lLLVMBitWriter -lLLVMX86AsmPrinter -lLLVMX86CodeGen
-lLLVMMC -lLLVMAsmParser -lLLVMARMAsmPrinter -lLLVMARMCodeGen
-lLLVMArchive -lLLVMBitReader -lLLVMAlphaAsmPrinter -lLLVMAlphaCodeGen
-lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMCodeGen -lLLVMScalarOpts
-lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMTarget -lLLVMCore
-lLLVMSupport -lLLVMSystem


However, this isn't right if we want to build a program like lli:

$ g++ ../src/tools/lli/lli.cpp  `./Debug/bin/llvm-config --cxxflags
--ldflags --libs` -I`pwd`/include
/usr/local/google/jyasskin/llvm/oprof/dbg/Debug/lib/libLLVMJIT.a(OProfileJITEventListener.o):
In function `(anonymous
namespace)::OProfileJITEventListener::NotifyFreeingMachineCode(llvm::Function
const&, void*)':
/usr/local/google/jyasskin/llvm/oprof/src/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp:85:
undefined reference to `op_unload_native_code'
...

(This is the lli.cpp after my patch, and the -I`pwd`/include is to
work around http://llvm.org/PR4481)

It works if I include libopagent.a after the libs:

$ g++ ../src/tools/lli/lli.cpp  `./Debug/bin/llvm-config --cxxflags
--ldflags --libs` /usr/local/lib/oprofile/libopagent.a -I`pwd`/include
$

So, how do I use the build system to tell llvm-config to print the
right output? If I change llvm-config to print the --ldflags output
after the --libs output, this works, but I presume they're in the
current order for some reason. Or is that reversal the right way to
fix this?

So, what's the Right Way (tm) to do this?

Thanks!
Jeffrey