链接错误:GCC中libm.a的选择性静态链接
我想有选择地静态链接链接错误:GCC中libm.a的选择性静态链接,c,linux,gcc,compilation,static-linking,C,Linux,Gcc,Compilation,Static Linking,我想有选择地静态链接libm.a,动态链接所有其他库(libc.so)。但是如果我使用math.h中的数学函数,它几乎总是无法正确链接。为什么? 为什么它有时会起作用?(例如,如果我只使用sqrt,fabs或奇怪的是,tanh,它似乎链接正确) myscript.sh: #!/bin/bash for i in sqrt tanh sin tan do echo "-----$i----------" sed "s/ciao/$i/" prova.c >provat
libm.a
,动态链接所有其他库(libc.so
)。但是如果我使用math.h
中的数学函数,它几乎总是无法正确链接。为什么?
为什么它有时会起作用?(例如,如果我只使用sqrt
,fabs
或奇怪的是,tanh
,它似乎链接正确)
myscript.sh:
#!/bin/bash
for i in sqrt tanh sin tan
do
echo "-----$i----------"
sed "s/ciao/$i/" prova.c >provat.c
gcc provat.c -fno-builtin -l:libm.a
[[ $? -eq 0 ]] && { echo -n "$i(2.0)="; ./a.out; echo " OK!"; }
echo
done
prova.c:
#include <stdio.h>
#include <math.h>
int main()
{
printf("%f", ciao(2.0));
return 0;
}
我不明白这些错误信息。有人能解释一下发生了什么吗?
为什么我不能静态链接libm.a
(其余的则是动态链接)?为什么它有时会起作用
注意:我使用GCC的-fno builtin
标志,以便GCC不使用任何内置函数。所以问题不在那里。我不太清楚为什么需要限制(libm.a+libc.So),所以闻起来像是XY问题
根据(由@KamilCuk指出):
这是不受支持的
您可能会将静态libm.a与未来的libc.so.6和ld.so混合在一起,从而打破了核心库之间的相互依赖关系,这些核心库构成了“C运行时的实现”
运行时的整个实现都是静态链接的,或者没有一个是静态链接的。您不能选择静态链接部分,而不是其他部分,因为每个部分都依赖于其他部分来形成完整的实现。数学库不是一个可以静态链接的瘦库,我们有一个libm.a,但这是一个实现细节
请对整个应用程序使用“-static”
这似乎是一个不受支持的配置。这是有道理的,但也有点混淆:即使libc和libm是磁盘上的两个独立文件(对于每个配置:静态、共享),它们也是同一个库的一部分(glibc),因此:
- 使用静态构建的库的一半,另一半作为共享对象是不合适的(我想到的一些事情是:gcc的-fPIC标志,以及库的初始化)
- 当然,大多数情况下,库由单个文件组成,因此上面的项目符号不适用(这就是混淆的原因)
- 仅用于某些(三角)函数(如sin、cos,但nottanh)-我只是在这里猜测:基于函数值的计算方式(例如泰勒级数)
- 它只在libc(libm)同步时发生
#包括
#包括
#如果!已定义(FUNC)
#定义FUNC sqrt
#恩迪夫
int main(){
双val=3.141592;
printf(“func(%.06lf):%.06lf\n”,val,func(val));
返回0;
}
下面是我在研究问题时遵循的一系列步骤:
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q056415996]>~/sopr.sh
***设置较短的提示,以便粘贴到StackOverflow(或其他)页面时更适合***
[提示]>联阿援助团-a
Linux cfati-ubtu16x64-0 4.15.0-51-generic#55~16.04.1-Ubuntu SMP-Thu May 16 09:24:37 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
[提示]>gcc--版本
gcc(Ubuntu 5.4.0-6ubuntu1~16.04.11)5.4.0 20160609
版权所有(C)2015免费软件基金会。
这是自由软件;有关复制条件,请参见源。没有
担保甚至不是为了适销性或适合某一特定目的。
[提示]>ldd--版本
ldd(UbuntuGlibc2.23-0ubuntu11)2.23
版权所有(C)2016免费软件基金会。
这是自由软件;有关复制条件,请参见源。没有
担保甚至不是为了适销性或适合某一特定目的。
由罗兰·麦格拉斯和乌尔里希·德雷珀撰写。
[提示]>ls
main.c
[prompt]>gcc-fPIC main.c-DFUNC=sin-o sin_static.out-static-lm
[提示]>ll sinu static.out
-RWXR-x 1 cfati cfati 1007744 Jun 13 20:08 sin_static.out
[提示]>ldd sin_static.out
不是动态可执行文件
[提示]>。/sin\u static.out
func(3.141592):0.000001
[提示]>
[prompt]>gcc-fPIC main.c-DFUNC=sin-o sin_mso.out-l:libm.so
[提示]>ll sin_mso.out
-RWXR-x 1 cfati cfati 8656 Jun 13 20:09 sin_mso.out
[提示]>ldd sin_mso.out
linux vdso.so.1=>(0x00007ffc80ddd000)
libm.so.6=>/lib/x86_64-linux-gnu/libm.so.6(0x00007f999636b000)
libc.so.6=>/lib/x86_64-linux-gnu/libc.so.6(0x00007f9995fa1000)
/lib64/ld-linux-x86-64.so.2(0x00007f9996674000)
[提示]>。/sin\u mso.out
func(3.141592):0.000001
在这两种情况下,一切都很好[prompt]>gcc-fPIC main.c-DFUNC=sin-o sin_ma.out-l:libm.a
/usr/lib/gcc/x86_64-linux-gnu/5/./../../../x86_64-linux-gnu/libm.a(s_sin.o):在函数`\u cos'中:
(.text+0x3542):未定义对“dl\U x86\U cpu\U功能”的引用
/usr/lib/gcc/x86_64-linux-gnu/5/./../../../x86_64-linux-gnu/libm.a(s_sin.o):在函数`_sin'中:
(.text+0x3572):对“dl\U x86\U cpu\U功能”的未定义引用
collect2:错误:ld返回了1个退出状态
[提示]>ll sin_ma.out
ls:无法访问“sin_ma.out”:没有这样的文件或目录
[提示]>
[prompt]>gcc-fPIC main.c-DFUNC=tanh-o tanh_ma.out-l:libm.a
[提示]>我要出去了
-RWXR-x 1 cfati cfati 12856 Jun 13 20:10 tanh_ma.out
[提示]>ldd tanh_ma.out
linux vdso.so.1=>(0x00007ffcfa531000)
libc.so.6=>/lib/x86_64-linux-gnu/libc.so.6(0x00007f124625c000)
/lib64/ld-linux-x86-64.so.2(0x00007f1246626000)
[提示]>。/谭胡妈
func(3.141592):0.996272
如图所示:
$./myscript.sh
-----sqrt----------
sqrt(2.0)=1.414214 OK!
-----tanh----------
tanh(2.0)=0.964028 OK!
-----sin----------
/usr/lib/x86_64-linux-gnu/libm-2.27.a(s_sin.o): In function `__sin_ifunc':
(.text+0x4d42): undefined reference to `_dl_x86_cpu_features'
/usr/lib/x86_64-linux-gnu/libm-2.27.a(s_sin.o): In function `__cos_ifunc':
(.text+0x4da2): undefined reference to `_dl_x86_cpu_features'
collect2: error: ld returned 1 exit status
-----tan----------
/usr/lib/x86_64-linux-gnu/libm-2.27.a(s_tan.o): In function `__tan_ifunc':
(.text+0x5782): undefined reference to `_dl_x86_cpu_features'
collect2: error: ld returned 1 exit status