iOS 制作靜態(tài)庫

制作靜態(tài)庫

  • 動態(tài)庫:.dylib .framework
  • 靜態(tài)庫:.a .framework

兩者區(qū)別*:動態(tài)庫時在程序運行時動態(tài)鏈接的,且可以被多個程序鏈接,相當(dāng)于以動態(tài)庫為中心,系統(tǒng)只會加載動態(tài)庫到內(nèi)存一次,這樣動態(tài)庫就始終只占一份內(nèi)存,而靜態(tài)庫是提前把需要編譯的實現(xiàn)文件編譯為二進制文件,每個程序都需要復(fù)制一份,這是在使用靜態(tài)庫就決定了的特性,我們需要把靜態(tài)庫復(fù)制到工程文件內(nèi),供我們程序使用,而在制作時靜態(tài)庫時,我們可以選擇暴露哪些文件給使用者,當(dāng)然大部分都只需暴露頭文件,我們當(dāng)然也可以暴露實現(xiàn)文件,供我們參考學(xué)習(xí),了解其中原理,眾使我們修改了該文件的內(nèi)容也沒關(guān)系,因為該文件已經(jīng)在制作靜態(tài)庫時已經(jīng)編譯成二進制文件,我們使用時不會再次編譯該文件,資源文件如圖片等也是可以我們替換,因為編譯時只是簡單的COPY,所以我們可以替換SVProgressHUB里的error或success成我們個性化的圖片。蘋果官方不允許我們App包含動態(tài)庫。

.a.framework的區(qū)別:
制作.a 都需要我們手動在Header Search Paths加頭文件搜索路徑
制作 .framework不需要

制作.framework靜態(tài)庫

我們先說.framework 的制作過程,我們新建項目選擇iOS的framwork / library ,建好后默認(rèn)有一個頭文件,這不是我們需要的,直接刪掉,這里我們可以任意建文件夾和文件,把我們需要的功能庫搭建好后,我們在Build phase > Headers > public 內(nèi)添加我們需要暴露的文件,這樣我們就建好了,然后我們分別選著模擬器 和 Generic iOS Device 來構(gòu)建我們的product ,只有當(dāng)我們構(gòu)建完Generic iOS Device才能看到product內(nèi)的target由紅色變?yōu)楹谏?,這說明文件存在,構(gòu)建完畢,然后我們右鍵 show in finder 找到編譯好的文件,當(dāng)然,這個文件只包含armv7 和arm64 架構(gòu)的。我們還需要在Mach-type修改類型為Static Library,當(dāng)然我們也可以制作動態(tài)庫,只是不能發(fā)布。如果你制作動態(tài)庫就需要在Embedded Binaries 內(nèi)添加庫。

對于這幾種CPU架構(gòu)分類:

真機:

3gs ~ 4s :armv7

5 ~5c :armv7s

5s~ 6plus:arm64

模擬器:

4s~5 : i386

5s~6plus : x86_64

所以我們需要合并這幾種包,并且都是debug包,我們一般發(fā)布給別人Release包,這需要我們Edit Scheme 選擇Run > info >build configuration 為Release。Release包會比debug包要小一點,因為編譯時作了代碼優(yōu)化,運行效率會高一點,但不會明顯提高。

