[llvm-c] Proposal: Make LLVMInitializeNativeTarget and co. non-inline

Hi,

when building llvm as a shared library LLVMInitializeNativeTarget and co.
(located in llvm/Support/TargetSelect) will not get
exported as symbol into the shared library, because they are static inline.
Since they are functions defined in the C API no one else inside LLVM calls them,
which results in them not being exported.

This is, of course, no problem for C programs using the C API, because they get
these functions by simply doing #include on the headers; but for Non-C languages,
that are C compatible and want to use LLVM via the C API that is a problem,
because there's no way for them to get at these functions (other than
to write additional C code, which is not always desired).

Since LLVMInitializeNativeTarget and co. are functions in the C API,
do not get called by other LLVM functions and will likely be called
by user code only once at startup, there does not seem to be a fundamental
need for them to be inlined.

This is why I propose to make them non-inline, normal functions that
get declared in their current header and defined in lib/IR/Core.cpp.

The list of functions affected by this is:
void llvm::InitializeAllTargetInfos ()
void llvm::InitializeAllTargets ()
void llvm::InitializeAllTargetMCs ()
void llvm::InitializeAllAsmPrinters ()
void llvm::InitializeAllAsmParsers ()
void llvm::InitializeAllDisassemblers ()
bool llvm::InitializeNativeTarget ()
bool llvm::InitializeNativeTargetAsmPrinter ()
bool llvm::InitializeNativeTargetAsmParser ()
bool llvm::InitializeNativeTargetDisassembler ()

The reason why those are inline and can't be moved into Core.cpp is layering. All the individual target initialization routines are part of the target libraries, while Core.cpp is part of the IR library. The target libraries depend on the IR library, so calling an initialization routine from Core.cpp would give you a cyclic dependency and break the build.

The problem is now that we don't really have a place where we can put such a call without introducing a cycle. We could solve this by adding a new library that sits on top of all the targets (e.g. libLLVMAllTargets.a) and only contains the entry points for initializeAll*. I'm not entirely sure how much work this would be.

As a simpler workaround you can call the LLVMInitializeXXXTarget() functions manually for the targets you need, those are exported with C linkage.

- Ben