1. 程式人生 > >iOS經典錯誤library not found for -lXXX

iOS經典錯誤library not found for -lXXX

開發中經常會和ibrary not found for -xxx打交道,尤其是我們從遠端倉庫或者github clone下來一個專案,編譯很有可能報這個錯誤。如下圖:


報錯資訊


library not found for -lXXX 屬於iOS經典錯誤之一。下面我們通過復現這個錯誤的方式來說明這個錯誤的解決方法。其中l是lib(library)的意思。

首先宣告,我的工程中引用了友盟的統計SDK,名稱叫做libMobClickLibrary.a。儲存在 third_party目錄下,如下圖(左圖為libMobClickLibrary.a在工程目錄/虛擬目錄的位置,右圖為libMobClickLibrary.a在磁碟目錄/物理目錄的位置):


工程目錄
磁碟目錄

沒有配置Library Search Paths導致報錯

(1)刪除building setting -> Library Search Paths下的 $(PROJECT_DIR)/YunFu/third_party/UMAnalytics。如下圖:
那麼,你可能會問,為什麼要刪除這個路徑而不是其他的路徑呢?因為我知道這個路徑就是libMobClickLibrary.a靜態庫的目錄。


(2)command + B編譯專案,然後不出所料,我們會遇到下面這個錯誤:


(3)點開這個錯誤,然後就能看到這個經典錯誤,如下圖:
這個錯誤的意思是找不到名字叫做 MobClickLibrary的庫。


至此,我們可知,就因為我們在Library Search Paths下刪除了$(PROJECT_DIR)/YunFu/third_party/UMAnalytics 導致報這個library not found for -lMobClickLibrary的錯誤。所以下次遇到同類問題,我們便可知道某個靜態庫的路徑可能沒有配置。

結論一:沒有配置靜態庫的search路徑導致出現library not found for lXXX。
注意:設定的路徑必須是靜態庫在磁碟下的路徑(物理目錄),不能設定為專案的虛擬目錄。拿此例來說,libMobClickLibrary.a的在專案中是放在third_party資料夾下的,而其真正的磁碟路徑是third_party下的UMAnalytics資料夾。

沒有正確配置Library Search Paths導致報錯

上面的情況是,我們沒有配置某個靜態庫的路徑會導致library not found for lXXX錯誤。而有時候,我們確實在Library Search Paths下配置了靜態庫路徑,卻依然報同樣錯誤。此時我們就要考慮,這個路徑配置的到底對不對。如下圖(分別是libMobClickLibrary.a正確的路徑和錯誤的路徑):
正確路徑:


正確路徑

錯誤路徑(去掉了最後一級目錄"/UMAnalytics"):


錯誤路徑

編譯專案依然會報同樣的錯誤library not found for -lMobClickLibrary.a,如下圖:


錯誤資訊

歸根到底,原因在於,我們雖然跟他指定了libMobClickLibrary.a的目錄,但是在所指定的目錄下沒有搜尋到靜態庫libMobClickLibrary.a。此時又分為兩種情況:

  • 情況一:如果我們指定的目錄和靜態庫libMobClickLibrary.a的目錄完全不相關,那麼需要重新到Library Search Paths下設定(注意:設定的是靜態庫的磁碟路徑)

  • 情況二:如果我們指定的目錄和靜態庫的目錄有關係。即,我們指定的目錄是靜態庫所在目錄的上級目錄,或者是上上級目錄。這種情況下,無需指定靜態庫的精確的路徑,只需要把non-recursive選項修改為recursive即可。如下圖:


    設定recursive

因為recursive選項代表在我們指定的目錄下遞迴搜尋靜態庫。即,如果在當前目錄沒有搜尋到靜態庫,那麼就去當前目錄的子目錄下繼續搜尋。預設情況下是non-recursive(非遞迴)的。

結論二:雖然Library Search Paths 中配置了靜態庫的search路徑。但是沒有正確配置而導致出現library not found for lXXX。

匯入第三方framework靜態庫編譯報錯xxx.h file not found

上面講的是當我們專案匯入的是.a靜態庫,但因為沒有在 Library Search Paths 中配置.a靜態庫的search路徑,或者是雖然配置了路徑但是路徑配置錯誤而導致出現library not found for -xxx錯誤的解決辦法。
但我們知道,在iOS中,靜態庫有兩種形式:.a格式的靜態庫和.framework格式的靜態庫。
那麼如果我們的專案中引入了.framework格式的靜態庫要不要配置search路徑呢?答案是肯定的,無論我們以什麼方式匯入.framework靜態庫(cocoapods的方式或者直接把framework靜態庫拖拽到專案中的方式),如果沒有配置framework的search路徑,同樣會報錯,但報的錯誤卻是和.a格式的靜態庫有些不同,如果我們專案中引入了framework格式靜態庫也使用了靜態庫(所謂使用就是import了framework靜態庫中的某個標頭檔案),但沒有配置search路徑,那麼就會報 xxx.h file not found 這類錯誤。如下圖:


xxx file not found

因為我的專案中引入了一個叫做PushCenterSDK.framework的靜態庫。同時也使用了這個靜態庫中的某個API。如下圖所示,分別是靜態庫在專案中的路徑和磁碟路徑:


在專案中的路徑
在磁碟中的路徑

我們依然採用復現問題的方式來驗證解決錯誤的方法,首先,我的專案是可以編譯通過的,然後嘗試在build setting -> Framework Search Paths 下刪除PushCenterSDK.framework的搜尋路徑(磁碟路徑),下圖分別是刪除前和刪除後的截圖:

刪除前:


刪除前

刪除後:


刪除後

刪除路徑之後編譯專案,發現出現瞭如下錯誤XXX.h file not found, 如下圖:
很顯然,沒有找到PushCenterSDK 下的TBSDKPushCenterEngine.h檔案。


報錯

綜上,framework靜態庫的路徑也是必須的,如果專案中的framework靜態庫的路徑配置錯誤或者沒有配置就會報錯 xxx.h file not found 類似錯誤。下次遇到這類錯誤,便可以從framework search paths 著手思考。

同樣,framework靜態庫的搜尋路徑也支援遞迴搜尋,我們不必配置一個精確無誤的路徑,可以指定一個父級目錄,然後選擇 recursive。

結論:無論我們以什麼方式匯入.framework靜態庫(cocoapods的方式或者直接把framework靜態庫拖拽到專案中的方式),如果沒有配置framework的search路徑,同樣會報錯,但報的錯誤卻是和.a格式的靜態庫有些不同,如果我們專案中引入了framework格式靜態庫也使用了靜態庫(所謂使用就是import了framework靜態庫中的某個標頭檔案),但沒有配置search路徑,那麼就會報 xxx.h file not found 這類錯誤

轉載地址:http://www.jianshu.com/p/72aec7e38ef0