ndk-build 編譯報錯 fatal error: error writing to -: Invalid argument } ^

最近下載同事的 Android 工程代碼,協作開發一些 Native 底層功能,需要首先編譯底層的一些 JNI 的代碼庫,由於工程較大,且依賴的第三方庫比較多,下載完畢後,通過 ndk-build 進行編譯,報了一些個奇怪的錯誤,並指向了代碼文件的最後一行,如下所示:

fatal error: error writing to -: Invalid argument } ^

此工程源碼一直是同事在 MAC 下進行開發維護的,在同事的環境中是正常的,而我是 Windows 平臺,剛開始懷疑是文件類型不對,通過 NotePad++ 轉換代碼文件格式爲 UNIX ,編譯測試失敗;通過 msys  的 VI 編輯器新建文件複製此代碼文件內容並保存爲新的文件,經測試也是不行,至此判斷應該不是文件格式的問題了。

通過 Google 查找此錯誤信息,資料甚少,只有一個有用的信息,說是文件路徑名太長了,改短一點就行了,我們知道 Windows 系統對路徑的最大長度限定爲 260 字節,但是我查看我們的文件全路徑總長度也就才 130 幾個字節,尚未查過最大長度,但通過簡單的嘗試,如僅僅是縮短了文件名長度,進行編譯,最後發現還是有些效果的,至少大部分 native 代碼文件不會再報此類錯誤了,但是不幸的,NDK 編譯的四個 ABI 架構(armeabi、armeabi-v7a、arm64-v7a、x86),前三個 ABI 都是可以編譯成功的,唯獨最後一個仍然會報上述錯誤,而且報錯的只會是 LOCAL_SRC_FILES 指向的第一個代碼文件,調整代碼文件順序依舊,這就說明了這種編譯錯誤應該是與 Android.mk 文件有關了,而此 mk 文件在同事的 MAC 上運行一切正常,唯獨到我的 Windows 上運行出現各種錯誤,針對此問題,看來還是上述方法中通過簡單的縮短代碼文件名的方法並沒有從根本上解決問題,通過仔細查看 ndk-build 編譯過程中輸出的日誌信息,發現其生成的代碼中間文件 *.o 存儲在 objs 的很深的目錄,是吧我代碼文件的全局路又複製了一遍,通過 Windows 的快捷鍵去複製、粘貼 這樣的文件夾,系統就會報錯,提示路徑長度太長,至此,我似乎看到一絲希望。

原來同事爲了保證大家下載編譯這個工程目錄能夠統一,在代碼文件前定義了一個宏變量,如:

ENCODER_MODULE_PATH := $(TOP_LOCAL_PATH)/encoder-module

然後在引用指定代碼文件列表的時候,加上了此宏變量作爲前綴,如:

LOCAL_SRC_FILES += $(ENCODER_MODULE_PATH)/video_encoder.c 

這樣就相當於給此文件制定了一個絕對路徑了,由於代碼所在目錄本來就很深,這樣相當於在 obj 中間文件目錄中重複了一遍源文件的目錄,導致整體路徑長度超過了 260 字節,從而報出此類奇葩的錯誤,而 Linux 下系統對目錄的最大長度限制默認爲 4096,怪不得同事的 MAC 系統不報錯。好的,原因知道了,修改源文件列表中由絕對路徑改爲相對路徑就可以了,如:

LOCAL_SRC_FILES += ./video_encoder.c

至此,大功告成,編譯成功!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章