使用uclibc时如何解决fenv.h中函数的未定义引用问题?

7

我想测试 fenv.h 的一些函数,但是当我编译下面的函数时,ld 失败并出现 undefined reference to 'feclearexcept'undefined reference to 'fetestexcept'。我在硬化的 Gentoo 上编译了 uclibc,并且我认为这至少与此有些相关。

#include <stdio.h>      /* printf */
#include <math.h>       /* sqrt */
#include <fenv.h>      
#pragma STDC FENV_ACCESS on

int main ()
{
  feclearexcept (FE_ALL_EXCEPT);
  sqrt(-1);
  if (fetestexcept(FE_INVALID)) printf ("sqrt(-1) raises FE_INVALID\n");
  return 0;
}

fenv.h位于/usr/include。在/usr/lib中有静态库和动态库(libm.a, libm.so)。我用gcc -o test test.c -lm进行编译;是否有人知道为什么链接器找不到相关函数呢?似乎fenv.h中没有相应的库。

更新:这篇十年前的博客文章似乎表明uclibc不支持fenv。我无法确定现在是否仍然如此,但如果确实如此,是否有任何解决办法。 http://uclibc.10924.n7.nabble.com/missing-fenv-h-for-qemu-td2703.html


链接器能找到 sqrt() 吗? - user12205
我运行了完全相同的发布代码。使用的是Ubuntu Linux 14.04和GCC编译器。编译器发出了以下警告:忽略#pragma STDC FENV_ACCESS。但它没有任何问题找到feclearexcept()函数或FE_ALL_EXCEPT和FE_INVALID值。请确保您的/usr/include目录中有fenv.h文件,因为它应该在那里。 - user3629249
我运行的是硬化的uclibc gentoo linux,所以我怀疑其中的某个特殊性是问题所在。这段代码肯定是有效的,并且可以在大多数系统上编译。 - ragingSloth
2个回答

8

将库放在最后,尝试使用以下方式编译

$ gcc -o test test.c -lm

我在我的x86_64 Linux系统上尝试了您的程序,并使用上述编译语句进行编译,它成功地构建并运行:

$ gcc -o fenv fenv.c -lm
$ ./fenv
sqrt(-1) raises FE_INVALID

我的二进制文件具有以下依赖项:

$ ldd ./fenv
    linux-vdso.so.1 =>  (0x00007ffd924b7000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fca457e8000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fca4541e000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fca45af0000)

我还验证了来自fenv.h的函数确实存在于数学库中:
emil@synapse:~/data/src$ strings /lib/x86_64-linux-gnu/libm.so.6 | grep -E ^fe
feclearexcept
fegetexceptflag
feraiseexcept
fesetexceptflag
fetestexcept
fegetround
fesetround
fegetenv
feholdexcept
fesetenv
feupdateenv
fedisableexcept
feenableexcept
fegetexcept

也许你的设置有其他问题。

你能取消这个重复标记吗?sqrt已经正确地定义,并且-lm都放置正确了。问题似乎仅限于fenv.h中的函数,我真的需要一个答案。 - ragingSloth
@ragingSloth,sqrt 应用于常量并不会导致问题,并不意味着数学库被正确链接。有一个 sqrt 汇编指令,而您无论如何都将其应用于常量。 - Pascal Cuoq
是的,我正在使用uclibc而不是gnu libc,所以我认为这是问题的一部分。有趣的是,libm的静态和动态版本都没有列出任何相关函数。 - ragingSloth

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接