為了保證都能運行,我們還需要合并包,這里的包是.framework 文件里的同名的無擴展名的二進制文件,使用下面命令合并,更多使用方法( man lipo

lipo -create test1 test2 -output test3

然后替換之前任意一個同名的二進制文件,這里多次強調(diào)同名,因為系統(tǒng)就是根據(jù)根據(jù)靜態(tài)庫名在靜態(tài)庫內(nèi)尋找二進制文件,不然會報找不到該文件的錯誤。

這樣我們直接把替換二進制文件后的.framework文件拖進我們其它工程直接使用。

當(dāng)然如果我們還需要在靜態(tài)庫內(nèi)使用資源文件,我們使用Bundle,在該項目內(nèi)Add Target ,選擇OSX 內(nèi)的Bundle,我們需要刪除一系列,修改sdk,修改product name等等。

制作.a靜態(tài)庫

類似制作.framework靜態(tài)庫,我們新建項目XHQ_StaticFramework,選擇Cocoa Touch Static Library
這時可以看到兩個文件夾:XHQ_StaticFrameworkProduct , Xcode 為我們自動建好的XHQ_StaticFramework(.h/.m)文件,一般我們只需要頭文件,頭文件寫下我們所有需要公開的頭文件,其它全部刪掉,以便客戶使用時只需引入這個頭文件。Product存放我們生成的二進制文件。這里我們引入<UIKit/UiKit.h>框架,(網(wǎng)上多個版本都提到需要在Build Phrases >Link Binary With Libraries 內(nèi)添加UIKit.framework,但是作者沒有添加也能正常使用,如果你知道原因請告訴我,謝謝?。?/p>

我們在XHQ_StaticFramework 文件夾下建好我們自己的代碼庫后,把需要公開的頭文件加到Build Phases >Headers ,如果你沒有這個目錄,你需要手動Editor > Add Build Phases> Add Headers Build Phases 來添加。(提示:如果無法選擇,你需要點擊Build Phases 空白處后再重復(fù)上面的步驟。)

點開 Headers 默認(rèn)是有三個文件目錄: public&&private&&project, 其中pulic和private都是放對外公開的文件,兩者區(qū)別就是存儲的路徑可能不一樣,我們可以在Packaging> Private/Public Headers Folder Path設(shè)置路徑。這里我們設(shè)置為include/$(PROJECT_NAME),project 存放我們私有的文件。

然后我們需要在Build Settings設(shè)置一些值:

Dead Code Stripping > NO(去掉不會執(zhí)行到的代碼)

Strip Style > Debugging Symbols

Strip Debug Symbol During Copy > NO(去掉Debug相關(guān)符號)

Strip Linked Product > NO

這樣做是為了后期產(chǎn)生bug時,我們能通過符號文件定位到我們需要的類的信息, 但是如果是iOS 或者 OSX則配置完全相反。相關(guān)文章

我們編譯成功后就可以正常使用。使用時我們有兩種方式

一種是在其它項目中拖進該項目,在新項目中添加依賴 Build Phases > Target Dependencies添加.a靜態(tài)庫,然后就是link library 內(nèi)添加.a靜態(tài)庫;

上面的方式適合我們自己內(nèi)部使用,好處就是可以動態(tài)的修改靜態(tài)庫的文件,Xcode會根據(jù)是否需要重新編譯來生成靜態(tài)文件,而其實我們可以是直接使用生成的.a靜態(tài)庫和包涵頭文件的include文件夾,只不過我們每次都需要配置Search Headers Paths,這種方式適合給外部使用。

使用腳本生成集成包

相信上面的這些分別生成支持不同架構(gòu)的包已經(jīng)讓你精疲力竭,我們有更加方便的方法制作通用的包,那就是使用腳本來構(gòu)建支持多個架構(gòu)的包.首先我們在前面制作framework的基礎(chǔ)上添加
Aggragate target,然后在Build Phases 內(nèi)添加 Run Script
把下面代碼添加進去。直接運行,然后生成的包目錄會自動打開。

FMK_NAME=${PROJECT_NAME}

# Install dir will be the final output to the framework.

# The following line create it in the root folder of the current project.

INSTALL_DIR=${SRCROOT}/Products/${FMK_NAME}.framework

# Working dir will be deleted after the framework creation.

WRK_DIR=build

DEVICE_DIR=${WRK_DIR}/Release-iphoneos/${FMK_NAME}.framework

SIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator/${FMK_NAME}.framework

# -configuration ${CONFIGURATION}

# Clean and Building both architectures.

xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphoneos clean build

xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphonesimulator clean build

# Cleaning the oldest.

if [ -d "${INSTALL_DIR}" ];then

rm -rf "${INSTALL_DIR}"

fi

mkdir -p "${INSTALL_DIR}"

cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/"

# Uses the Lipo Tool to merge both binary files (i386 + armv6/armv7) into one Universal final product.

lipo -create "${DEVICE_DIR}/${FMK_NAME}" "${SIMULATOR_DIR}/${FMK_NAME}" -output "${INSTALL_DIR}/${FMK_NAME}"

rm -r "${WRK_DIR}"

open "${INSTALL_DIR}"

參考文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容