第9課.gcc和arm-linux-gcc和Makefile

1.gcc編譯器和arm-linux-gcc編譯器

PC上的編譯工具:gcc,ld,objcopy,objdump ARM平臺上必須使用交叉編譯工具:arm-linux-gcc

A.一個C/C++文件處理過程:

        預處理---> 編譯 ---> 彙編 ---> 鏈接
.c/.cpp ----- .i  ---- .S  ----- .o  ----

a.預處理

以"#"開頭的命令被稱爲預處理命令,得到.i文件

b.編譯

把.i文件翻譯成彙編代碼(.S)

c.彙編

將彙編代碼(.S)翻譯成符合一定格式的機器碼(.o)

d.鏈接

將上步產生的文件和系統庫的OBJ文件,庫文件連接起來

B.arm-linux-gcc和gcc的一些常用選項

a.總體選項

-E            只預處理,不會編譯、彙編、鏈接
-S            只編譯,不會彙編、鏈接
-c            編譯和彙編,不會鏈接   
-o <file>     指定輸出文件名爲file,這個名稱不能跟源文件名同名
-v            查看gcc編譯器的版本,顯示gcc執行時的詳細過程

b.警告選項

-Wall        打開所有需要注意的警告信息
eg:
    gcc -Wall -c main.c

C.arm-linux-ld

arm-linux-ld用於將多個目標文件,庫文件連接成可執行文件

-T:    用於指定代碼段,數據段,bss段的起始位置,也可以用來指定一個鏈接腳本,在腳本中進行復雜設置
eg:
    -Ttext startaddr        指定代碼段起始位置
    -Tdata startaddr        指定數據段起始位置
    -Tbss  startaddr        指定bss段起始位置

    注:startaddr是一個16進制的數
    
eg:
    arm-linux-ld -Ttext 0x00000000 -g led_on.o -o led_on.elf
解析:代碼段的地址爲0x00000000,由於沒有定義數據段,bss段的起始位置,它們被放在代碼段的後面

D.arm-linux-objcopy

arm-linux-objcopy被用來複制一個目標文件的內容到另一個文件中,可以進行格式轉換(常用來elf轉二進制文件)

-O        使用指定的格式來輸出文件
    eg:
        -O binary        以二進制格式輸出
-S        不從源文件中複製重定位信息和符號信息到目標文件中去

E.arm-linux-objdump

arm-linux-objdump用於顯示二進制文件信息,常用來查看反彙編代碼。

-d/-D        反彙編可執行段/反彙編所有段

F.示例

all:
	arm-linux-gcc -c -o led.o led.c
            解析:
                arm-linux-gcc -c:預處理,編譯,彙編。把led.c->.o文件
                -o:把產生的結果文件命名爲led.o

    arm-linux-gcc -c -o start.o start.S

	arm-linux-ld -Ttext 0 start.o led.o -o led.elf
            解析:
                -Ttext 0:指定代碼段的起始位置爲0(16進制)
                把文件鏈接在一起,並把目標文件命名爲led.elf

	arm-linux-objcopy -O binary -S led.elf led.bin
            解析:
                -O binary:轉換爲二進制文件
                -S:不復制重定位信息和符號
                把上面產生的文件轉換爲二進制的機器碼

	arm-linux-objdump -D led.elf > led.dis
            解析:
                -D:反彙編所有段
                >:新建文件
                <:原文件上添加
                把連接文件,轉換爲反彙編代碼

2.Makefile

A.Makefile規則

目標:依賴1 依賴2 ...
[TAB]命令

使用規則

make [目標]
a.如果無目標,默認執行第一個目標。
b.依賴文件比目標文件新時纔會去執行命令
c.如果沒有依賴,則它的命令會被強制執行

B.Makefile的語法

a.通配符:

%.*        所有的.*文件
$@         表示目標
$<         表示第一個依賴
$^         表示所有依賴
eg:
    %.o: %.c                // 所有的.o文件依賴於所有的%.c文件
        gcc -c -o $@ $^     // 把所有的依賴預處理,編譯,彙編處理爲目標文件

b.假想目標:.PHONY

可避免文件已經存在而不能進行目標名操作
eg:
    clean:
        rm *.o test
    .PHONY: clean
    解析:此時Makefil外存在一個clean文件,會影響到clean這個目標的使用。這時使用PHONY

c.即使變量,延時變量

即使變量:在定義時它的值就確定了
延時變量:在使用這個變量時纔會被確定

:=        即時變量
=         延時變量
?=        延時變量,但這個僅僅在變量還沒有定義的情況下有效,如果變量前面已經被定義了,則忽略詞條語句
+=        附加,是即時變量還是延時變量,取決於前面的定義

C.Makefile常用函數

a. $(foreach var,list,text)
b. $(filter pattern...,text)      # 在text中取出符合patten格式的值
   $(filter-out pattern...,text)  # 在text中取出不符合patten格式的值

c. $(wildcard pattern)            # pattern定義了文件名的格式,
								  # wildcard取出其中存在的文件
d. $(patsubst pattern,replacement,$(var))  # 從列表中取出每一個值
										   # 如果符合pattern
										   # 則替換爲replacement
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章