首页 文章

静态链接任何库会导致libc无法链接

提问于
浏览
1

我的系统是运行2.6.32的旧NAS . 我发现当对任何后续库使用-static时,它也会尝试静态链接我可能需要的任何其他库 .

当我首先添加-Wl,-Bdynamic标志然后使用-lc显式命名这些库时,例如“-Wl,-Bdynamic -lc -lstdc”,那么它可以工作 . 所以会发生什么是libc和其他人无法静态链接 .

系统上的静态libc称为 /opt/lib/libc_nonshared.a.

/opt/lib/libc.so的内容是这样的:

OUTPUT_FORMAT(elf32-littlearm)
GROUP ( /lib/libc.so.6 /opt/lib/libc_nonshared.a )

gcc版本是4.2.3 . 我面临的当前构建命令在最后添加 -dynamic 但这没有多大帮助 . 当我使用.a名称直接添加一些静态库,而不是使用-l标志时,则没有问题 .

问题似乎是libc的动态库随NAS一起提供,但静态版本位于/ opt / lib中 .

我跑:

gcc hamming.c -static -L. -L/opt/lib -l:matrix.a -o hamming

我明白了:

/opt/lib/gcc/arm-none-linux-gnueabi/4.2.3/../../../../arm-none-linux-gnueabi/bin/ld: cannot find -lc
collect2: ld returned 1 exit status
make: *** [hamming] Error 1

当我尝试按原样使用静态libc时 . 如果我执行'hack'将libc_nonshared.a链接到libc.a,它会突然找到它 . 但抱怨:

hamming.c:54: undefined reference to `malloc'
hamming.c:54: undefined reference to `memset'

当然还有其他的错误 . 如上所述,/ opt / libc.so包含对这两个文件的引用(动态和静态) .

对于libstdc,只存在.la文件 .

1 回答

  • 1

    -static 链接器标志不带任何参数 . 它是一个布尔标志,只是指示链接器链接没有共享库,如documented

    -static不要链接共享库...

    当有选择时,没有必要明确指示链接器链接共享(动态)库,因为这是默认的bevaiour . 如果您只是链接,例如

    gcc -o prog ... -lfoo ...
    

    然后链接器将链接在命令行序列中搜索的任何指定( -Ldir )或默认搜索目录中找到的 libfoo.so (共享)或 libfoo.a (静态)中的第一个 . 如果它在同一目录中找到 libfoo.solibfoo.a ,则它将选择 libfoo.so . 因此,共享和静态库可以自由混合,而无需任何特殊选项 .

    仅当您希望仅链接静态库时,才指定 -static .

    如果您希望坚持链接特定的 libfoo.a ,即使 libfoo.so 在同一目录中并且默认情况下会被选中,请使用 -l 选项的显式形式: -l:libfoo.a

    Later

    gcc hamming.c -static -L. -L/opt/lib -l:matrix.a -o hamming
    

    此命令失败:

    ld: cannot find -lc
    

    因为链接器( ld )无法在任何指定的链接器搜索目录( -L. -L/opt/lib )或默认链接器搜索目录中找到静态库 libc.a . 如果您希望链接 /opt/lib/libc_nonshared.a ,那么您的命令应该是:

    >gcc hamming.c -static -L. -L/opt/lib -l:matrix.a -lc_nonshared -o hamming
    

    但是,您还没有解释为什么要首先静态链接此程序( -static ),这不是通常的方式,并且需要您安装链接所需的所有库的静态版本 - 这两个都是您明确链接的以及 gcc 将为C语言链接添加的默认库(标准C库,GCC运行时库) .

    假设您有一个名为(奇怪地) matrix.a (而不是正常地, libmatrix.a )的静态库,它位于 /some/dir/ 中,那么编译和链接程序的常规方法是:

    gcc hamming.c -L/some/dir -l:matrix.a -o hamming
    

    我建议你从那开始,只有当问题迫使你时才会偏离 .

    发现 /opt/lib/libc.so 包含:

    OUTPUT_FORMAT(elf32-littlearm)
    GROUP ( /lib/libc.so.6 /opt/lib/libc_nonshared.a )
    

    误导了你 . 这不是你的共享 libc . 共享库是二进制文件 . 这是一个链接器脚本,它表示您的共享 libc 实际上是 /lib/libc.so.6 . 链接器几乎肯定会在默认情况下找到并使用它 .

相关问题