1. 程式人生 > >嵌入式linux:make 引數 ARCH與CROSS_COMPILE

嵌入式linux:make 引數 ARCH與CROSS_COMPILE

經常看到make 命令帶一些引數,例如海思編譯核心時使用命令

make ARCH=arm CROSS_COMPILE=arm-hisiv100nptl-linux- menuconfig

這時什麼意思呢?

ARCH
即architecture,就是選擇編譯哪一種cpu architecture,也就是編譯arch/目錄下的哪一個子目錄。如指定make ARCH=arm就是編譯arch/arm下的程式碼。如果不指定,make將使用本機(用什麼機器編譯就是什麼)的cpu作為預設ARCH.注意:arch/arm下不但有arm體系架構特有的程式碼,還有arm特有的kconfig,也就是配置選項,所以在make menuconfig,make xxxx_defconfig的時候也必須指定ARCH=arm。

CROSS_COMPILE

即交叉編譯器的字首(prefix),也就是選擇將程式碼編譯成目標cpu的指令的工具,如指定make CROSS_COMPILE=arm-none-linux-gnueabi-就是使用arm-none-linux-gnueabi-gcc, arm-none-linux-gnueabi-ld等工具將程式碼編譯成arm的可執行指令。如果不指定CROSS_COMPILE引數,make時將認為prefix為空,即使用gcc來編譯。這裡cross_compile的設定,是假定所用的交叉工具鏈的gcc程式名稱為arm-linux-gcc。如果實際使用的gcc名稱是some-thing-else-gcc,則這裡照葫蘆畫瓢填some-thing-else-即可

。總之,要省去名稱中最後的gcc那3個字母。

在配置或編譯核心之前,首先要確定目標CPU架構,以及編譯時採用什麼工具鏈。這是最最基礎的資訊,首先要確定的。

如果你是為當前使用的PC機編譯核心,則無須設定。

否則的話,就要明確設定。

這裡以arm為例,來說明。

有兩種設定方法():

a) 修改Makefile

開啟核心原始碼根目錄下的Makefile,修改如下兩個Makefile變數並儲存。

ARCH           := arm
CROSS_COMPILE  := arm-linux-

注意,這裡cross_compile的設定,是假定所用的交叉工具鏈的gcc程式名稱為arm-linux-gcc。如果實際使用的gcc名稱是some-thing-else-gcc,則這裡照葫蘆畫瓢填some-thing-else-即可

。總之,要省去名稱中最後的gcc那3個字母。

b) 每次執行make命令時,都通過命令列引數傳入這些資訊。

這其實是通過make工具的命令列引數指定變數的值。

例如

配置核心時時,使用

make  ARCH=arm  CROSS_COMPILE=arm-linux-  menuconfig

編譯核心時使用

make  ARCH=arm  CROSS_COMPILE=arm-linux- 

注意,實際上,對於編譯PC機核心的情況,雖然使用者沒有明確設定,但並不是這兩項沒有配置。因為如果使用者沒有設定這兩項,核心原始碼頂層Makefile(位於原始碼根目錄下)會通過如下方式生成這兩個變數的值。

SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
 -e s/arm.*/arm/ -e s/sa110/arm/ \
 -e s/s390x/s390/ -e s/parisc64/parisc/ \
 -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
 -e s/sh[234].*/sh/ )

ARCH?= $(SUBARCH)
CROSS_COMPILE?=

經過上面的程式碼,ARCH變成了PC編譯機的arch,即SUBARCH。因此,如果PC機上uname -m輸出的是ix86,則ARCH的值就成了i386。

而CROSS_COMPILE的值,如果沒配置,則為空字串。這樣一來所使用的工具鏈程式的名稱,就不再有類似arm-linux-這樣的字首,就相當於使用了PC機上的gcc。

最後再多說兩句,ARCH的值還需要再進一步做泛化。因為核心原始碼的arch目錄下,不存在i386這個目錄,也沒有sparc64這樣的目錄。

因此頂層makefile中又構造了一個SRCARCH變數,通過如下程式碼,生成他的值。這樣一來,SRCARCH變數,才最終匹配到核心原始碼arch目錄中的某一個架構名。

SRCARCH := $(ARCH)  

ifeq ($(ARCH),i386)
        SRCARCH := x86
endif


ifeq ($(ARCH),x86_64)
        SRCARCH := x86
endif

ifeq ($(ARCH),sparc64)
       SRCARCH := sparc
endif

ifeq ($(ARCH),sh64)
       SRCARCH := sh
endif