1. 程式人生 > >Xcode other link flag引數詳解和解決靜態庫衝突分析

Xcode other link flag引數詳解和解決靜態庫衝突分析

1.Xcode設定Other Link Flag

先猜一下這個引數,Other Link Flag 其他連結標誌,從字面上的意思來看,肯定程式碼連結的時候有關和連結器有關。

一個程式從簡單易讀的程式碼到可執行檔案往往要經歷以下步驟:

原始碼 > 前處理器 > 編譯器 > 彙編器 > 機器碼 > 連結器 > 可執行檔案

原始檔經過一系列處理以後,會生成對應的.obj檔案,然後一個專案必然會有許多.obj檔案,並且這些檔案之間會有各種各樣的聯絡,例如函式呼叫。連結器做的事就是把這些目標檔案和所用的一些庫連結在一起形成一個完整的可執行檔案。

可能我描述的比較膚淺,因為我自己瞭解的也不是很深,建議大家讀一下這篇文章,可以對連結器做的事情有個大概的瞭解:

連結器做了什麼

為什麼會閃退

蘋果官方Q&A上有這麼一段話:

The "selector not recognized" runtime exception occurs due to an issue between the implementation of standard UNIX static libraries, the linker and the dynamic nature of Objective-C. Objective-C does not define linker symbols for each function (or method, in Objective-C) - instead, linker symbols are only generated for each class. If you extend a pre-existing class with categories, the linker does not know to associate the object code of the core class implementation and the category implementation. This prevents objects created in the resulting application from responding to a selector that is defined in the category.

翻譯過來,大概意思就是Objective-C的連結器並不會為每個方法建立符號表,而是僅僅為類建立了符號表。這樣的話,如果靜態庫中定義了已存在的一個類的分類,連結器就會以為這個類已經存在,不會把分類和核心類的程式碼合起來。這樣的話,在最後的可執行檔案中,就會缺少分類裡的程式碼,這樣函式呼叫就失敗了。

解決方法

解決方法在背景那塊我就提到了,就是在Other Linker Flags里加上所需的引數,用到的引數一般有以下3個:

  • -ObjC
  • -all_load
  • -force_load

下面來說說每個引數存在的意義和具體做的事情。

首先是-ObjC,一般這個引數足夠解決前面提到的問題,蘋果官方說明如下:

This flag causes the linker to load every object file in the library that defines an Objective-C class or category. While this option will typically result in a larger executable (due to additional object code loaded into the application), it will allow the successful creation of effective Objective-C static libraries that contain categories on existing classes.

簡單說來,加了這個引數後,連結器就會把靜態庫中所有的Objective-C類和分類都載入到最後的可執行檔案中,雖然這樣可能會因為載入了很多不必要的檔案而導致可執行檔案變大,但是這個引數很好地解決了我們所遇到的問題。但是事實真的是這樣的嗎?

如果-ObjC引數真的這麼有效,那麼事情就會簡單多了。

Important: For 64-bit and iPhone OS applications, there is a linker bug that prevents -ObjC from loading objects files from static libraries that contain only categories and no classes. The workaround is to use the -allload or -forceload flags.

當靜態庫中只有分類而沒有類的時候,-ObjC引數就會失效了。這時候,就需要使用-all_load或者-force_load了。

-all_load會讓連結器把所有找到的目標檔案都載入到可執行檔案中,但是千萬不要隨便使用這個引數!假如你使用了不止一個靜態庫檔案,然後又使用了這個引數,那麼你很有可能會遇到ld: duplicate symbol錯誤,因為不同的庫檔案裡面可能會有相同的目標檔案,所以建議在遇到-ObjC失效的情況下使用-force_load引數。

-force_load所做的事情跟-all_load其實是一樣的,但是-force_load需要指定要進行全部載入的庫檔案的路徑,這樣的話,你就只是完全載入了一個庫檔案,不影響其餘庫檔案的按需載入。

2.靜態庫衝突的解決

第一種:-force_load path/to/your/報錯靜態庫.a

第二種:因為.a是由於.o檔案組成,靜態庫衝突主要原因是因為有重複部分,所以可以將兩個靜態庫去除重複部分重新合併。


相關推薦

Xcode other link flag引數解決靜態衝突分析

1.Xcode設定Other Link Flag 先猜一下這個引數,Other Link Flag 其他連結標誌,從字面上的意思來看,肯定程式碼連結的時候有關和連結器有關。 一個程式從簡單易讀的程式碼到可執行檔案往往要經歷以下步驟: 原始碼 > 前處理器 &

服務器TIME_WAITCLOSE_WAIT解決辦法

src 並不會 blog 目的 core 沒有 解決辦法 ++ 重用 來自:http://blog.csdn.net/shootyou/article/details/6622226 昨天解決了一個HttpClient調用錯誤導致的服務器異常,具體過程如下:

伺服器TIME_WAITCLOSE_WAIT解決辦法 伺服器TIME_WAITCLOSE_WAIT解決辦法

伺服器TIME_WAIT和CLOSE_WAIT詳解和解決辦法   來自:http://blog.csdn.net/shootyou/article/details/6622226   昨天解決了一個HttpClient呼叫錯誤導致的

伺服器TIME_WAITCLOSE_WAIT解決辦法

