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