link script(鏈接器ld吃的文件)中使用宏定義的解決方案
0條評論
[摘要:題目:事情中碰到一個需供:須要正在ld script中應用類C說話的define等宏界說去做一些判別戰調換 試驗: 1:實際上*.c中皆能用,是不是gcc/ld也支撐正在ld script中間接用宏呢,效果: arm-linux-]
問題:工作中遇到一個需求:需要在ld script中使用類似C語言的define等宏定義來做一些判斷和替換
實驗:
1:理論上*.c中都能用,是否gcc/ld也支持在ld script中直接用宏呢,結果:
arm-linux-ld:xxx.lds:2: ignoring invalid character `#' in expression arm-linux-ld:xxx.lds:2: syntax error人說水火無情,看來ld和gcc也不給面子啊。這裏用的是交叉編譯的ld,x86的也是一樣的結論,本是同根生嘛。看來此路不通。
2:*.c中爲什麼能用define等宏呢,這個是在預編譯階段完成的。我們把gcc的預編譯拿來先幫我們處理一次是否就可以了呢?帶着疑問我們繼續出發
先貼一份原始的ld script 吧:old.lds,裏面有些define和註釋哦
/* * comments like C style * if comments line is less than 2 lines like this, maybe generate some strange result * */ #ifdef __ARM__ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) #else OUTPUT_FORMAT("elf32-littlends", "elf32-littlends", "elf32-littlends") OUTPUT_ARCH(nds) #endif ENTRY(_start) SECTIONS { //C++ comments . = 0x00000000; . = ALIGN(__ALIGN__); .text : /*C style comment*/ { #if defined(__ARM__) cpu/arm920t/start.o (.text) #endif board/xxx/lowlevel_init.o (.text) board/xxx/nand_read.o (.text) *(.text) } . = ALIGN(__ALIGN__); .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } . = ALIGN(__ALIGN__); .data : { *(.data) } . = ALIGN(__ALIGN__); __bss_start = .; .bss (NOLOAD) : { *(.bss) . = ALIGN(__ALIGN__); } _end = .; }
我們請gcc出馬幫忙只進行預編譯吧:(主要是 -E 和 -P的參數,不瞭解的man gcc 或者 gcc --help)
deeve@debian:~/linux_all/project$ arm-linux-gcc -E -D__ARM__ -D__ALIGN__=4 -P old.lds -o new.lds arm-none-linux-gnueabi-gcc: old.lds: linker input file unused because linking not done
繼續被打,看了gcc還認文件擴展名呀。那我們忽悠忽悠它吧:
deeve@debian:~/linux_all/project$ cp old.lds old.c deeve@debian:~/linux_all/project$ arm-linux-gcc -E -D__ARM__ -D__ALIGN__=4 -P old.c -o new.lds哇,居然成功糊弄過去了,趕緊看看new.lds是否是預期的呢:
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { . = 0x00000000; . = ALIGN(4); .text : { cpu/arm920t/start.o (.text) board/xxx/lowlevel_init.o (.text) board/xxx/nand_read.o (.text) *(.text) } . = ALIGN(4); .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } . = ALIGN(4); .data : { *(.data) } . = ALIGN(4); __bss_start = .; .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } _end = .; }太cool了,gcc看來還比較好騙嘛,O(∩_∩)O哈哈~
如果客官您覺得改名成*.c感覺不是太好,那您就使用下面的一行命令來搞定它吧:(注意命令中單獨的一個"-"的用法哦)
deeve@debian:~/linux_all/project$ cat old.lds | arm-linux-gcc -E -D__ARM__ -D__ALIGN__=4 -P - -o new.lds deeve@debian:~/linux_all/project$ arm-linux-gcc -E -D__ARM__ -D__ALIGN__=4 -P - <old.lds -o new.lds deeve@debian:~/linux_all/project$ arm-linux-gcc -E -D__ARM__ -D__ALIGN__=4 -P - <old.lds > new.lds以上三個命令,隨便撈一個吧(一行居然沒顯示下,將就看看吧)
接下來呢,ld再吃已經處理過的new.lds就可以啦。不用我說,聰明的客官你肯定早知道了。