天天看點

util-linux交叉編譯,交叉編譯的方法

如何交叉編譯 應用程式,技巧,注意事項。

最近大家都涉及交叉編譯應用程式, 感覺大家的路子有點偏 ,覺得有必要糾正一下。

一般的應用程式 ,編譯的步驟無外呼 ./configure && make && make install

但是對于 交叉編譯不能照搬 , 尤其要注意不能輕易make install (當然如果指定了 --prefix就無所謂了, 否則可能會覆寫标準路徑的程式就慘了)

這裡有兩個思路:

1>對于剛開始交叉編譯的人來說, 往往很暈 , 總想借助 ./configure 後面加一堆參數來解決 ,比如 ./configure --target=arm-9tdmi-linux-gnu --host=arm-9tdmi-linux-gnu 來搞定 ,

對于一般的小的程式來說, 應該沒有問題, 而且也推薦大家這樣用, 但是要注意 , 這樣作之前 ,先要 ./configure --help |grep --host ,看看有沒有這樣的選項, 如果沒有呢?

想想也可能, 如果程式的作者根本沒有考慮到除了x86的平台呢?你隻能自己改寫Makefile 了。

是以 ,./configure 不是萬能的,而且文法很混亂 ,不要指望 ./configure 給你作一切。而且局限很大。

2>是以這個時候 ,就要求交叉編譯的第二個層次, 自己改寫Makefile ,想怎麼改就怎麼改,靈活性最大 需要你開始就./configure 一下, 跟平台有關的參數一律不加。

./configure 過後就會生成Makefile 了, 裡面的gcc相關的參數,包括lib的路徑當然是x86下的了, 比如 /usr/local/lib/ , /usr/lib/ ,/lib/ 什麼的, 改掉就是了。 或者注釋掉。

gcc 要換成 arm-linux-gcc一類的編譯器, (如果不想每次都改, 參考下面的 include prerules.mk的做法) ,

總之, 這要求你的Makefile掌握的很熟練, 思路就是 邊編譯 ,發現問題,再改, 即使一開始Makefile不熟練, 到後來,也熟練了。 是個練習Makefile的好方式。

總之, 我們最後要的就是Makefile , 看你怎麼能得到它。

一個最标準的Makefile (去掉很多無用的東西)

通過./configure 生成的Makefile ,你會發現備援的地方非常多, 其實關鍵的地方,就那麼20幾條, 可以試着精簡一下, 這樣對程式的組織架構會熟悉的快一些, 畢竟Makefile反應了

程式(具體就是 .c 和 .h )之間的依賴關系 。

openssh 的Makefile我沒有精簡過(當然要精簡也很容易), 舉個telnetd的例子,

說明一下:

---------------------------telnetd ----------------------------------------

#-----------------------------------------------------

TOPDIR  :=  $(shell /bin/pwd)

TOPDIR  :=  $(TOPDIR)/..

#prerules.mk 包含了這些變量的定義, 比如 $CC , $CPP , $CXX , $CFLAGS 等等。

#盡量不要在這裡出現, CC=arm-linux-gcc這樣的定義,擴充性不好, 盡量用 全局變量,便于管理和拓展。

include $(TOPDIR)/prerules.mk

#-----------------------------------------------------

EXEC = telnetd

#好的Makefile都是這樣寫的, 也就是具體生成一個可執行檔案或者lib庫, 需要哪些.o , 這些.o 會依據後面的 .c.o : 規則來編譯出來的。

OBJS = telnetd.o state.o termstat.o slc.o sys_term.o \

utility.o global.o authenc.o logwtmp.o logout.o

#$(CC) 的編譯選項, 一般程式自己的帶的,不要改它, 而且一般都是+= , 不要用 = ,

CFLAGS += -DEMBED -DPARANOID_TTYS -DUSE_TERMIO -DKLUDGELINEMODE -D_GNU_SOURCE -Wall

ifdef CONFIG_DEFAULTS_LIBC_UCLIBC

LDLIBS := -lutil $(LDLIBS)

endif

all: $(EXEC)       #很顯然all是最關鍵的了, 也要發在最開始的地方。 這樣make 就相當于make all , 這是大家的潛規則。

.c.o:

$(CC)  -c -o $@ $

$(EXEC): $(OBJS)

$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS$(LDLIBS_$@))     #這裡的LDFLAGS=-lcrypt -lzlib  -L../lib -L.  總之根據自己的需要往裡面增加。

$(STRIP) telnetd        #如果不需要調試, 一定要strip一下, 比如 15M的file ,strip過後, 可能變成 3M , 還不影響功能。

install:

cp $(EXEC) $(T_USBIN)                    #自己寫install , 不要用原來的, 可以copy到自己的ramdisk中去。

clean:

-rm -f $(EXEC) *.elf *.gdb *.[do]

$(OBJS): defs.h ext.h pathnames.h telnetd.h logwtmp.h logout.h