【问题标题】:How to create a 32-bit shared-library on a 64-bit platform with autotools如何使用自动工具在 64 位平台上创建 32 位共享库
【发布时间】:2011-07-19 23:49:25
【问题描述】:

我正在使用自动工具来构建我的系统,该系统主要由一个库组成。在 64 位 Red Hat 平台上,我需要能够生成一个能够在 32 位 Red Hat 平台上工作的库。

当我将 -m32 添加到编译行时,一切正常,可以生成静态 (.a) 库,但是一旦我尝试创建共享库,就会收到如下错误:

/usr/bin/ld: warning: i386:x86-64 architecture of input file `/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crti.o' is incompatible with i386 output
/usr/bin/ld: warning: i386:x86-64 architecture of input file `/usr/lib/gcc/x86_64-redhat-linux/4.1.2/crtbeginS.o' is incompatible with i386 output  
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/crtbeginS.o: In function `__do_global_dtors_aux':  
crtstuff.c:(.text+0x29): undefined reference to `__DTOR_END__'  
collect2: ld returned 1 exit status' 

我可以看到问题在于它包含来自 /usr/lib64 的 64 位目标文件,而不是来自 /usr/lib 的正确 32 位目标文件(它们在那里没问题),但我不能弄清楚如何解决它。

【问题讨论】:

  • 你弄错了 crti.o 请参阅this previous question about inspecting the include path。你确定你的库路径中有 32 位 crti.o 吗? (并且它在 64 位版本出现之前就存在于路径中。)
  • 据我所知,包含路径内置在编译器/链接器中。由于我想根据 autotools 配置脚本的参数构建 32 位或 64 位版本,因此无法重新构建工具。我也需要这个才能在我的客户机器上工作。
  • 你真的安装了 32 位 glibc-devel 吗?

标签: shared-libraries autotools


【解决方案1】:

首先,确保您的编译器/libc 支持 32 位编译。在 Ubuntu 等一些发行版中,您需要做的是安装软件包 gcc-multilib 和/或 g++-multilib

sudo apt-get install gcc-multilib g++-multilib

然后,在调用configure时,指定一个32位主机,并传递32位编译标志:

./configure --host=i686-linux-gnu "CFLAGS=-m32" "CXXFLAGS=-m32" "LDFLAGS=-m32"

如果您没有安装 multilib,在传递 -m32 标志时会收到类似 configure: error: C compiler cannot create executables 的错误。

【讨论】:

  • 是的。它成功地构建了 32 位目标文件。当我尝试制作一个可共享的对象库时,就会出现问题。
  • 问题是关于自动工具的。使用 autotools 时如何做到这一点?
  • 这是对您答案的最出色更新!感谢gcc-multilib 等方面的提示。
【解决方案2】:

我在 RHEL6 上遇到了这个问题。这有效

./configure --host=i386-redhat-linux --build=i386-redhat-linux "CFLAGS=-m32" "CXXFLAGS=-m32" "LDFLAGS=-m32" "LTCC=gcc -m32"

LTCC=gcc -m32 是让 libtool 构建 32 位库所需的魔法咒语

【讨论】:

    【解决方案3】:

    我也遇到过同样的问题。但我不使用自动工具。然后,在手工编辑的 Makefile 中,我注意到在

    $(CC) -shared -Wl,-soname,lib$(NAME).so.0 -o lib$(NAME).so.$(VERSION) $(OBJ)
    

    gcc 没有选项表明 32 位架构。一旦我的 CFLAGS 已经有了选项 -m32,我决定把它放在上面提到的行中:

    $(CC) $(CFLAGS) -shared -Wl,-soname,lib$(NAME).so.0 -o lib$(NAME).so.$(VERSION) $(OBJ)
    

    然后瞧。有效!

    因此,在 autotools 中,可能将 CFLAGS 变量设置为包含 -m32 选项也对您有用。

    希望我有所帮助...

    【讨论】:

    • 我很想验证这是否适合我,但自从我提出这个问题后,该计划已经基本结束,我已经换了公司。
    【解决方案4】:

    你会试试:

    CFLAGS=-m32 -Wl,-m32
    CXXFLAGS=-m32 -Wl,-m32
    LDFLAGS=-m32
    

    在您的 makefile 中,因为某些脚本尝试使用 gcc 或 g++ 而不是我们期望的 ld 进行链接?

    更新:如果您手动修改每个 gcc/g++ 调用,请尝试使用 -m32 -Wl,-m32 而不是简单的 -m32 作为附加选项。

    【讨论】:

    • 我得到了同样的结果。链接由 libtool 执行,该脚本由 autotools 配置脚本生成,似乎没有使用 makefile 中的 *FLAGS 变量。
    • (1) 我发现有人建议 LDFLAGS="-m32 -L/usr/lib" ([mail-archive.com/autoconf@gnu.org/msg16323.html])。 (2) 但是,如果您的配置脚本正确生成带有 --host 选项的脚本,那将是非常可取的:(例如: ./configure --host i686-redhat-linux )
    • 我尝试使用 -host 等提供交叉编译标志的配置脚本变体,我发现自动工具希望通过为每个目标平台安装不同的编译器来完成交叉编译。
    • 长话短说,我已经获取 libiconv-1.14.bz2 并成功在 Centos 5.6 x86_64 中构建 ELF 32-bit LSB shared object,使用以下命令:CC="gcc -m32" sh configure && make。我希望这会对你有所帮助。
    • 问题是关于自动工具的。使用 autotools 时如何做到这一点?
    【解决方案5】:

    我也遇到过同样的问题:在 Ubuntu 64 位机器上运行,我设法使用 export CFLAGS=-m32; ./configure --host=i386 为 32 位主机编译和链接,但 libtool 仍会生成 64 位共享库。

    我通过创建一个 32 位构建环境并 chroot 来解决这个问题。 Ubuntu 通过debootstrap 让这一切变得简单。

    【讨论】:

    • 我们将库作为源代码提供,并希望我们的用户使用配置脚本来构建它们,所以我不能指望专门配置的环境。
    • Ups,这让它变得更加困难:)
    【解决方案6】:

    在 64 位机器上构建 32 位共享对象的 GNU 链接器标志是:-m elf_i386 所以请例如在 Makefile 中写入:

    LDFLAGS=-m elf_i386
    

    【讨论】:

    • 对不起,我什至不能再尝试了。很久以前,我放弃并从我的 makefile 中删除了所有对此的引用。我要求在 32 位平台上执行 32 位构建,似乎没有人认为这是不合理的。
    • 问题是关于自动工具的。使用 autotools 时如何做到这一点?
    【解决方案7】:

    快速修复....

    在另一台具有 32 位 linux 的 PC 上构建应用程序并传输结果 应用程序文件(库等)到所需的 64 位 linux 机器。看看它是否有效。它对我有用。

    【讨论】:

      猜你喜欢
      • 2013-11-14
      • 2021-12-22
      • 2016-11-30
      • 2014-08-23
      • 2015-02-27
      • 2010-12-14
      • 1970-01-01
      • 2023-03-29
      相关资源
      最近更新 更多