鏈接腳本預處理

首頁 > 精品文庫 > link script(鏈接器ld吃的文件)中使用宏定義的解決方案

link script(鏈接器ld吃的文件)中使用宏定義的解決方案

[摘要:題目:事情中碰到一個需供:須要正在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就可以啦。不用我說,聰明的客官你肯定早知道了。大笑
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章