開發的過程當中,導入第三方庫(framework/.a)或者下載使用別人的demo會經常會遇到一些關于庫的導入的問題。而導入第三方庫后,這寫庫的路徑應該現在在導入當前項目target的Search Paths中,具體的設置路徑:target -> Build Settings -> Search Paths -> Framework Search Paths 或者 Library Search Paths, 頭文件在改配置中的Header Search Paths管理。
Framework Search Paths 管理導入的*.framework的路徑
Library Search Paths 管理導入的*.a的路徑
Header Search Paths 管理導入的頭文件的路徑
Search Paths相關參數說明
導入庫的時候自動生成的的路徑:$(PROJECT_DIR)/XcodeForSeachPathTest/ThirdLib/zhenLib,手動拖拽的路徑"$(SRCROOT)/../Frameworks/zhenFW/zhenFW.framework",很明顯的區別是手動拖得有雙引號,雙引號的作用是如果在路徑中有空格,可以識別該路徑。沒有雙引號但是路徑中有空格,我們發現它會自動變成兩個路徑。
路徑中有空格必須要加雙引號
多個路徑可以用空格隔開,不用雙引號包住
$(SRCROOT)/?$(PROJECT_DIR)基本沒啥區別,都是指向*.xcodeproj所在的路徑
通過../來調到上一層路徑,返回上上層文件夾用../../
$(inherited): target 的?Framework Search Paths添加$(inherited)參數會從PROJECT -> Build Settings -> Framework Search Paths里面的路徑會被其繼承,沒有的話不會繼承。所以一個項目里面有多個target,使用到了同一個庫(Library或Framework)那么為了方便我們可以在target添加繼承參數,并且PROJECT統一中添加庫的路徑。繼承的優先級:
Platform defaults
Project file (描述舉例用這個優先級,比較常用)
xcconfig file for the Project file
Target
xcconfig file for the Target
recursive:遍歷該目錄,non-recursive:默認路徑設置;不遍歷該目錄。如果路徑的屬性為recursive,那么編譯的時候在找庫的路徑的時候,會遍歷該目錄下的所有子目錄的庫文件。PS:在搭建項目的時候,可以創建一個專門放庫文件的文件夾并且設置其屬性為recursive。$(PROJECT_DIR)/**相當于遍歷項目文件同級下的所有路徑(不推薦使用,項目大的話,影響編譯的速度)。
Search Paths子選項:Header Search Paths 、User Header Search Paths的參數設置與其相同
XCode用戶可以 通過Header Search Paths 來配置環境變量。但這里涉及到一個另外一個參數 User Header Search Paths, 這兩者到底有什么區別呢?
首先明確一點,Header Search Paths 顧名思義就是用來存放 Project 中頭文件的搜索根源,沒有被add到項目里的頭文件,可以通過配置Header Search Paths 來引入頭文件,這樣的好處可以不讓project 包含的文件太多,便于管理。
?? ? 淺顯一點的區別是,編碼時候通過 #include 引入頭文件的方式有兩種 <> 和 ""。<> 是只從 Header Search Paths 中搜索, 而 "" 則能從? Header Search Paths 和? User Header Search Paths 中搜索。換言之 ,假如你把 路徑加到? User Header Search Paths 中,那么 你用 #include <file.h> 的方式去引入對應的頭文件,就會報錯。 如果加到? Header Search Paths,? 就沒有問題了。
?? ? 具體一點的區別是,<> 是從系統目錄空間 (對應 Header Search Paths)中搜索文件, "" 是從用戶目錄空間(對應 User Header Search Paths)中搜索文件。如果你把路徑加到 User Header Search Paths 中,而 <> 無法從系統目錄空間中找到新加的路徑,從而報錯。
所以在修改User Header Search Paths這個選項的時候使用
"$(SRCROOT)/當前工程名字/需要包含頭文件所在文件夾"
將上面的雙引號里面的字符串拷貝之后,你會發現這個“$(SRCROOT)”,會自動變成當前工程所以的目錄。
這樣就可以了,發給別人,別人也不用在去修改路徑了。
1.c/c++ 頭文件引用問題
include <> 引用編譯器的類庫路徑下的頭文件
include “” 引用工程目錄的相對路徑的頭文件
include 是編譯指令,在編譯時,編譯器會將相對路徑替換成絕對路徑,因此,頭文件絕對路徑=搜索路徑+相對路徑。
Xcode Build Settings 下 Search Paths設置搜索路徑
Header Search Paths:頭文件搜索路徑設置
$(SRCROOT)宏和$(PROJECT_DIR)宏都指xxx.xcodeproj所在的父目錄
例如:引用工程testDemo/scr/test.h 頭文件,
Header Search Paths中添加$(SRCROOT),引用為include “scr/test.h"
如果在Header Search Paths中添加$(SRCROOT)/scr,那么頭文件引用直接引用 include “test.h”
1.
$(inherited) "$(SRCROOT) 修改.a文件的路徑 --Library Search Paths
?$(inherited) "$(SRCROOT)/.a文件所在的文件名"
? //如果有多個.a文件格式就像這樣
$(inherited) "$(SRCROOT)/xxxx" "$(SRCROOT)/xx"
?如果取的是相對是絕對路徑那么工程移到別的地方就有可能導致運行出錯。所以要改成相對路徑
=========library searchpath
Project的Building Settings中得設置默認并不被Targets繼承,只有當Targets的設置加入了$(inherited)時才被繼承,添加目錄的時候寫上 “$(inherited)” 就表示從frameworks里面讀取。
一種很常見的情況, 我建一個工程運行正常,但是把工程發給別人就會出現這個錯誤,這也是XcodeSearch?Path的相對路徑和絕對路徑導致的。
所以在修改Library /?Header?Search Paths這個選項的時候使用: ?"$(SRCROOT)/當前工程名字/需要包含頭文件所在文件夾"
將上面的雙引號里面的字符串拷貝之后,你會發現這個“$(SRCROOT)”,會自動變成當前工程所以的目錄。這樣就可以了,發給別人,別人也不用在去修改路徑了。
Xcode添加靜態庫以及編譯選項配置常見問題
一,Xcode編譯出現Link錯誤,出現"duplicate symbols for architecture i386 clang"提示.
問題:鏈接時,項目有重名文件.
解決:
根據錯誤提示,做如下檢查:
1.Taraget->Build Settings->Link Binary With Libraries檢查是否有重復lib.
2.全工程搜索下重名文件,決定如何刪除.
二,關于Category位于靜態庫時,引用該靜態庫的工程使用Category,出現"unrecognized selector sent to class"提示.
問題:標準UNIX靜態庫與Objective-C之間Linker的差異.在標準的UNIX靜態庫內,linker symbol是依照每一個類別而產生的,但由于Category并沒有真正產生一個類別,所以出錯.
解決:
1.在該靜態庫的Taraget->Build Settings->Other Linker Flags->加上 -ObjC.
2.在使用該靜態庫的工程Taraget->Build Settings->Other Linker Flags->加上-all_load或-force_load.
三,編譯warning:ld: warning: directory not found for option '-L'.
問題:通常是Path問題.
解決:
Taraget->Build Settings->Library Search Paths 和 Framework Search Paths,刪掉編譯報warning的路徑即OK
四,引入(帶源碼的)靜態庫所需配置.
步驟:
1.Add Files to.. 加入靜態庫的.xcodeproj 文件,不要勾選Copy Items.. 選項。(可以先把源代碼項目先復制到使用項目文件夾下)
2.Target->Build Phases->Target Dependecies->加靜態庫 && Link Binary With Libraries->加靜態庫.
3.配置靜態庫頭文件路徑,在Taraget->Build Settings->User Header Search Paths->配上靜態庫的物理路徑.
[錯誤tips: 若出現加入的.xcodeproj無法展開,則在Xcode中關閉靜態庫項目即可]
PS:只有.a 和 .h的靜態庫,則直接拖入項目即可。
五,關于重構,解決跨層調用問題,
常用選擇:
1.傳參(包括靜態變量的使用)
2.傳回調
3.直接移動調用的代碼(若代碼出現在不適合的地方,移動類/方法/etc)
之所以使用該標志,和Objective-C的一個重要特性:類別(category)有關。根據這里的解釋,Unix的標準靜態庫實現和Objective-C的動態特性之間有一些沖突:Objective-C沒有為每個函數(或者方法)定義鏈接符號,它只為每個類創建鏈接符號。這樣當在一個靜態庫中使用類別來擴展已有類的時候,鏈接器不知道如何把類原有的方法和類別中的方法整合起來,就會導致你調用類別中的方法時,出現"selector not recognized",也就是找不到方法定義的錯誤。為了解決這個問題,引入了-ObjC標志,它的作用就是將靜態庫中所有的和對象相關的文件都加載進來。
本來這樣就可以解決問題了,不過在64位的Mac系統或者iOS系統下,鏈接器有一個bug,會導致只包含有類別的靜態庫無法使用-ObjC標志來加載文件。變通方法是使用-all_load 或者-force_load標志,它們的作用都是加載靜態庫中所有文件,不過all_load作用于所有的庫,而-force_load后面必須要指定具體的文件。
*************pch(prefix header)設置
如何添加pch文件呢?
向項目中添加新文件,在Other中選擇PCH File:
設置pch文件的路徑。
target ->Build Setting ,向搜索框輸入prefix header:
設置Precomplite Prefix Header 的布爾值為true,
作用是讓pch文件預編譯后緩存起來,減少之后的編譯時間
設置Prefix Header的值為:
$SRCROOT/(你的項目名稱)/(你的pch文件名稱)
如:$(SRCROOT)/GIFMaker/GIFPrefixHeader.pch
也可以直接把pch文件拖進來,但是這是絕對路徑,到另外一個項目回報錯
其中的變量SRCROOT的值為你項目所在的根目錄,
它會隨著你項目的目錄遷移而自動改變。
ok, 現在pch文件添加成功了。
***************倒入co coaPods后的文件路徑問題---CocoaPods導入第三方庫,提示找不到頭文件的解決方法
通過cocoaPods倒入框架后;找到TARGETS -> Build Settings -> SearchPaths -> User Header Search Paths ?在后面的空白處雙擊;在Header search path中新增一個值”$(PODS_ROOT)”,并且選擇”recursive”,這樣Xcode就會在項目目錄中遞歸搜索文件且會自動找到Pods文件,頭文件自動補齊功能馬上就好使了.
***************項目里有該文件,但是還是顯示找不到。或者是cocopods打開的項目。
原因:.h文件路徑找不到。具體找不到的原因有很多種。
可能pods 的頭文件找不到
#import "Reachability.h"找不到
首先找到下面配置文件:
Reachability-Private.xcconfig
?查看里面內容:
#include "Reachability.xcconfig"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private"?"${PODS_ROOT}/Headers/Private/Reachability"?"${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/MKNetworkKit" "${PODS_ROOT}/Headers/Public/MKNetworkKit/Categories" "${PODS_ROOT}/Headers/Public/Reachability"
OTHER_LDFLAGS = ${REACHABILITY_OTHER_LDFLAGS}
PODS_ROOT = ${SRCROOT}
SKIP_INSTALL = YES
上面標紅的地址,去文件夾看看相應路徑是否存在該文件,經常是在別的文件夾下面。
---------------------
作者:liyubao160
來源:CSDN
原文:https://blog.csdn.net/u011146511/article/details/77198330
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!