【问题标题】:Linking with gcc and -lm doesn't define ceil() on Ubuntu与 gcc 和 -lm 链接没有在 Ubuntu 上定义 ceil()
【发布时间】:2012-01-06 03:52:21
【问题描述】:

我目前使用gcc编译,需要使用<math.h>。 问题是它无法识别图书馆。 我也试过-lm,什么也没试过。 我尝试使用的函数是ceil(),我收到以下错误:

: undefined reference to `ceil'
collect2: ld returned 1 exit status

我正在使用最新的 Ubuntu 并且 math.h 在那里。 我尝试在另一台计算机上使用-lm,它运行良好。

有人知道如何解决这个问题吗?


我确实包含了<math.h>。另外,我使用的命令是:

gcc -lm -o fb file.c

【问题讨论】:

  • 你能给出你正在使用的完整命令行吗?
  • 在你使用ceil之前你还记得#include <math.h>吗?
  • 我确实包含了 math.h 另外,我使用的命令是:gcc -lm -o fb file.c
  • 您是否指定了-lm源文件名之后?
  • 有你的麻烦 - 在源文件名之后指定库。

标签: c math.h


【解决方案1】:

将此代码放入文件ceil.c

#include <math.h>
#include <stdio.h>
int main(void)
{
    printf("%f\n", ceil(1.2));
    return 0;
}

编译:

$ gcc -o ceil ceil.c
$ gcc -o ceil ceil.c -lm

这两个中的一个应该可以工作。如果两者都不起作用,则显示每个编译的完整错误消息。请注意,-lm 出现在源文件的名称之后(如果在链接之前将源文件编译为对象,则为目标文件)。

注意事项:

  1. 现代编译器可能会优化代码以将 2.0 直接传递给 printf(),而无需在运行时调用 ceil(),因此根本不需要数学库。

  2. 经验法则: 在命令行上列出库之前的目标文件和源文件。这个答案表明在使用中:-lm 位于源文件ceil.c 之后。如果您使用make 等进行构建,那么您通常在命令行上使用ceil.o(以及其他目标文件);通常,您应该在任何库之前列出所有目标文件。

经验法则偶尔会有例外,但它们很少见,并且会记录在预期/需要例外的特定情况下。在没有明确的相反文档的情况下,应用经验法则。

【讨论】:

  • @Johnathan Leffler 有没有办法做到这一点,而无需在编译期间每次都 tpying -lm?
  • @Brandon:迁移到 Mac? &lt;math.h&gt; 中的函数位于主系统库中,因此您无需指定 -lm(尽管如果您在命令行上指定 -lm,则有一个 libm.dylib 为您提供链接库)。否则,请确保您使用的是 makefile 并且您已将 LDLIBS(或 LDLIBES)设置为 -lm,如果您使用它足以保证它 - 或者根据需要编写包含/排除库的每个程序规则由每个程序。所以,换句话说,“不,没有办法避免指定它”。你可以问 GLibC 团队为什么他们没有去一个图书馆。
  • 请注意,如果您优化代码,编译器可以在编译时评估ceil(1.2),避免在运行时调用函数,在这种情况下您可能不需要@ 987654339@图书馆。但这对于我的示例中的简单程序来说是一个模糊的边缘情况——通常,编译器将无法进行优化,然后你需要链接到数学库,除非函数已经在 main系统库。
  • 谢谢!我错过了在文件后放置标志。
【解决方案2】:

只想提一下,Peter van der Linden 的书 Expert C Programming 在第 5 章 Thinking of Linking 中对此主题进行了很好的处理。

归档(静态库)的作用与共享对象(动态库)不同。对于动态库,所有库符号都进入输出文件的虚拟地址空间,并且所有符号都可用于链接中的所有其他文件。相比之下,静态链接仅在归档中查找加载程序在处理归档时当前已知的未定义符号。

如果您在目标文件之前指定数学库(通常是静态库),则链接器不会添加任何符号。

【讨论】:

    【解决方案3】:

    尝试这样编译:

    gcc -Wall -g file.c -lm -o file
    

    我遇到了同样的问题,用这个命令解决了。此外,如果您在同一天安装了 Ubuntu,则可能是更新问题。

    【讨论】:

    • 这个问题早就有答案了。
    • 经验法则:库在源文件或目标文件之后——这个命令行遵循 RoT。
    猜你喜欢
    • 2012-01-19
    • 1970-01-01
    • 2012-02-15
    • 1970-01-01
    • 2018-10-17
    • 1970-01-01
    • 1970-01-01
    • 2018-08-07
    • 2010-11-03
    相关资源
    最近更新 更多