【问题标题】:Creating a shared library from list of static libraries从静态库列表创建共享库
【发布时间】:2017-08-02 07:05:05
【问题描述】:

您好,我正在尝试从目标文件和 .a 文件列表中创建一个 so 文件。但我收到错误。这是下面的命令和错误。

 gcc -g -shared bucomm.o filemode.o libiberty.a version.o make-temp-file.o  -o liballshared.so

make-temp-file.o: In function `choose_tmpdir':
/home/dinesh/packages/binutils-2.29/libiberty/./make-temp-file.c:106: multiple definition of `choose_tmpdir'
libiberty.a(make-temp-file.o):/home/dinesh/packages/binutils-2.29/libiberty/./make-temp-file.c:106: first defined here
make-temp-file.o: In function `make_temp_file':
/home/dinesh/packages/binutils-2.29/libiberty/./make-temp-file.c:185: multiple definition of `make_temp_file'
libiberty.a(make-temp-file.o):/home/dinesh/packages/binutils-2.29/libiberty/./make-temp-file.c:185: first defined here
collect2: error: ld returned 1 exit status

【问题讨论】:

  • Sooooo... 你期待什么?它告诉您您的某些对象对某些函数的定义存在冲突。
  • 我从命令中删除了 libiberty.a 并编译了它。我无法弄清楚问题是什么

标签: gcc g++ shared-libraries static-libraries


【解决方案1】:

我无法弄清楚问题是什么

这里:

make-temp-file.o: In function `choose_tmpdir':
/home/dinesh/packages/binutils-2.29/libiberty/./make-temp-file.c:106: multiple definition of `choose_tmpdir'

链接器告诉你目标文件make-temp-file.o定义了一个函数choose_tmpdir 已在已链接的目标文件中定义。链接器不允许 您可以链接choose_tmpdir 的多个定义。它应该在您的liballshared.so 中链接哪个定义?

下一步:

libiberty.a(make-temp-file.o):/home/dinesh/packages/binutils-2.29/libiberty/./make-temp-file.c:106: first defined here

链接器告诉你静态库libiberty.a 中的目标文件make-temp-file.o 是它拥有的目标文件 已经在其中定义了 choose_tmpdir 的链接。

下一步:

make-temp-file.o: In function `make_temp_file':
/home/dinesh/packages/binutils-2.29/libiberty/./make-temp-file.c:185: multiple definition of `make_temp_file'
libiberty.a(make-temp-file.o):/home/dinesh/packages/binutils-2.29/libiberty/./make-temp-file.c:185: first defined here

链接器告诉你,你还有一个函数make_temp_file的多重定义,这也是 在make-temp-file.o 中定义,并且在之前链接make-temp-file.o 时也已经定义 来自静态库libiberty.a

这两个多重定义错误都是因为在您的链接命令中发生的:

gcc -g -shared bucomm.o filemode.o libiberty.a version.o make-temp-file.o  -o liballshared.so

你首先给链接器库libiberty.a,其中包含目标文件make-temp-file.o, 然后你再给链接器make-temp-file.o

当您给链接器一个目标文件时,它会在您的程序或共享库中无条件地链接它。当你给 链接器是一个静态库,它检查静态库中的目标文件,只提取那些 它需要并将它们链接到您的程序或共享库中。链接器需要来自静态库的目标文件 如果该目标文件提供了一个或多个已被引用的符号的定义,但没有 尚未定义,在它已经链接的目标文件中。

当链接器在您的命令行中到达libiberty.a 时,它会检查 库中的目标文件,看看它们是否提供了未定义符号的定义 在它已经链接到您的liballshared.so(即bucomm.ofilemode.o)的目标文件中引用。 它发现libiberty.a(make-temp-file.o) 为函数choose_tmpdirmake_temp_file,它需要。所以它会从libiberty.a 中提取make-temp-file.o 并将其链接到您的共享库中。

当它在您的命令行中到达make-temp-file.o 时,它会无条件地链接它。所以这个目标文件有 现在在您的共享库中已链接两次,并且它定义的符号已在您的共享库中定义了两次, 所以你的链接失败了。

您的链接不会因以下命令而失败:

gcc -g -shared bucomm.o filemode.o version.o make-temp-file.o libiberty.a -o liballshared.so

其中libiberty.a 位于所有目标文件之后。所有的目标文件都将被链接, 无条件地,在检查 libiberty.a 之前。当检查libiberty.a 时,链接器 不会提取并链接libiberty.a(make-temp-file.o),因为不需要

道德:首先链接对象文件,然后是库

您评论说,如果您完全删除 libiberty.a,您的链接就会成功。如果这是真的,那 告诉您共享库中引用的 所有 符号是在 bucomm.o filemode.o version.o make-temp-file.o 之一中定义的, 所以一开始就链接libiberty.a 是没有意义的。但如果你坚持以下规则 首先链接目标文件,然后链接库,然后拥有库不会造成任何伤害 在不需要的链接中。不需要的库不会给程序添加任何内容 或您正在链接的共享库。

【讨论】:

猜你喜欢
  • 2017-12-27
  • 1970-01-01
  • 2021-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-18
  • 2020-01-03
  • 2023-03-03
相关资源
最近更新 更多