昨天解決了一個HttpClient呼叫錯誤導致的伺服器異常,具體過程如下: 裡頭的分析過程有提到,通過檢視伺服器網路狀態檢測到伺服器有大量的CLOSE_WAIT的狀態。 在伺服器的日常維護過程中,會經常用到下面的命令: [plain] view plaincopyprint?

大量TIME_WAIT的終極解決方案

上篇筆記主要介紹了與TIME_WAIT相關的基礎知識,本文則從實踐出發,說明如何解決文章標題提出的問題。 1. 檢視系統網路配置和當前TCP狀態在定位並處理應用程式出現的網路問題時,瞭解系統預設網路配置是非常必要的。以x86_64平臺Linux kernelversion

gcc擴充套件__attribute__((constructor))在.a中的使用方法

gcc對c語言做了很多擴充套件,使得c語言的表現力得到了很大的增強,本文主要介紹一下constructor擴充套件,這個擴充套件和C++的建構函式很像,它會在main函式之前由程式載入器自動呼叫,與之相對的是destructor,它會在main函式執行結束或者exit的時候自

time_wait 解決方案

1. 產生原因 2. 導致問題 3. Nginx 3.1 長連線 4. 解決方案 5 .參考 產生原因 TCP 連線關閉時,會有 4 次通訊(四次揮手),來確認雙方都停止收發資料了。如上圖,主動關閉方,最後傳送 ACK 時,會進入 TIME_WAIT 狀態,要等 2MSL 時間後,這條連線才真正

configure配置,動靜態編譯及Cmake配置

       最近在配置mapserver一整套環境,本來動態庫好好地,老闆讓搞成一個檔案,得,那基本就是靜態庫了,靜態庫合併看我發的另一個文章有說,本篇光說動靜態庫編譯。        編譯是依靠配置configure的各個屬性來配置的,一般常用的基本也就 prefix(

mencoderffmpeg引數2 (轉)

有很多軟體能夠擷取影片影象、合併影象,但如果影片太多,比如視訊網站為使用者上傳的影象生成預覽圖之類的,人工在gui方式下操作就不可取了,我們需要在命令列方式下來擷取、合併。 首先,擷取影片影象使用最多的就是mplayer或者ffmpeg,我用mplayer比較熟,本文就以此為例了,ffmpe

U_boot 的 bootcmd bootargs引數

U-boot的環境變數值得注意的有兩個: bootcmd 和bootargs。 bootcmd     前面有說過bootcmd是自動啟動時預設執行的一些命令,因此你可以在當前環境中定義各種不同配置,不同環境的引數設定,然後設定bootcmd為你經常使用的那種引數。

MultiByteToWideCharWideCharToMultiByte引數及使用方法

轉自:https://www.cnblogs.com/ziwuge/archive/2011/11/05/2236968.html https://www.cnblogs.com/gakusei/articles/1585211.html 簡單整理,未驗證,不對結果負責 函式原型: in

JSON.parseJSON.stringify 引數

JSON.parse和JSON.stringify這兩個瀏覽器自帶(IE6/7除外)的方法平常我們經常用到,但是一般都只是用到了他們的第一個引數,比如字串轉物件:JSON.parse('{}')   物件轉字串:JSON.stringify({}) 今天特意看了下這

Linux核心調整核心引數

SYN COOKIE原理和Linux核心中的實現 http://www.ibm.com/developerworks/cn/linux/l-syncookie/?ca=dwcn-newsletter-linux Linux系統下的DDOS攻擊防範 http://hi.baidu.com/mo

rsync+inotify-toos實現檔案實時同步引數

文章摘自:http://lxw66.blog.51cto.com/5547576/1331048 文章摘自:http://www.cnblogs.com/smail-bao/p/5667287.html rsync 幫助文件:http://man.linuxde.ne

Dockerfile用法引數

Dockerfile建立映象 – Dockerfile格式,對應的引數 FROM //指定基於哪個基礎映象 格式 FROM 或者 FROM :, 比如 FROM centos FROM centos:latest MAINTAINER /

Redis 主從配置引數

安裝redis 下載redis wget http://download.redis.io/releases/redis-3.0.7.tar.gz 解壓redis tar -xvf redis-3.0.7.tar.gz 安裝redis cd redis-3.0.7 “有可能需要安裝g

xmlHttp的readyState status引數

AJAX中有檢查狀態碼的, xmlHttp.onreadystatechange=handleStateChange;   function handleStateChange()  {   if(xmlHttp.readyState==4)  

Kafka概念關於springboot配置Kafka引數

1.基本概念 *Producer:            訊息生產者,往Topic釋出訊息 *Consumer:            訊息消費者,往Topic取訊

特殊許可權suid,sgid,stickyacl(訪問控制列表)引數

特殊許可權的設定基本檔案許可權見上文:http://blog.csdn.net/gui951753/article/details/79078682特殊許可權:SUID:當對一個可執行的二進位制檔案作用了suid許可權之後,任何人在執行該檔案時臨時擁有其所屬人的許可權。   

java socket引數:SendBufferSizeReceiveBufferSize

TCP傳送快取區和接收快取區,預設是8192,一般情況下足夠了,而且就算你增加了傳送快取區,對方沒有增加它對應的接收緩衝,那麼在TCP三握手時,最後確定的最大發送視窗還是雙方最小的那個緩衝區,就算你無視,發了更多的資料,那麼多出來的資料也會被丟棄。除非雙方都協商好。