在iOS開發(fā)中小染,有時候為了項目模塊間的相互獨立性次兆,降低模塊間的耦合援岩,通常將底層相對穩(wěn)定的模塊抽取出來歼狼,形成SDK,以靜態(tài)包或者靜態(tài)庫的形式引入項目享怀。這中間免不了編譯打包靜態(tài)包/庫羽峰,通常的做法是模擬器和真機分別編譯,然后再將兩個靜態(tài)包或者庫lipo
合并成一個。這樣的工作做多了梅屉,難免覺得麻煩值纱,想省事兒,整一腳本變得自然而然了坯汤。
喜歡我的可以關注收藏我的個人博客:RobberJJ
1. 創(chuàng)建一個靜態(tài)包/庫工程(已有請?zhí)^這一步)
創(chuàng)建如下圖:
在Trargets下面虐唠,點擊左下角的“+”,選擇添加一個新的Target, 然后選擇“Aggregate”選項惰聂,新建一個集合類target疆偿,如下圖所示:
2. 給集合類添加依賴
在Targets下面選中我們新建的集合類,然后Build Phases --> Target Dependencies 下面添加我們需要編譯的靜態(tài)庫,如下圖所示:
3. 添加腳本
在Targets下面選中我們新建的集合類,然后在Build Phases下搓幌,點擊左上角的“+”杆故,選擇"New Run Script Phase"選項,如下圖:
然后設置我們運行的腳本的所在位置,如下圖所示:
注意:
../scripts/build-framework.sh 表示腳本的位置在當前工程的上一個目錄下地scripts文件夾下. 當然"../"也可以用"${SRCROOT}/../"來代替.
腳本位置可根據(jù)實際情況自行設置。
4. 選擇我們創(chuàng)建的集合類的target溉愁,編譯
在編譯時反番,你可能會遇到下面的錯誤:
Permission denied.
這是因為shell腳本,還沒有添加可執(zhí)行的權限叉钥。
解決辦法:在終端上, cd 進入到腳本所在的文件夾篙贸; 然后使用 chmod +x ./yourShellName.sh 命令投队, 成功之后,就可以正常的運行Xcode工程了爵川。
5. 指定target
一般來說我們編譯的target名稱敷鸦,跟我們的project工程的名稱是一樣的,但是寝贡,如果我們修改了我們的target名稱扒披,需要在我們制定腳本的位置后面跟上我們需要編譯的target名稱,既:腳本位置+空格+target名稱圃泡。如下圖:
喜歡我的可以關注收藏我的個人博客:RobberJJ
6. shell腳本源碼
編譯library的腳本
#!/bin/sh
#要build的target名
target_Name=${PROJECT_NAME}
if [[ $1 ]]
then
target_Name=$1
fi
UNIVERSAL_OUTPUT_FOLDER="${SRCROOT}/${PROJECT_NAME}_Products"
# 創(chuàng)建輸出目錄碟案,并刪除之前的文件
rm -rf "${UNIVERSAL_OUTPUT_FOLDER}"
mkdir -p "${UNIVERSAL_OUTPUT_FOLDER}"
# 分別編譯真機和模擬器版本
xcodebuild -target "${target_Name}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target "${target_Name}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
#復制頭文件到目標文件夾
HEADER_FOLDER="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/include/${target_Name}"
if [[ -d "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/usr/local/include" ]]
then
HEADER_FOLDER="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/usr/local/include"
fi
cp -R "${HEADER_FOLDER}" "${UNIVERSAL_OUTPUT_FOLDER}"
#合成模擬器和真機.a包
lipo -create "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/lib${target_Name}.a" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/lib${target_Name}.a" -output "${UNIVERSAL_OUTPUT_FOLDER}/lib${target_Name}.a"
# 判斷build文件夾是否存在,存在則刪除
if [ -d "${SRCROOT}/build" ]
then
rm -rf "${SRCROOT}/build"
fi
#打開目標文件夾
open "${UNIVERSAL_OUTPUT_FOLDER}"
編譯framework的shell腳本
#!/bin/sh
#要build的target名
TARGET_NAME=${PROJECT_NAME}
if [[ $1 ]]
then
TARGET_NAME=$1
fi
UNIVERSAL_OUTPUT_FOLDER="${SRCROOT}/${PROJECT_NAME}_Products/"
#創(chuàng)建輸出目錄颇蜡,并刪除之前的framework文件
mkdir -p "${UNIVERSAL_OUTPUT_FOLDER}"
rm -rf "${UNIVERSAL_OUTPUT_FOLDER}/${TARGET_NAME}.framework"
#分別編譯模擬器和真機的Framework
xcodebuild -target "${TARGET_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target "${TARGET_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
#拷貝framework到univer目錄
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework" "${UNIVERSAL_OUTPUT_FOLDER}"
#合并framework价说,輸出最終的framework到build目錄
lipo -create -output "${UNIVERSAL_OUTPUT_FOLDER}/${TARGET_NAME}.framework/${TARGET_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework/${TARGET_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${TARGET_NAME}.framework/${TARGET_NAME}"
#刪除編譯之后生成的無關的配置文件
dir_path="${UNIVERSAL_OUTPUT_FOLDER}/${TARGET_NAME}.framework/"
for file in ls $dir_path
do
if [[ ${file} =~ ".xcconfig" ]]
then
rm -f "${dir_path}/${file}"
fi
done
#判斷build文件夾是否存在,存在則刪除
if [ -d "${SRCROOT}/build" ]
then
rm -rf "${SRCROOT}/build"
fi
rm -rf "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator" "${BUILD_DIR}/${CONFIGURATION}-iphoneos"
#打開合并后的文件夾
open "${UNIVERSAL_OUTPUT_FOLDER}"