【问题标题】:Linking Math Library in GCC 4.6.1 (Ubuntu 11.10)在 GCC 4.6.1 (Ubuntu 11.10) 中链接数学库
【发布时间】:2011-11-21 04:58:11
【问题描述】:

我在我的应用程序的链接过程中发现了一个问题。我对 gcc 4.5 没有同样的看法。它尝试使用以下命令链接数学库。

gcc -Wall -Wno-unused -MD -o mems_seektest mems_seektest.o -lm -L. -g -DASSERTS  -I../src// -I../ -I../src//src -DDEBUG -lmems_internals

并报告以下错误消息:

undefined reference to `sqrt'

有什么想法吗?

【问题讨论】:

  • 我无法重现这个(在 Linux 中使用 gcc 4.6.2),这个代码是用 gcc 4.5 构建的吗?
  • @birryree 当然你不能,如果你使用像float test = sqrt(5); 这样的东西,因为 gcc 会通过在编译时计算结果来优化它。尝试使用 float test = sqrt(a); 之类的东西,其中 a 是一个变量,其值要到运行时才能知道。
  • @PengyuCHEN - 我没有使用常量,我知道 gcc 的常量折叠。正如你所看到的,他已经在使用-lm 标志,所以你的答案是重复他所做的事情。
  • @birryree 是的,伙计,我注意到在发布答案后,现在对此感到抱歉:-(

标签: c gcc linker


【解决方案1】:

最近的 gcc/ld 默认使用 --as-needed 链接器标志。实际上,这意味着必须以命令行上依赖项的相反顺序指定库。如果 mems_internals 库需要 sqrt 函数,则 -lm 在 -lmems_internals 之后。

gcc -Wall -Wno-unused -MD -o mems_seektest mems_seektest.o  -L. -g -DASSERTS  -I../src// -I../ -I../src//src -DDEBUG -lmems_internals -lm

【讨论】:

    【解决方案2】:

    我在 gcc 4.6.1 上遇到过同样的问题,即使只有一个库。这不起作用:

    $ gcc -lm eg.o -o eg
    eg.o: In function `foo':
    /home/nick/tmp/eg.c:5: undefined reference to `sqrt'
    collect2: ld returned 1 exit status
    

    但这确实:

    $ gcc eg.o -o eg -lm
    

    我点击这个是因为我在 Makefile 中使用了“LDFLAGS=-lm”。如果您改用“LDLIBS=-lm”,则效果很好。

    【讨论】:

    • -lm 放在 eg.o ($^) 之后总是更好。
    【解决方案3】:

    您没有告诉我们-lmems_internals 是什么,但可能未解析的符号来自那里。 -l 选项的顺序通常对链接器很重要,您应该始终将系统库放在最后。

    您可以使用类似的方法检查未解析符号的来源

    nm yourLibrary | grep sqrt
    

    如果sqrt 前面有U,则符号未定义。

    【讨论】:

      【解决方案4】:

      我会说链接器使用了错误的 libm。

      【讨论】:

        猜你喜欢
        • 2012-01-19
        • 1970-01-01
        • 2012-03-23
        • 2011-12-11
        • 1970-01-01
        • 1970-01-01
        • 2012-01-12
        • 1970-01-01
        • 2012-01-23
        相关资源
        最近更新 更多