【问题标题】:Linker error on Linux: "undefined reference to"Linux 上的链接器错误:“未定义的引用”
【发布时间】:2026-02-18 05:05:01
【问题描述】:

我可以毫无问题地创建一个共享库。我创建了 libcbitcoin.so(没有错误)并尝试使用可执行文件和 OpenSSL 库链接它。我使用这个命令:

gcc -L/media/sf_BitEagle_Projects/cbitcoin/build/bin -lcbitcoin \
-Wl-rpath,/media/sf_BitEagle_Projects/cbitcoin/build/bin -lssl -lcrypto \
-L/usr/local/ssl/lib/ -o /media/sf_BitEagle_Projects/cbitcoin/build/bin/testCBAddress \
/media/sf_BitEagle_Projects/cbitcoin/build/obj/testCBAddress.o \
/media/sf_BitEagle_Projects/cbitcoin/build/obj/CBOpenSSLCrypto.o

bin 目录是库的位置。 obj 目录包含我希望链接到可执行文件的目标文件。在命令中,我使用了 -L、-l 和 -rpath 选项,我认为这些选项是在 linux 中链接所需的全部内容。似乎我错了,因为我收到如下错误:

/media/sf_BitEagle_Projects/cbitcoin/test/testCBAddress.c:40:
undefined reference to `CBNewByteArrayFromString'

在库中找到 CBNewByteArrayFromString。由于某种原因,它没有被链接。 OpenSSL 也是:

/media/sf_BitEagle_Projects/cbitcoin/dependencies/crypto/CBOpenSSLCrypto.c:37:
undefined reference to `SHA1'

如何使链接正常工作?

GCC 版本:gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

在 Linux Mint 13 上

谢谢。

【问题讨论】:

标签: linux gcc build linker


【解决方案1】:

将库放在链接命令行上的目标文件之后:

gcc /media/sf_BitEagle_Projects/cbitcoin/build/obj/testCBAddress.o \
    /media/sf_BitEagle_Projects/cbitcoin/build/obj/CBOpenSSLCrypto.o \
    -L/media/sf_BitEagle_Projects/cbitcoin/build/bin \
    -lcbitcoin -Wl-rpath,/media/sf_BitEagle_Projects/cbitcoin/build/bin \
    -L/usr/local/ssl/lib/ -lssl -lcrypto \
    -o /media/sf_BitEagle_Projects/cbitcoin/build/bin/testCBAddress

如果你不这样做,链接器可能会在它扫描库的链接阶段决定它不需要来自特定库的任何内容,然后它不会在以后找到一些未定义的库后重新扫描库目标文件中的符号。如果你把目标文件放在第一位,你就不会遇到这个问题。

【讨论】:

  • 也解决了我的问题。这是一个多么可怕的(违反直觉的、意外的)错误/设计决策(使选项相对于位置参数的顺序很重要)传统上,选项首先出现,其他参数紧随其后。
  • -L 选项可以或多或少地放在命令行的任何位置,但您需要将-l name 选项视为指定在命令行中该点处理的文件(所以任何相关的-L 标志都应该在它之前)。自 (Unix) 时代开始以来一直如此——无论如何,在 1970 年代的某个时候。
  • 似乎-l 选项相对于彼此的顺序也很重要,更一般/更低级别的依赖关系应该是last,而不是首先。我得到了undefined reference to 'pow',直到我将-lm 移动到我的选项字符串的最end
【解决方案2】:

我认为是can NOT find symbol引起的,gcc会先从左到右,尽量把lib文件放在最后

【讨论】:

    最近更新 更多