iOS Xcode打包framework

A訫飛Flyme發表於2017-12-20

之前Xcode準備建立模組就不說是,直接上個圖

fm1.png

fm4.png

fm5.png

fm2.png

fm3.png

貼出要加入的shell指令碼,方便實用。

# Sets the target folders and the final framework product.
# 如果工程名稱和Framework的Target名稱不一樣的話,要自定義FMKNAME
# 例如: FMK_NAME = "MyFramework"
FMK_NAME="SLFMWK"
# 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}"
複製程式碼

打包 .a的合併靜態庫

if [ "${ACTION}" = "build" ]
then



#要build的target名
target_Name=${PROJECT_NAME}
echo "target_Name=${target_Name}"


#build之後的資料夾路徑
build_DIR=${SRCROOT}/build
echo "build_DIR=${build_DIR}"

#真機build生成的標頭檔案的資料夾路徑
DEVICE_DIR_INCLUDE=${build_DIR}/Release-iphoneos/include/${PROJECT_NAME}
echo "DEVICE_DIR_INCLUDE=${DEVICE_DIR_INCLUDE}"

#真機build生成的.a檔案路徑
DEVICE_DIR_A=${build_DIR}/Release-iphoneos/lib${PROJECT_NAME}.a
echo "DEVICE_DIR_A=${DEVICE_DIR_A}"

#模擬器build生成的.a檔案路徑
SIMULATOR_DIR_A=${build_DIR}/Release-iphonesimulator/lib${PROJECT_NAME}.a
echo "SIMULATOR_DIR_A=${SIMULATOR_DIR_A}"


#目標資料夾路徑
INSTALL_DIR=${SRCROOT}/Products/${PROJECT_NAME}
echo "INSTALL_DIR=${INSTALL_DIR}"

#目標標頭檔案資料夾路徑
INSTALL_DIR_Headers=${SRCROOT}/Products/${PROJECT_NAME}/Headers
echo "INSTALL_DIR_Headers=${INSTALL_DIR_Headers}"

#目標.a路徑
INSTALL_DIR_A=${SRCROOT}/Products/${PROJECT_NAME}/lib${PROJECT_NAME}.a
echo "INSTALL_DIR_A=${INSTALL_DIR_A}"


#判斷build資料夾是否存在,存在則刪除
if [ -d "${build_DIR}" ]
then
rm -rf "${build_DIR}"
fi

#判斷目標資料夾是否存在,存在則刪除該資料夾
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi
#建立目標資料夾
mkdir -p "${INSTALL_DIR}"


#build之前clean一下
xcodebuild -target ${target_Name} clean

#模擬器build
xcodebuild -target ${target_Name} -configuration Release -sdk iphonesimulator

#真機build
xcodebuild -target ${target_Name} -configuration Release -sdk iphoneos

#複製標頭檔案到目標資料夾
cp -R "${DEVICE_DIR_INCLUDE}" "${INSTALL_DIR_Headers}"

#合成模擬器和真機.a包
lipo -create "${DEVICE_DIR_A}" "${SIMULATOR_DIR_A}" -output "${INSTALL_DIR_A}"

#開啟目標資料夾
open "${INSTALL_DIR}"


fi
複製程式碼

實用framework時候如果有 類別什麼的,需要在Xcode的Build Settings下Other Linker Flags裡面加入-ObjC標誌。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後面必須要指定具體的檔案。 (還有問題的話可能加入第三方庫路徑問題)

github地址

結束

相關文章