【问题标题】:Enforce 32-bit enums with GCC linker使用 GCC 链接器强制执行 32 位枚举
【发布时间】:2017-10-08 23:06:45
【问题描述】:

我正在为 ARM 设备(无操作系统)编写裸机应用程序。我需要 32 位枚举,所以我使用 -fno-short-enums 编译器标志编译了应用程序。如果没有这个标志,我会得到变量枚举(并且通过向每个枚举添加额外的 0xFFFFFFFF 值来强制大小不是一种选择)。

现在我收到每个对象的以下链接器警告:

c:/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/6.2.1/../../../../arm-none-eabi/bin/ld.exe: warning: ./src/test.o uses 32-bit enums yet the output is to use variable-size enums; use of enum values across objects may fail

这只是一个警告,没有错误。但这究竟是什么意思?如何指定“输出”?

我尝试使用上述标志重新编译 newlib 以确保所有对象使用相同的枚举大小,但我仍然收到警告。有什么我错过的吗?

【问题讨论】:

  • 为什么需要 32 位枚举?
  • 也许你应该为链接器添加一些标志,并为所有对象使用短枚举。
  • 我需要它来兼容其他平台/处理器上的软件部件。我绝对需要 32 位枚举。
  • 什么样的兼容性?网络?
  • 顺便说一句,你不使用其他一些库吗?显示完整的构建日志:)

标签: c gcc enums arm ld


【解决方案1】:

我有一个部分答案,因为我有同样的问题。问题是使用 -fno-short-enums 时会出现来自链接器的警告消息。该消息表明目标对象不兼容。所以我花了很多时间寻找现在将目标更改为兼容。

但这不是问题所在。 gcc 编译器将默认构建 32 位枚举!所以这个选项是没有必要的,除非你不想要 32 位枚举。但是,如果您确实指定了 -fno-short-enums,您将收到警告消息。不幸的是,我不知道为什么。

所以底线是 no-short-enums 标志不是实现 32 位枚举所必需的。如果您确实指定了它,那么您将收到警告消息。

【讨论】:

  • 不,在 ARM 上,gcc 默认使用最小的枚举大小,具体取决于要存储的值。检查 gcc 文档中的 4.9 结构、联合、枚举和位域
【解决方案2】:

过了一会儿,我开始工作了。 我用这个标志重建了整个工具链,包括编译器。这是我的做法:

  1. https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads获取工具链source

  2. 在构建脚本的某些部分添加 3 行 build-toolchain.sh:

    saveenv
    saveenvvar CFLAGS_FOR_TARGET '-fno-short-enums'
      [...build commands...]
    restoreenv
    

    修改部分:

    • Task [III-1] /$HOST_NATIVE/gcc-first/
    • Task [III-2] /$HOST_NATIVE/newlib/
    • Task [III-4] /$HOST_NATIVE/gcc-final/
    • Task [IV-3] /$HOST_MINGW/gcc-final/

    我跳过了 newlib-nanogcc-size-libstdcxx 的构建。

  3. 运行修改后的脚本build-prerequisites.shbuild-toolchain.sh 来构建一切。


在那之后,编译器使用大枚举模式,链接器可以很好地处理我的对象。但是现在,我收到了 newlib 的某些对象的相反警告(lib_a-mbtowc_r.olib_a-svfiprintf.olib_a-svfprintf.olib_a-vfprintf.olib_a-vfiprintf.o):

c:/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/6.2.1/../../../../arm-none-eabi/bin/ld.exe: warning: c:/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/6.2.1/../../../../arm-none-eabi/lib\libc.a(lib_a-mbtowc_r.o) uses variable-size enums yet the output is to use 32-bit enums; use of enum values across objects may fail

我查看了这些对象的生成文件,很遗憾,它们被明确设置为可变大小枚举。唯一的“解决方案”是添加一个链接器标志来静音这个警告:

-Xlinker -no-enum-size-warning

就是这样。

【讨论】:

  • 应该是-Xlinker(使用小写的l)。 arm-none-eabi-g++: error: unrecognized command line option '-XLinker'; did you mean '-Xlinker'?
猜你喜欢
  • 2022-08-06
  • 2010-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-15
  • 1970-01-01
  • 1970-01-01
  • 2014-07-31
相关资源
最近更新 更多