1. 程式人生 > >[bug小記]Android.mk編寫中一個小失誤引起的吐血事件

[bug小記]Android.mk編寫中一個小失誤引起的吐血事件

這兩天要開始寫新的應用以及新的NDK層引擎。

最快的方式,當然是把我之前已經寫好的、較穩定的NDK和Jni層的android工程直接拷貝過來,然後改下Android.mk裡面的引數咯。

但即使這樣,即使只是編譯一些很簡單的c++框架程式碼,也不能在eclipse工程裡面編譯通過。

先是重複報了一堆warning:

E:/android-ndk-r9c/build/core/build-binary.mk:388: warning: overriding commands for target `obj/local/armeabi/objs/...  ....o'

E:/android-ndk-r9c/build/core/build-binary.mk:388: warning: ignoring old commands for target `obj/local/armeabi/objs/...  .....o'

接下來是無止境的:

E:/android-ndk-r9c/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld.exe: ./obj/local/armeabi/objs/ ....o: previous definition here

上述刷屏N久後得到的結果是:

collect2.exe: error: ld returned 1 exit status
make.exe: *** [obj/local/armeabi/lib.....so] Error 1


最噁心的是,顯示編譯連結的進度條在這個地方卡住了,eclipse由此被hang住。折騰了幾次之後,eclipse居然各種掛,每次都要野蠻地在task manager中將make.exe程序殺死,並且將eclipse工作目錄中的.metadata資料夾刪掉,再重新啟動eclipse才能再次編譯(當然,eclipse的ndk路徑和字型設定什麼的,也都因為粗暴刪除了.metadata而要重新配了)。


在網上搜了下warning和error中關鍵字,境內中文網頁多半隻是簡單地用中文說了一遍英文錯誤資訊...沒有針對我這案例的...而個別貌似有解的境外網站就是各種打不開(也許我太乖...)然後我可能有點不耐煩吧,不再逐句檢查我的makefile了(畢竟之前專案中是好用的呀)。然後轉方向開始糾結eclipse會掛掉的問題,考慮是不是eclipse升級過沒配好啊,是不是這段時間我不小心改了什麼環境啊。總之,各種走偏。

終於,在一次鬱悶地灌下一大杯溫開水後,我開始根據自己在makefile中加入的log資訊,檢查console中的編譯log。最後發現,問題居然是LOCAL_SRC_FILES中有很多重複檔案導致的。。。。

因為我是通過MY_SRC_FILES_PATH指定原始碼的路徑們,然後獲取指定路徑們之下具體檔案們。

# do the recursion search:
MY_ALL_SRC_DIRS := $(dir $(foreach src_path,$(MY_SRC_FILES_PATH), $(call rwildcard,$(src_path),*/) ) )

# delete the same items:

MY_ALL_SRC_DIRS := $(call uniq,$(MY_ALL_SRC_DIRS))

# find the files:
MY_ALL_SRC_FILES := $(foreach src_dir,$(MY_ALL_SRC_DIRS), $(call rwildcard,$(src_dir),*.*) )

其中, rwildcard=$(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))

這顯然太囉嗦,在給MY_ALL_SRC_DIRS 和MY_ALL_SRC_FILES 賦值時,分別都做了遞迴查詢。

雖然中間呼叫uniq刪除了重複items,但得到的MY_ALL_SRC_DIRS 裡面其實是會有以下這種組合case的:

路徑A   路徑A/a  路徑A/b ... (其中路徑A/a 和A/b甚至就是在第一次遞迴查詢時由路徑A得到的)

於是接下來做第二次遞迴查詢時,路徑A下面的所有檔案都會被找到,從而跟 路徑A/a 和路徑A/b中的檔案重複了。

當我刪除了第一次遞迴查詢過程,或者在最後再加一次call uniq刪除重複item。就能編譯成功了。

在之前的專案中,由於路徑們指定得很細,在最開始就直接指定到a和b級別,正好就避免了檔案重複的可能。

以後遇到詭異的問題,還是要多耐心看log,檢查哪怕覺得不可能出錯的穩定部分。

問題雖然解決了,但比較沒想到的是:eclipse編譯ndk程式碼,會這麼脆弱,被這種編譯錯誤搞hang掉。。。不知道是不是我對eclipse還不夠了解,不懂怎樣讓它直接就handle掉重複檔案的情況。如果各位看官有這方面經驗,還請賜教喔~!O(∩_∩)O~

雖然是小bug,卻折騰這麼久。唉,且行且珍惜吧。。。