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

时间:2017-06-09 06:00:56

标签: gcc static

我的系统是运行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 个答案:

答案 0 :(得分:2)

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

  

-static

     

不要链接共享库...

无需明确指示链接器链接共享(动态) 库有什么选择,因为这是默认的bevaiour。如果 你只需链接,例如

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

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

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

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

<强>后来

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

此命令失败:

ld: cannot find -lc

因为链接器(ld)找不到静态库libc.a 任何指定的链接器搜索目录(-L. -L/opt/lib)或 默认的链接器搜索目录。如果您希望链接 /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 实际上是 var pvarrData = new Array(); pvarrData[0] = JSON.stringify(item.Key); pvarrData[1] = JSON.stringify(SolrLabel); pvarrData[2] = JSON.stringify($localStorage.message); $http({ method: 'POST', url: '/api/TalentPool/ProcessCriteria', data: JSON.stringify(pvarrData), headers: { 'Content-Type': 'application/json' } }).then(function (response) { // success console.log('Facet Data Posted'); return response; }, function (response) { // failed console.log('facet post error occured!'); }); 。链接器几乎肯定会在默认情况下找到并使用它。