起源
最近在項目中集成百度地圖的相關功能,不過遇到了一個問題岭佳。百度地圖中集成了ssl庫libssl.a血巍,而我們工程中的另外一個第三方庫也集成了這個庫。編譯的時候就會造成沖突珊随,顯示ld: 4773 duplicate symbols for architecture x86_64述寡。
解決方式
解決問題的方式大概就分為兩種:
1.修改其中的一個第三方庫文件柿隙。
2.修改OTHER_LDFLAGS的編譯選項,讓編譯器只編譯其中的一個ssl庫鲫凶。
第一種方式禀崖,網(wǎng)上有不少文章說,具體可以參考:
http://www.reibang.com/p/c7274dca62f7
第二種方式螟炫,主要和OTHER_LDFLAGS選項有關波附。
OTHER_LDFLAGS詳解
OTHER_LDFLAGS常用的有三種:
-ObjC
鏈接器會把靜態(tài)庫中所有的Objective-C類和類別都加載到最后的可執(zhí)行文件中。
-all_load
強制鏈接器把所有找到的目標文件都加載到可執(zhí)行文件中昼钻。
-force_load
所做的事情跟-all_load其實是一樣的掸屡,但是-force_load需要指定要進行全部加載的庫文件的路徑。
但是千萬不要隨便使用-all_load和-force_load參數(shù)然评!假如你使用了不止一個靜態(tài)庫文件仅财,然后又使用了這個參數(shù),那么你很有可能會遇到ld: duplicate symbol錯誤碗淌,因為不同的庫文件里面可能會有相同的目標文件盏求。但是在cocoapods創(chuàng)建的工程中,它會自動的設置OTHER_LDFLAGS為-ObjC -all_load 亿眠。
之所以這樣做是因為在xcode4之前碎罚,xcode有個bug,你用了-ObjC以后纳像,如果類庫中只有category沒有這個類的具體實現(xiàn)時候荆烈,這些category是加載不進來。變通方法就是加入-all_load或者-force-load爹耗。-all_load會強制鏈接器把目標文件都加載進來耙考,即使沒有objc代碼。
因此我們可以將工程中的-all_load 直接去掉就行潭兽,但是因為我們是使用cocoapods來管理工程的,為了不需要每次pod install之后都需要刪除這個參數(shù)斗遏,我們需要修改podfile文件山卦。
CocoaPods的解決方法
post_install do |installer|
installer.pods_project.targets.each do |target|
#獲取準備修改的pod工程 `Pod-target-lib`
if target.name == "Pod-target-lib"
puts "Updating #{target.name} OTHER_LDFLAGS"
#獲取工程的xcconfig文件的路徑
xcconfig_path = ""
target.build_configurations.each do |config|
new_xcconfig_path = config.base_configuration_reference.real_path
puts "new_xcconfig_path #{new_xcconfig_path} OTHER_LDFLAGS"
if new_xcconfig_path != xcconfig_path
xcconfig_path = config.base_configuration_reference.real_path
# 從xcconfig中讀取build_settings到字典中
build_settings = Hash[*File.read(xcconfig_path).lines.map{|x| x.split(/\s*=\s*/, 2)}.flatten]
# 刪除 OTHER_LDFLAGS 中的-all_load
other_flag = build_settings['OTHER_LDFLAGS'];
build_settings['OTHER_LDFLAGS'] = other_flag.gsub('-all_load',' ')
# 清除當前文件的內(nèi)容
File.open(xcconfig_path, "w") {|file| file.puts ""}
# 將build_settings字典寫回xcconfig
build_settings.each do |key,value|
File.open(xcconfig_path, "a") {|file| file.puts "#{key} = #{value}"}
end
end
end
end
end
end
這樣,每次pod install后诵次,都會自動尋找當前工程的xcconfig配置文件账蓉,并將其中的OTHER_LDFLAGS中的-all_load選項替換成空格鍵。
其他注意事項
不過需要注意的是逾一,你需要保證這兩個相互沖突的第三方庫所共同引用的庫的版本是相同的铸本,否則可能會出現(xiàn)異常。
如果出現(xiàn)所引用的兩個第三方庫的版本不同遵堵,出現(xiàn)符號沖突時箱玷,動態(tài)鏈接會使用先加載的符號怨规。也就是說在Link Binary With Libraryies中靠前的的動態(tài)庫會優(yōu)先被鏈接,并占據(jù)當前符號的具體實現(xiàn)锡足,后續(xù)的重復類或者方法會自動被忽略波丰。
參考文獻:
https://www.cnblogs.com/lulushen/p/7646635.html