【问题标题】:ld complains: in function "_start", undefined reference to "__libc_csu_fini" & "__libc_csu_init"ld 抱怨:在函数“_start”中,未定义对“__libc_csu_fini”和“__libc_csu_init”的引用
【发布时间】:2012-04-23 12:34:09
【问题描述】:

我使用 clang 而不是 gcc 编译了一个 GTK+ 程序。到目前为止一切顺利,除了我无法正确地 ld 链接。

调用 gcc 的原始 makefile 进行链接,如下所示:

gcc -g -O2 -export-dynamic -o my_application somefile.o another.o -pthread -lgnomeui-2 -lSM -lICE -lbonoboui-2 -lgnomevfs-2 -lgnomecanvas-2 -lgnome-2 -lpopt - lbonobo-2 -lbonobo-activation -lORBit-2 -lart_lgpl_2 -lgconf-2 -lglade-2.0 -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgio-2.0 -lpangoft2-1.0 -lpangocairo-1.0 - lgdk_pixbuf-2.0 -lcairo -lpango-1.0 -lfreetype -lfontconfig -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lrt -lglib-2.0 -lxml2 -pthread -lgstreamer-0.10 -lgobject-2.0 -lgmodule-2.0 -lxml2 - lgthread-2.0 -lrt -lglib-2.0

如果我在上述命令中简单地将 gcc 替换为 clang,我会从后者收到以下警告:

clang:警告:编译期间未使用的参数:'-e xport-dynamic'

问题是:clang 不将“-export-dynamic”识别为链接器选项,因此它不会将其传递给 ld。这会导致对外部函数的引用被废弃:执行最终二进制文件时,菜单选项和按钮都没有反应。

如果我使用 gcc 进行最后的链接步骤,则二进制文件可以完美运行(即使它确实是用 clang 编译的,而 gcc 只进行链接)。由于我试图在我的机器上用 clang 完全替换 gcc,这是不可接受的。

所以我尝试了这个:

ld /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o -g -O2 -export-dynamic my_application somefile.o another.o -o -lgnomeui-2 - lSM -lICE -lbonoboui-2 -lgnomevfs-2 -lgnomecanvas-2 -lgnome-2 -lpopt -lbonobo-2 -lbonobo-activation -lORBit-2 -lart_lgpl_2 -lgconf-2 -lglade-2.0 -lgtk-x11-2.0 - lgdk-x11-2.0 -latk-1.0 -lgio-2.0 -lpangoft2-1.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo -lpango-1.0 -lfreetype -lfontconfig -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lrt - lglib-2.0 -lxml2 -lgstreamer-0.10 -lgobject-2.0 -lgmodule-2.0 -lxml2 -lgthread-2.0 -lrt -lglib-2.0

通过添加前 3 个对象,我避免了“找不到 _start”消息。但后来我收到了上述两个投诉:

/usr/lib/crt1.o:在函数_start中: (.text+0x12): 对__libc_csu_fini的未定义引用 /usr/lib/crt1.o:在函数_start: (.text+0x19): 对__libc_csu_init的未定义引用

我尝试在列表中添加 crtbegin.o 和 crtend.o,甚至在 crt1.o 之前,但无济于事。链接器的正确调用是什么?

(编辑后):如果没有其他方法,有没有办法在 gcc 时捕获 gcc 传递给 ld 的确切参数用于链接?

【问题讨论】:

  • 你试过用clang链接吗?
  • 是的,我确实尝试过使用 clang - 将重写以使其更明显

标签: c gtk ld


【解决方案1】:

gcc 自动将语言支持库和对象添加到您提供的链接列表中。如果你想直接调用ld,你必须自己添加它们。以man ld为例,可能是

ld -o <output> /lib/crt0.o hello.o -lc

尝试添加-lc,您需要的符号应该在其中(至少在我的系统上是这样)。

【讨论】:

  • 谢谢!只添加这个“-lc”标志而不添加“crt*.o”对象会导致 ld 仍然抱怨找不到条目符号“_start”丢失。有了这些目标文件和“-lc”然后 ld 给出 no错误,但可执行文件无法运行:当我尝试运行它时,bash 抱怨:“-bash: ./gnomebaker: No existe el fichero o el Directorio”(文件或文件夹在西班牙语中不存在 - 抱歉,忘记修改我的语言环境:P)
  • 这意味着文件gnomebaker 丢失。你没有把-o 选项弄错吗?没有出现其他名字可疑的文件吗?
  • 不,选项正确且文件确实存在。经过一番搜索,发现这里有什么问题:stackoverflow.com/questions/2716702/… 我也无法运行该文件,并且 ldd 也失败了。原来“gnomebaker”二进制文件正在寻找我的系统中不存在的 /lib/ld64.so.1 - 需要了解并解决这个问题。
  • @JoePineda:嗯。看来您已经为 libc5(不是当前的 libc6)创建了一个二进制文件。
  • 非常感谢!仍然不知道为什么二进制文件链接不好,从好的方面来说它现在已经解决了(尽管以不同的方式)并且我学会了使用 ldd 和 readelf。一个有趣的讨论,完全:-)
【解决方案2】:

您可以使用 -Wl,-export-dynamic-export-dynamic 传递给 ld 而无需 clang 知道它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-03
    • 1970-01-01
    • 2012-06-22
    • 2017-11-29
    • 1970-01-01
    • 2011-07-30
    • 1970-01-01
    相关资源
    最近更新 更多