【问题标题】:GCC libm not workingGCC libm 不工作
【发布时间】:2012-04-07 23:16:17
【问题描述】:

我有一个调用 sin、cos 和 acos 的 c 程序。编译时出现以下错误:

/tmp/ccDfW98S.o: In function `zip_search':
main.c:(.text+0xf30): undefined reference to `sin'
main.c:(.text+0xf45): undefined reference to `sin'
main.c:(.text+0xf66): undefined reference to `cos'
main.c:(.text+0xf7b): undefined reference to `cos'
main.c:(.text+0xf9c): undefined reference to `cos'
main.c:(.text+0xfc6): undefined reference to `acos'
collect2: ld returned 1 exit status

我知道这在您不使用 -lm gcc 标志时很常见。我正在使用这个标志。我这样称呼 GCC:

gcc -o zipcode-server -lm main.c

当我在我的一台计算机上编译时,它工作正常。我能想到的唯一区别是它不能在 x86_64 上运行,而它运行的计算机是 i686。两者都是Ubuntu。文件 libm.a 存在于它不工作的计算机上,我没有收到任何错误说找不到它。这可能是什么原因造成的?

【问题讨论】:

  • 能否请您发布代码的相关部分,以便我们帮助您解决问题?
  • 只是为了好玩试试:gcc -o zipcode-server main.c -lm

标签: c linux


【解决方案1】:

你应该把-lm放在main.c之后

一般来说,如果您有多个库,则应按使用顺序编写它们。例如,如果库 A 使用库 B,则您应该使用 -lA -lB

在您的情况下,作为main.c 编译结果的目标文件使用库m,因此-lm 应该在它之后。


出于好奇,这主要是出于效率原因。使用此方案,链接器可以使用参数列表中看到的每个新库解析当前未知符号,并在途中从该库中获取新的未知符号。这意味着链接器可以逐个访问库,从而将未知符号与每个库提供的少量符号进行匹配。

相比之下,链接器可以一次从所有库中加载符号,然后开始匹配未知符号。然而,在这种情况下,链接器需要处理更多的符号,从而增加了内存占用和链接器的执行时间。

由于库总是可以按照其依赖关系的正确顺序声明给链接器1,因此链接器没有理由选择低效的方式。

1库通常具有单向关系,即一个使用另一个。库之间的循环依赖是很少见的,如果存在的话,但它仍然可以通过重复某些要重新检查的库来与此模型一起使用。

【讨论】:

  • 好吧,实际上并不需要一次加载所有符号。您需要做的就是使用多通道链接器而不是单通道链接器。因此它将遍历所有库并解析所有符号,然后如果最后仍有未解析的符号,它将再次遍历库。如果您到了步行的尽头,并且您在结束时得到了与开始时相同的一组未解析的符号,那么您将因未定义的符号而失败。但是,这不是当今任何常见链接器的工作方式。
  • @MadScientist,既然您可以按正确的顺序指定它们并遍历一次,为什么还要多次遍历这些库?那只是链接速度较慢! (但重点)
  • 我没说应该那样做。我对现在几乎所有链接器都使用的单通道链接器模型没有任何问题。我只是说如果有人想编写一个不强制特定顺序的链接器,他们不必将每个符号加载到内存中。他们可以只使用多遍。
猜你喜欢
  • 2012-10-25
  • 2012-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多