반응형
단일 프레임워크를 Universal Framework로 만들때 쓰는 Run Script는 아래를 사용하고 있고,
#!/bin/sh
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
# Step 1. Build Device and Simulator versions. This also include the full bitcode generation of framework
xcodebuild BITCODE_GENERATION_MODE=bitcode OTHER_CFLAGS="-fembed-bitcode" -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild BITCODE_GENERATION_MODE=bitcode OTHER_CFLAGS="-fembed-bitcode" -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
# Step 2. Copy the framework structure (from iphoneos build) to the universal folder
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"
# Step 3. Copy Swift modules (from iphonesimulator build) to the copied framework directory
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/." "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"
# Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"
# Step 5. Convenience step to copy the framework to the project's directory
cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"
# Step 6. Convenience step to open the project's directory in Finder
open "${PROJECT_DIR}"
Cocoapod을 포함한 Workspace를 Universal Framework로 만들때에는 아래를 사용하고 있습니다.
(Workspace를 Universal Framework를 만들땐 Build가 아닌 Archive로 하고 있습니다.)
출처: https://github.com/gurhub/universal-framework
#!/bin/sh
######################
# Globals
######################
# Avilable Platforms/Architectures
# macosx | iphoneos | iphonesimulator | appletvos | appletvsimulator | watchos | watchsimulator
DEVICE_ARCH="iphoneos"
DEVICE_SIM_ARCH="iphonesimulator"
FRAMEWORK_NAME="${PROJECT_NAME}"
DEVICE_LIBRARY_PATH=${BUILD_DIR}/${CONFIGURATION}-${DEVICE_ARCH}/${FRAMEWORK_NAME}.framework
SIMULATOR_LIBRARY_PATH=${BUILD_DIR}/${CONFIGURATION}-${DEVICE_SIM_ARCH}/${FRAMEWORK_NAME}.framework
UNIVERSAL_LIBRARY_DIR=${BUILD_DIR}/${CONFIGURATION}-Universal
SUCCESS=true
EXIT_MESSAGE=$?
ROW_STRING="\n##################################################################\n"
echoPaths()
{
echo "${ROW_STRING}"
echo "DEVICE_LIBRARY_PATH: ${DEVICE_LIBRARY_PATH}"
echo "SIMULATOR_LIBRARY_PATH: ${SIMULATOR_LIBRARY_PATH}"
echo "UNIVERSAL_LIBRARY_DIR: ${UNIVERSAL_LIBRARY_DIR}"
echo "${ROW_STRING}"
}
checkSuccess()
{
if [[ -z $EXIT_MESSAGE ]]; then
SUCCESS=false
exitWithMessage
exit 1
fi
}
exitWithMessage()
{
echo "${ROW_STRING}"
if [ "$SUCCESS" = true ] ; then
echo "\n\n\n 🏁 Completed with Success! 🙂"
else
echo "\n\n\n 😱 Completed with Errors! Please check line above for details:"
echo "${EXIT_MESSAGE}"
fi
open /tmp/${FRAMEWORK_NAME}_archive.log
echo "\n 🔍 For more details you can always check the /tmp/${FRAMEWORK_NAME}_archive.log file. 📝 \n\n\n"
echo "${ROW_STRING}"
}
######################
######################
######################
######################
# Starting the logging
######################
exec > /tmp/${FRAMEWORK_NAME}_archive.log 2>&1
echo "\n ⏱ Starting the Universal Framework work... \n\n\n"
######################
# Echo the PATHS
######################
echoPaths
######################
# Make sure the output directory exists
######################
mkdir -p "${UNIVERSAL_LIBRARY_DIR}"
######################
# Step 1: Build Frameworks
######################
echo "${ROW_STRING}"
echo "\n\n\n 🚀 Step 1-1: Building for ${DEVICE_SIM_ARCH}"
echo "${ROW_STRING}"
EXIT_MESSAGE="$(xcodebuild BITCODE_GENERATION_MODE=bitcode OTHER_CFLAGS="-fembed-bitcode" -workspace "${WORKSPACE_PATH}" -scheme "${TARGET_NAME}" -configuration ${CONFIGURATION} -sdk ${DEVICE_SIM_ARCH} ONLY_DEVICE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" -UseModernBuildSystem=NO clean build)"
checkSuccess
echo "${ROW_STRING}"
echo "\n\n\n 🚀 Step 1-2: Building for ${DEVICE_ARCH} \n\n\n"
EXIT_MESSAGE="$(xcodebuild BITCODE_GENERATION_MODE=bitcode OTHER_CFLAGS="-fembed-bitcode" -workspace "${WORKSPACE_PATH}" -scheme "${TARGET_NAME}" ONLY_DEVICE_ARCH=NO -configuration ${CONFIGURATION} -sdk ${DEVICE_ARCH} BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" -UseModernBuildSystem=NO clean build)"
checkSuccess
######################
# Step 2. Copy the frameworks
######################
echo "${ROW_STRING}"
echo "\n\n\n 📦 Step 2: Copy the framework structure for ${DEVICE_ARCH}"
echo "${ROW_STRING}"
cp -R "${DEVICE_LIBRARY_PATH}" "${UNIVERSAL_LIBRARY_DIR}/"
######################
# Step 3. Create the universal binary
######################
echo "${ROW_STRING}"
echo "\n\n\n 🛠 Step 3: The LIPO Step"
echo "${ROW_STRING}"
lipo -create "${SIMULATOR_LIBRARY_PATH}/${FRAMEWORK_NAME}" "${DEVICE_LIBRARY_PATH}/${FRAMEWORK_NAME}" -output "${UNIVERSAL_LIBRARY_DIR}/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}"
######################
# Step 4. Copy the Swiftmodules.
# This step is necessary only if your project is Swift. For the Swift framework, Swiftmodule needs to be copied in the universal framework.
######################
echo "${ROW_STRING}"
echo "\n\n\n 📦 Step 4: Copy the Swiftmodules"
echo "${ROW_STRING}"
if [ -d "${SIMULATOR_LIBRARY_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule/" ]; then
cp -f ${SIMULATOR_LIBRARY_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule/* "${UNIVERSAL_LIBRARY_DIR}/${FRAMEWORK_NAME}.framework/Modules/${FRAMEWORK_NAME}.swiftmodule/" | echo
else
echo "ℹ️ Couldn't any Swift module file for SIMULATOR!"
fi
if [ -d "${DEVICE_LIBRARY_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule/" ]; then
cp -f ${DEVICE_LIBRARY_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule/* "${UNIVERSAL_LIBRARY_DIR}/${FRAMEWORK_NAME}.framework/Modules/${FRAMEWORK_NAME}.swiftmodule/" | echo
else
echo "ℹ️ Couldn't any Swift module file for DEVICE!"
fi
######################
# Step 5. Remove the existing copy of the Universal framework and copy the framework to the project's directory
######################
echo "${ROW_STRING}"
echo "\n\n\n 🚛 Step 5 Copying in the project directory"
echo "${ROW_STRING}"
rm -rf "${PROJECT_DIR}/${FRAMEWORK_NAME}.framework"
yes | cp -Rf "${UNIVERSAL_LIBRARY_DIR}/${FRAMEWORK_NAME}.framework" "${PROJECT_DIR}"
######################
# Step 6. Open the project's directory
######################
echo "${ROW_STRING}"
open "${PROJECT_DIR}"
echo "${ROW_STRING}"
######################
# Step 7. Open the log file on Console application
######################
exitWithMessage
오류 케이스 1: Universal Framework로 만들고 나서 추가한 메인 프로젝트에서 bitcode 관련 에러가 나는 경우
Universal Framework를 만들기 위해 생성한 Aggregate 타겟에서 Build Settings 에서 Apple Clang - Custom Compiler Flags 항목의
Other C Flags 값에 -fembed-bitcode를 추가한다.
오류 케이스 2: Universal Framework로 만들고 나서 추가한 메인 프로젝트에서 아카이브시 Code Signing 에러가 나는 경우
Universal Framework 를 사용한 메인 프로젝트의 타겟에 다음과 같은 Run Script를 추가한다.
# Type a script or drag a script file from your workspace to insert its path.
# skip if we run in debug
if [ "$CONFIGURATION" == "Debug" ]; then
echo "Skip frameworks cleaning in debug version"
exit 0
fi
APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
# This script loops through the frameworks embedded in the application and
# removes unused architectures.
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"
EXTRACTED_ARCHS=()
for ARCH in $ARCHS
do
echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
done
echo "Merging extracted architectures: ${ARCHS}"
lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
rm "${EXTRACTED_ARCHS[@]}"
echo "Replacing original executable with thinned version"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"
done
해당 Run Script는 불필요한 signing를 제거하여 아키이브시 오류가 나지 않도록 해준다.
반응형
반응형
'Programer > iOS' 카테고리의 다른 글
[Xcode] AppStore Uplaod할 때, ERROR ITMS-90035 해결방법 (2) | 2020.05.14 |
---|---|
[iOS] Framework 안에서 Objective-C / Swift 같이 쓰기 (0) | 2020.02.07 |
[iOS] Framework 사용시 주의 할 점 (Dynamic / Static 설정) (2) | 2019.12.19 |
[Swift] ObjectMapper 에서 toJSON사용시 Nil 파라미터 추가 하기 (0) | 2019.12.10 |
[Let's Swift] 렛츠 스위프트 판교 후기 (0) | 2019.12.07 |