使用 GCC 链接器强制执行 32 位枚举
Enforce 32-bit enums with GCC linker
我正在为 ARM 设备编写裸机应用程序(否 OS)。我需要 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
这只是一个警告,没有错误。但这到底是什么意思呢?如何指定 "output"?
我尝试使用上述标志重新编译 newlib 以确保所有对象使用相同的枚举大小,但我仍然收到警告。我错过了什么吗?
我有一个部分答案,因为我有同样的问题。问题是使用 -fno-short-enums 时会出现来自链接器的警告消息。该消息表明目标对象不兼容。所以我花了很多时间寻找现在将目标更改为兼容。
但这不是问题所在。默认情况下,gcc 编译器将构建 32 位枚举!!所以这个选项是没有必要的,除非你不想要 32 位枚举。但是,如果您确实指定了 -fno-short-enums,您将收到警告消息。不幸的是我不知道为什么。
所以底线是 no-short-enums 标志不是实现 32 位枚举所必需的。如果您确实指定了它,那么您将收到警告消息。
过了一会儿我开始工作了。
我用这个标志重建了整个工具链,包括编译器。这是我的做法:
从 https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads
获取工具链 source
在构建脚本的某些部分添加 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-nano
和 gcc-size-libstdcxx
。
运行 修改脚本 build-prerequisites.sh
和 build-toolchain.sh
来构建所有内容。
在那之后,编译器使用 large-enum-mode 并且链接器对我的对象没问题。但是现在,我收到了一些 newlib 对象的相反警告(lib_a-mbtowc_r.o
、lib_a-svfiprintf.o
、lib_a-svfprintf.o
、lib_a-vfprintf.o
和 lib_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
我查看了这些对象的 makefile,遗憾的是它们被明确设置为 variable-size-enums。唯一的 "solution" 是添加一个链接器标志来消除此警告:
-Xlinker -no-enum-size-warning
就是这样。
我正在为 ARM 设备编写裸机应用程序(否 OS)。我需要 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
这只是一个警告,没有错误。但这到底是什么意思呢?如何指定 "output"?
我尝试使用上述标志重新编译 newlib 以确保所有对象使用相同的枚举大小,但我仍然收到警告。我错过了什么吗?
我有一个部分答案,因为我有同样的问题。问题是使用 -fno-short-enums 时会出现来自链接器的警告消息。该消息表明目标对象不兼容。所以我花了很多时间寻找现在将目标更改为兼容。
但这不是问题所在。默认情况下,gcc 编译器将构建 32 位枚举!!所以这个选项是没有必要的,除非你不想要 32 位枚举。但是,如果您确实指定了 -fno-short-enums,您将收到警告消息。不幸的是我不知道为什么。
所以底线是 no-short-enums 标志不是实现 32 位枚举所必需的。如果您确实指定了它,那么您将收到警告消息。
过了一会儿我开始工作了。 我用这个标志重建了整个工具链,包括编译器。这是我的做法:
从 https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads
获取工具链 source
在构建脚本的某些部分添加 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-nano
和gcc-size-libstdcxx
。运行 修改脚本
build-prerequisites.sh
和build-toolchain.sh
来构建所有内容。
在那之后,编译器使用 large-enum-mode 并且链接器对我的对象没问题。但是现在,我收到了一些 newlib 对象的相反警告(lib_a-mbtowc_r.o
、lib_a-svfiprintf.o
、lib_a-svfprintf.o
、lib_a-vfprintf.o
和 lib_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
我查看了这些对象的 makefile,遗憾的是它们被明确设置为 variable-size-enums。唯一的 "solution" 是添加一个链接器标志来消除此警告:
-Xlinker -no-enum-size-warning
就是这样。