1. 程式人生 > >ios程式編譯連結引數 all_load 的 ld duplicate symbol 的bug及修復

ios程式編譯連結引數 all_load 的 ld duplicate symbol 的bug及修復

duplicate symbol _OBJC_CLASS 的幾種原因

1.專案檔案裡面有多個相同名字的檔案;

2.import 的時候.h寫成.m了;xcode的自動完成特性,在你匯入標頭檔案的時候,將".h"補成了".m"

3.有多個main檔案。

問題

-all_load 是在Objective-C 編譯時常用到的一個引數,比如這篇文章所介紹的,。但是我們在加入這個引數後,有時會出現“ld: duplicate symbol _main“的錯誤,比如 libCurl duplicate symbol,但是把 -all_load 引數從 Other Like Flags 裡去掉後,編譯雖然可以通過,但在執行時會崩潰。問題出在什麼地方呢?

分析

參考 Universal static library problem in iPhone SDK(需翻牆,通過bing的cache檢視),cocos2d for Mac ,Building Objective-C static libraries with categories 等文章,我們可以大概知道 -all_load 的作用:

Objective C 中特有的語法特性 Category 大家肯定很熟悉,類似於C#中的擴充套件方法,可以在一個類的外面擴充套件這個類的功能,使得我們可以
方便的為系統類新增自己的功能,比如為 NSString 新增 md5 編碼。在編譯到靜態庫時,這些程式碼模組實際上是存在不同的obj檔案裡的。程式
在連線Category方法時,實際上只加載了Category模組,擴充套件的基類程式碼並沒有被載入。這樣,程式雖然可以編譯通過,但是在執行時,因為找
不到基類模組,就會出現 unrecognized selector 這樣的錯誤。

但是使用了 -all_load 之後,隨之而來的問題就是,有的庫裡自作主張的定義了main函式,比如 libcurl.a。誰知道他們定義main函式是幹什麼的,但問題就是這個樣子。因此,-all_load,加還是不加,這是個問題。

解決方案

有兩個解決方案,其實都是尋找 -all_load 的替代引數。

蘋果的官方文件裡給了我們一個解決方案,使用 -ObjC 引數。它的文件說,-ObjC 引數會把所有的 Objective-C 程式碼模組載入,所以程式會有點臃腫;也許libcurl不是 Objective-C 實現的,所以不會載入。但相對於巨大的圖片聲音資源來說,程式稍微變大一點應該不算什麼。

另外一個解決方案是 使用 -force_load 引數,可以參考 Objective-C categories in static library,How can I avoid “duplicate symbol” errors in xcode with shared static libraries?。我們可以只加載感興趣的 靜態庫。

相關推薦

ios程式編譯連結引數 all_loadld duplicate symbolbug修復

duplicate symbol _OBJC_CLASS 的幾種原因 1.專案檔案裡面有多個相同名字的檔案; 2.import 的時候.h寫成.m了;xcode的自動完成特性,在你匯入標頭檔案的時候,將".h"補成了".m" 3.有多個main檔案。 問題 -all_lo

【C程式編譯連結】gcc使用命令介紹 gcc的使用簡介與命令列引數說明

1.gcc或者g++安裝rpm -qa|grep gcc ==>檢查gcc是否安裝gcc -v ==>檢查gcc版本 編譯器會在可執行檔案中植入一些資訊,可執行檔案會變大。一般開發時候使用 -g ,編譯一個 “release 版本” 時不使用 -g 編譯。gcc如果是最新的則不重

【C程式編譯連結】gcc使用命令介紹 GCC編譯器編譯連結  

1.gcc安裝 rpm -qa|grep gcc ==>檢查gcc是否安裝 gcc -v ==>檢查gcc版本 yum -y install gcc ==>安裝gcc  2.基本語法 gcc最基本的用法是:gcc [options]

程式編譯連結

預處理:.c --> .i $ gcc -E hello.c -o hello.i 編譯: .i 或 .c --> .s $ gcc -S hello.i -o hello.s 彙編:.s --> .o $ gcc -c hello.s -o hello

Linux程式編譯連結動態庫版本的問題

不同版本的動態庫可能會不相容,如果程式在編譯時指定動態庫是某個低版本,執行是用的一個高版本,可能會導致無法執行。Linux上對動態庫的命名採用libxxx.so.a.b.c的格式,其中a代表大版本號,b代表小版本號,c代表更小的版本號,我們以Linux自帶的cp

程序虛擬地址空間 程式編譯連結過程

1..程式編譯、連結、執行的過程。 (1)預編譯階段**** 生成*.i檔案。 處理原始碼檔案,即以“#”開始的預編譯指令。 有展開巨集;去註釋;新增行號;保留所有#pragma編譯指令。

【作業系統】4.1程式編譯連結

