第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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM