OS X 上的链接器 (ld):如何使用 -Wl,--start-group(和 --end-group)?
linker (ld) on OS X: How to use -Wl,--start-group (and --end-group)?
我正在外部构建一些使用 libclang 静态库的项目。
链接失败是这样的:
ld: unknown option: --start-group
clang: error: linker command failed with exit code 1 (use -v to see invocation)
我需要使用它的原因是因为循环依赖(或者事实证明,我猜是因为不知道正确的库顺序)。
到目前为止,我不得不求助于从 makefile 中取出 -Wl,--{start,end}-group
,查看未定义符号错误列表,找到带有 nm
的库,然后手动将它们附加到库列表(因此它们在库列表中出现不止一次)。
3.5 的 LLVM/Clang 库(取自我自己使用它的项目)的正确顺序是:
"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"
您不必自己确定顺序 - 使用 -llvm-config 获取 LLVM 顺序。 Clang 命令有点棘手 - 从内存中,您需要从用于构建 Clang 本身的 makefile 中提取它,或类似的东西。然而,Clang 列表非常小,因此根据 LLVM 顺序确定它非常容易,并且 Clang 必须在 LLVM 之前。我不知道 libclang 在这个列表中的什么位置,因为我不使用它,但我猜它应该放在第一位。
@Puppy 接受的答案确实满足了 OP 的最终需求——如何按要求的 link 顺序获取库。
但它没有回答 OP 的实际问题——如何使用 --start-group
和 --end-group
。
clang
和 gcc
命令行选项是:
-Wl,--start-group
libs-in-the-order-you-need ...
-Wl,--end-group
您的里程数可能因其他编译器而异。
更新(2019.07.11):
David Given 指出 OSX 默认提供的 gcc 甚至不支持这些选项。
那是因为OSX只提供gcc 2.x
兼容性。
当我开始在我的项目中使用这些选项时,我使用的是 gcc 4.8
和 gcc 7.0
。
我不确定它们是什么时候第一次添加到 gcc 中的。
我正在外部构建一些使用 libclang 静态库的项目。
链接失败是这样的:
ld: unknown option: --start-group
clang: error: linker command failed with exit code 1 (use -v to see invocation)
我需要使用它的原因是因为循环依赖(或者事实证明,我猜是因为不知道正确的库顺序)。
到目前为止,我不得不求助于从 makefile 中取出 -Wl,--{start,end}-group
,查看未定义符号错误列表,找到带有 nm
的库,然后手动将它们附加到库列表(因此它们在库列表中出现不止一次)。
3.5 的 LLVM/Clang 库(取自我自己使用它的项目)的正确顺序是:
"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"
您不必自己确定顺序 - 使用 -llvm-config 获取 LLVM 顺序。 Clang 命令有点棘手 - 从内存中,您需要从用于构建 Clang 本身的 makefile 中提取它,或类似的东西。然而,Clang 列表非常小,因此根据 LLVM 顺序确定它非常容易,并且 Clang 必须在 LLVM 之前。我不知道 libclang 在这个列表中的什么位置,因为我不使用它,但我猜它应该放在第一位。
@Puppy 接受的答案确实满足了 OP 的最终需求——如何按要求的 link 顺序获取库。
但它没有回答 OP 的实际问题——如何使用 --start-group
和 --end-group
。
clang
和 gcc
命令行选项是:
-Wl,--start-group
libs-in-the-order-you-need ...
-Wl,--end-group
您的里程数可能因其他编译器而异。
更新(2019.07.11): David Given 指出 OSX 默认提供的 gcc 甚至不支持这些选项。
那是因为OSX只提供gcc 2.x
兼容性。
当我开始在我的项目中使用这些选项时,我使用的是 gcc 4.8
和 gcc 7.0
。
我不确定它们是什么时候第一次添加到 gcc 中的。