![](/img/trans.png)
[英]gcc linker not linking programs under debian 7.4 wheezy 32-bit, gnome 3.4.2
[英]Enforce 32-bit enums with GCC linker
我正在為 ARM 設備(無操作系統)編寫裸機應用程序。 我需要 32 位枚舉,所以我使用-fno-short-enums
編譯器標志編譯了應用程序。 沒有這個標志,我會得到變量枚舉(並且通過向每個枚舉添加額外的0xFFFFFFFF
值來強制大小不是一個選項)。
現在,對於每個 object,我都會收到以下 linker 警告:
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 以確保所有對象都使用相同的枚舉大小,但我仍然收到警告。 我錯過了什么嗎?
我有一個部分答案,因為我有同樣的問題。 問題是來自鏈接器的警告消息,它將使用-fno-short-enums出現。 該消息表明目標對象不兼容。 所以我花了一段時間尋找現在改變目標以兼容。
但那不是問題。 gcc編譯器默認會構建32位枚舉! 因此,除非您不想要32位枚舉,否則此選項是沒有必要的。 但是,如果您指定-fno-short-enums,您將收到警告消息。 不幸的是我不知道為什么。
所以最重要的是,無需短枚舉標志就不需要實現32位枚舉。 如果您確實指定了它,那么您將收到警告消息。
過了一會兒,我開始工作了。 我重建了整個工具鏈,包括帶有此標志的編譯器。 這是我的方式:
從https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads獲取工具鏈源代碼
在buildscript build-toolchain.sh
某些部分添加3行:
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
。
運行修改后的Scripts 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。 對此唯一的“解決方案”是添加鏈接器標志以靜音此警告:
-Xlinker -no-enum-size-warning
而已。
我遇到了同樣的問題,因為我在數據結構中有很多枚舉 map 到硬件。 就我而言,我的解決方法是執行以下操作:
struct x {
union {
enum my_enum eval;
uint32_t :32;
};
uint32_t some_val;
...
}
這有效並且在數據結構之外是透明的,盡管這意味着每次在數據結構中使用枚舉時都需要這個聯合包裝器。 我想宏也可能是可能的。 我同意這是一種痛苦。 我使用過的所有其他 32 位和 64 位環境都將枚舉視為 32 位,並且不要讓我開始決定在 ARM 嵌入式 ABI 中將 uint32_t 設為無符號長整數(我已經使用它是一個無符號整數,使 64 位 ABI 的可移植性變得容易)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.