知識回顧: 主存:儲存程序執行時的程式和資料 暫存器:速度最快,價格昂貴容量不大,一般以字為單位,只要存放指令一次操作的資料就夠了 。 快取記憶體:一種速度比記憶體快的儲存裝置,一般同暫存器一樣整合在CPU中。存放記憶體的部分拷貝,把常用的資料放這裡可以提高速度。將

【Not BUG】微軟Winform窗體中設計上的Bug,會導致程式編譯失敗?不,這不是BUG

這不是BUG!!! 原文地址: https://www.cnblogs.com/thanks/p/14302011.html   現在讓我們回憶一下原文       原文的操作步驟: 1. 新建一個Window Form窗體,命名為Form1 2. 在Fo

eclipse下新增GCC編譯器的編譯連結庫以及程式執行引數方法

eclipse下新增GCC編譯器的編譯連結庫 在Linux下編寫多執行緒程式,在呼叫pthread.h下的函式時需要新增連結庫,如果是在命令列的環境下只需要在gcc命令後加上 -pthread就可以編譯、連線通過,但是如何在eclipse下新增-pthread?不然會出現

xcode上編譯c語言程序報錯:ld: x duplicate symbol for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

text internal self. value gen scrip info 內容 讀取 在網上查了一下: duplicate symbol的大概意思是,編譯器認為你重復定義了一些東西。 linker command failed with exit cod

VC如何在編譯連結程式過程中在輸出視窗看到連結的順序

VC如何在編譯連結程式過程中在輸出視窗看到連結的順序 具體操作:選擇VC選單Project->Settings->Link頁,然後在Project Options的Edit欄中輸入/verbose:lib,這樣就可以在編譯連結程式過程中在輸出視窗看到連結的順序了。 同時這樣也可以解決

GCC 編譯連結 以及相關引數

1) 預處理 gcc -E test.c -o test.i 2) 編譯為彙編程式碼(Compilation) gcc -S test.i -o test.s 3) 彙編(Assembly) 二進位制檔案 gcc -c test.s -o test.o 4) 連線(Linking) gcc te

程式編譯連結

程式進記憶體的一般過程: 1、編譯compiler:編譯程式:將使用者原始碼編譯成若干個目標模組。 2、連結link:連結程式:將形成的一組目標模組,及它們需要的庫函式連結在一起,形成一個完整的裝入模組。 3、裝入load:由裝入程式將裝入模組裝入記憶體,構造P

程式編譯連結與執行--IAR

IAR是很多嵌入式平臺的編譯連結與下載工具,為程式設計人員提供了極大的方便。下面我將以它為例來詳細解說。一般程式下載進入相應的硬體平臺需要以下三個階段:程式的編譯、程式的連結、程式的執行。 1.1 程式的編譯階段 編譯,首先由編譯器和彙編器,生成可重定向的目標檔案,或也可

make,makefile和程式編譯連結過程

一,Linux下程式執行過程 1,在一個目錄下新建三個檔案:main.c hello.c hello.h分別編寫他們如下圖: 2,想要讓這個程式執行起來,就必須對上面的三個檔案分別進行編譯連結執行,如下圖: 通過上面這個過程。我們可

程式編譯連結過程

原文連結: https://www.cnblogs.com/kekec/p/3238741.html還是從HelloWorld開始說吧...#include <stdio.h> int main(int argc, char* argv[]) { pri

程式編譯連結原理理解

一、本書解決的問題本書主要介紹系統軟體的執行機制和原理,涉及在Windows和Linux兩個系統平臺下,一個應用程式在編譯、連結、和執行時所做的事,具體如下:1.Windows和Linux作業系統下各自的可執行檔案、目標檔案格式?2.普通的C/C++程式程式碼如何編譯成目標

C/C++程式編譯連結過程

在以前學習C語言的時候,想必大家寫的第一個程式碼都是“hello world”吧。在以前我們除錯一個程式碼的時候是在vc++6.0或者是在vs上面除錯的,這種就是整合開發環境,它為我們簡化了一個程式碼的

C程式編譯連結過程

程式由原始檔編譯得到可執行檔案看起來好像是很簡單的過程,windows的IDE環境下,點一下bulid就可以生成可執行檔案,在Linux環境下,gcc編譯器也提供了很多選項可以很方便的從原始檔生成可執行檔案。事實上程式的編譯和連結是一個非常複雜的過程,IDE幫我

C/C++ 程式編譯連結的過程詳解(靜態連結

我們知道一個程式的執行需要經過編譯和連結兩個階段,其過程究竟是怎樣的呢? 程式的編譯階段分為以下幾個步驟,分別是預編譯、編譯、彙編、生成二進位制可重定向檔案(.o)。 預編譯: 首先是原始碼檔案xxx.c和相關的標頭檔案被預編譯器編譯成一個.i檔案。