Search code examples
c++macosclangld

linker (ld) on OS X: How to use -Wl,--start-group (and --end-group)?


I am building some projects externally which use libclang static libs.

Linking fails like this:

ld: unknown option: --start-group
clang: error: linker command failed with exit code 1 (use -v to see invocation)

The reason I need to use this is because of circular dependencies (or as it turns out, I guess because of not knowing the correct library order).

So far I have to resort to taking the -Wl,--{start,end}-group out of the makefile, looking at the undefined symbols error list, finding the libs that have them with nm, and appending them manually to the library list (so they appear more than once in the library list).


Solution

  • The correct order of LLVM/Clang libs (taken from my own project that uses it) for 3.5 is:

        "clangFrontend",
        "clangSerialization",
        "clangDriver",
        "clangTooling",
        "clangCodeGen",
        "clangParse",
        "clangSema",
        "clangAnalysis",
        "clangRewriteFrontend",
        "clangRewrite",
        "clangEdit",
        "clangAST",
        "clangLex",
        "clangBasic",
        "LLVMLTO",
        "LLVMObjCARCOpts",
        "LLVMLinker",
        "LLVMipo",
        "LLVMVectorize",
        "LLVMBitWriter",
        "LLVMIRReader",
        "LLVMAsmParser",
        "LLVMR600CodeGen",
        "LLVMR600Desc",
        "LLVMR600Info",
        "LLVMR600AsmPrinter",
        "LLVMSystemZDisassembler",
        "LLVMSystemZCodeGen",
        "LLVMSystemZAsmParser",
        "LLVMSystemZDesc",
        "LLVMSystemZInfo",
        "LLVMSystemZAsmPrinter",
        "LLVMHexagonCodeGen",
        "LLVMHexagonAsmPrinter",
        "LLVMHexagonDesc",
        "LLVMHexagonInfo",
        "LLVMNVPTXCodeGen",
        "LLVMNVPTXDesc",
        "LLVMNVPTXInfo",
        "LLVMNVPTXAsmPrinter",
        "LLVMCppBackendCodeGen",
        "LLVMCppBackendInfo",
        "LLVMMSP430CodeGen",
        "LLVMMSP430Desc",
        "LLVMMSP430Info",
        "LLVMMSP430AsmPrinter",
        "LLVMXCoreDisassembler",
        "LLVMXCoreCodeGen",
        "LLVMXCoreDesc",
        "LLVMXCoreInfo",
        "LLVMXCoreAsmPrinter",
        "LLVMMipsDisassembler",
        "LLVMMipsCodeGen",
        "LLVMMipsAsmParser",
        "LLVMMipsDesc",
        "LLVMMipsInfo",
        "LLVMMipsAsmPrinter",
        "LLVMAArch64Disassembler",
        "LLVMAArch64CodeGen",
        "LLVMAArch64AsmParser",
        "LLVMAArch64Desc",
        "LLVMAArch64Info",
        "LLVMAArch64AsmPrinter",
        "LLVMAArch64Utils",
        "LLVMARMDisassembler",
        "LLVMARMCodeGen",
        "LLVMARMAsmParser",
        "LLVMARMDesc",
        "LLVMARMInfo",
        "LLVMARMAsmPrinter",
        "LLVMPowerPCDisassembler",
        "LLVMPowerPCCodeGen",
        "LLVMPowerPCAsmParser",
        "LLVMPowerPCDesc",
        "LLVMPowerPCInfo",
        "LLVMPowerPCAsmPrinter",
        "LLVMSparcDisassembler",
        "LLVMSparcCodeGen",
        "LLVMSparcAsmParser",
        "LLVMSparcDesc",
        "LLVMSparcInfo",
        "LLVMSparcAsmPrinter",
        "LLVMTableGen",
        "LLVMDebugInfo",
        "LLVMOption",
        "LLVMX86Disassembler",
        "LLVMX86AsmParser",
        "LLVMX86CodeGen",
        "LLVMSelectionDAG",
        "LLVMAsmPrinter",
        "LLVMX86Desc",
        "LLVMX86Info",
        "LLVMX86AsmPrinter",
        "LLVMX86Utils",
        "LLVMJIT",
        "LLVMLineEditor",
        "LLVMMCAnalysis",
        "LLVMMCDisassembler",
        "LLVMInstrumentation",
        "LLVMInterpreter",
        "LLVMCodeGen",
        "LLVMScalarOpts",
        "LLVMInstCombine",
        "LLVMTransformUtils",
        "LLVMipa",
        "LLVMAnalysis",
        "LLVMProfileData",
        "LLVMMCJIT",
        "LLVMTarget",
        "LLVMRuntimeDyld",
        "LLVMObject",
        "LLVMMCParser",
        "LLVMBitReader",
        "LLVMExecutionEngine",
        "LLVMMC",
        "LLVMCore",
        "LLVMSupport"
    

    You don't have to determine the order yourself- use -llvm-config to get the LLVM order. The Clang order is a bit trickier- from memory, you need to extract it from makefiles used to build Clang itself, or something like that. However, the Clang list is pretty small so determining it is pretty easy given the LLVM order and that Clang must go before LLVM. I don't know where libclang goes in this list since I don't use it, but I'm guessing that it should go first.