link script(連結器ld吃的檔案)中使用宏定義的解決方案

來源:互聯網
上載者:User

標籤:編譯   連結   

問題:工作中遇到一個需求:需要在ld script中使用類似C語言的define等宏定義來做一些判斷和替換

實驗:

1:理論上*.c中都能用,是否gcc/ld也支援在ld script中直接用宏呢,結果:

arm-linux-ld:xxx.lds:2: ignoring invalid character `#' in expressionarm-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)#elseOUTPUT_FORMAT("elf32-littlends", "elf32-littlends", "elf32-littlends")OUTPUT_ARCH(nds)#endifENTRY(_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)

[email protected]:~/linux_all/project$ arm-linux-gcc -E -D__ARM__ -D__ALIGN__=4 -P old.lds -o new.ldsarm-none-linux-gnueabi-gcc: old.lds: linker input file unused because linking not done

繼續被打,看了gcc還認副檔名呀。那我們忽悠忽悠它吧:

[email protected]:~/linux_all/project$ cp old.lds old.c[email protected]:~/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感覺不是太好,那您就使用下面的一行命令來搞定它吧:(注意命令中單獨的一個"-"的用法哦)

[email protected]:~/linux_all/project$ cat old.lds | arm-linux-gcc -E -D__ARM__  -D__ALIGN__=4 -P - -o new.lds[email protected]:~/linux_all/project$ arm-linux-gcc -E -D__ARM__  -D__ALIGN__=4 -P - <old.lds -o new.lds[email protected]:~/linux_all/project$ arm-linux-gcc -E -D__ARM__  -D__ALIGN__=4 -P - <old.lds > new.lds
以上三個命令,隨便撈一個吧(一行居然沒顯示下,將就看看吧)
接下來呢,ld再吃已經處理過的new.lds就可以啦。不用我說,聰明的客官你肯定早知道了。

link script(連結器ld吃的檔案)中使用宏定義的解決方案

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.