Xcode 10 的胖框架脚本?

Fat Framework Script for Xcode 10?

我在我的计划中的存档的 post-action 中使用了这个脚本来制作 FAT 二进制框架。一个可以在模拟器和实际设备上运行的。

https://gist.github.com/gauravkeshre/eabb2a13ef6d673fadec84ca60b56b05

有谁知道如何将其转换为与 Xcode 10 一起使用?

使用遗留构建系统修复了错误,但我不想依赖它。

这是脚本本身:

exec > /tmp/${PROJECT_NAME}_archive.log 2>&1

UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal

if [ "true" == ${ALREADYINVOKED:-false} ]
then
echo "RECURSION: Detected, stopping"
else
export ALREADYINVOKED="true"

# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"

echo "Building for iPhoneSimulator"
xcodebuild -workspace "${WORKSPACE_PATH}" -scheme "${TARGET_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone XS' ONLY_ACTIVE_ARCH=NO ARCHS='i386 x86_64' BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" ENABLE_BITCODE=YES OTHER_CFLAGS="-fembed-bitcode" BITCODE_GENERATION_MODE=bitcode clean build

# Step 1. Copy the framework structure (from iphoneos build) to the universal folder
echo "Copying to output folder"
cp -R "${ARCHIVE_PRODUCTS_PATH}${INSTALL_PATH}/${FULL_PRODUCT_NAME}" "${UNIVERSAL_OUTPUTFOLDER}/"

# Step 2. Copy Swift modules from iphonesimulator build (if it exists) to the copied framework directory
SIMULATOR_SWIFT_MODULES_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework/Modules/${TARGET_NAME}.swiftmodule/."
if [ -d "${SIMULATOR_SWIFT_MODULES_DIR}" ]; then
cp -R "${SIMULATOR_SWIFT_MODULES_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/${TARGET_NAME}.framework/Modules/${TARGET_NAME}.swiftmodule"
fi

# Step 3. Create universal binary file using lipo and place the combined executable in the copied framework directory
echo "Combining executables"
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${EXECUTABLE_PATH}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${EXECUTABLE_PATH}" "${ARCHIVE_PRODUCTS_PATH}${INSTALL_PATH}/${EXECUTABLE_PATH}"

# Step 4. Create universal binaries for embedded frameworks
for SUB_FRAMEWORK in $( ls "${UNIVERSAL_OUTPUTFOLDER}/${TARGET_NAME}.framework/Frameworks" ); do
BINARY_NAME="${SUB_FRAMEWORK%.*}"
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${TARGET_NAME}.framework/Frameworks/${SUB_FRAMEWORK}/${BINARY_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${SUB_FRAMEWORK}/${BINARY_NAME}" "${ARCHIVE_PRODUCTS_PATH}${INSTALL_PATH}/${TARGET_NAME}.framework/Frameworks/${SUB_FRAMEWORK}/${BINARY_NAME}"
done

# Step 5. Convenience step to copy the framework to the project's directory
echo "Copying to project dir"
yes | cp -Rf "${UNIVERSAL_OUTPUTFOLDER}/${FULL_PRODUCT_NAME}" "${PROJECT_DIR}"

open "${PROJECT_DIR}"

fi

**构建成功**后输出日志中的错误:

Copying to output folder
cp: /Users/aaronbratcher/Library/Developer/Xcode/DerivedData/iOS-Messaging-SDK-dnynwhbesxdjhmedgaxbdcjgaksx/Build/Intermediates.noindex/ArchiveIntermediates/ContactAtOnceMessaging/BuildProductsPath/Release-universal/ContactAtOnceMessaging.framework/Modules/ContactAtOnceMessaging.swiftmodule: No such file or directory
cp: /Users/aaronbratcher/Library/Developer/Xcode/DerivedData/iOS-Messaging-SDK-dnynwhbesxdjhmedgaxbdcjgaksx/Build/Intermediates.noindex/ArchiveIntermediates/ContactAtOnceMessaging/BuildProductsPath/Release-iphonesimulator/ContactAtOnceMessaging.framework/Modules/ContactAtOnceMessaging.swiftmodule/.: unable to copy extended attributes to /Users/aaronbratcher/Library/Developer/Xcode/DerivedData/iOS-Messaging-SDK-dnynwhbesxdjhmedgaxbdcjgaksx/Build/Intermediates.noindex/ArchiveIntermediates/ContactAtOnceMessaging/BuildProductsPath/Release-universal/ContactAtOnceMessaging.framework/Modules/ContactAtOnceMessaging.swiftmodule: No such file or directory
cp: /Users/aaronbratcher/Library/Developer/Xcode/DerivedData/iOS-Messaging-SDK-dnynwhbesxdjhmedgaxbdcjgaksx/Build/Intermediates.noindex/ArchiveIntermediates/ContactAtOnceMessaging/BuildProductsPath/Release-universal/ContactAtOnceMessaging.framework/Modules/ContactAtOnceMessaging.swiftmodule/i386.swiftmodule: No such file or directory
cp: /Users/aaronbratcher/Library/Developer/Xcode/DerivedData/iOS-Messaging-SDK-dnynwhbesxdjhmedgaxbdcjgaksx/Build/Intermediates.noindex/ArchiveIntermediates/ContactAtOnceMessaging/BuildProductsPath/Release-universal/ContactAtOnceMessaging.framework/Modules/ContactAtOnceMessaging.swiftmodule/x86_64.swiftdoc: No such file or directory
cp: /Users/aaronbratcher/Library/Developer/Xcode/DerivedData/iOS-Messaging-SDK-dnynwhbesxdjhmedgaxbdcjgaksx/Build/Intermediates.noindex/ArchiveIntermediates/ContactAtOnceMessaging/BuildProductsPath/Release-universal/ContactAtOnceMessaging.framework/Modules/ContactAtOnceMessaging.swiftmodule/x86_64.swiftmodule: No such file or directory
cp: /Users/aaronbratcher/Library/Developer/Xcode/DerivedData/iOS-Messaging-SDK-dnynwhbesxdjhmedgaxbdcjgaksx/Build/Intermediates.noindex/ArchiveIntermediates/ContactAtOnceMessaging/BuildProductsPath/Release-universal/ContactAtOnceMessaging.framework/Modules/ContactAtOnceMessaging.swiftmodule/i386.swiftdoc: No such file or directory

然后:

fatal error: /Applications/Xcode 10.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: can't create temporary output file: /Users/aaronbratcher/Library/Developer/Xcode/DerivedData/iOS-Messaging-SDK-dnynwhbesxdjhmedgaxbdcjgaksx/Build/Intermediates.noindex/ArchiveIntermediates/ContactAtOnceMessaging/BuildProductsPath/Release-universal/ContactAtOnceMessaging.framework/ContactAtOnceMessaging.lipo (No such file or directory)
ls: /Users/aaronbratcher/Library/Developer/Xcode/DerivedData/iOS-Messaging-SDK-dnynwhbesxdjhmedgaxbdcjgaksx/Build/Intermediates.noindex/ArchiveIntermediates/ContactAtOnceMessaging/BuildProductsPath/Release-universal/ContactAtOnceMessaging.framework/Frameworks: No such file or directory
Copying to project dir
cp: /Users/aaronbratcher/Library/Developer/Xcode/DerivedData/iOS-Messaging-SDK-dnynwhbesxdjhmedgaxbdcjgaksx/Build/Intermediates.noindex/ArchiveIntermediates/ContactAtOnceMessaging/BuildProductsPath/Release-universal/ContactAtOnceMessaging.framework: No such file or directory

进入 Release-universal 文件夹后,第一个路径就会出现问题,因为没有 .framework 文件夹。相反,框架的内容在那里。

您无需更改任何内容。只需在框架目标的构建设置中将 skip_install 设置为 NO 即可。在归档之前,还要从 ${PROJECT_DIR} 中删除 .framework。

如果仍然无效,请根据 ${PROJECT_NAME}_archive.log 所说的问题修改您的问题。

编辑:也尝试在 xcode 10 中使用遗留系统进行构建。 文件 -> 工作区设置 -> 构建系统

编辑 2:由于某些原因 Xcode 10 post 操作 bash 脚本对于以前的 Xcode 版本表现不同。特别是行:

cp -R "${ARCHIVE_PRODUCTS_PATH}${INSTALL_PATH}/${FULL_PRODUCT_NAME}" "${UNIVERSAL_OUTPUTFOLDER}/"

在 Xcode 10 中,这会将 .framework 的内容复制到 ${UNIVERSAL_OUTPUTFOLDER},而在 Xcode 9.3 中,它会将整个 .framework 复制到文件夹中.

因此,如果您将此行更改为:

cp -R "${ARCHIVE_PRODUCTS_PATH}${INSTALL_PATH}/" "${UNIVERSAL_OUTPUTFOLDER}"

脚本在 Xcode 10.

中可以正常工作

我使用的脚本:

exec > /tmp/${PROJECT_NAME}_archive.log 2>&1

UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal

if [ "true" == ${ALREADYINVOKED:-false} ]
then
echo "RECURSION: Detected, stopping"
else
export ALREADYINVOKED="true"

# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
#mkdir -p "${UNIVERSAL_OUTPUTFOLDER}/${TARGET_NAME}.framework" 

echo "Building for iPhoneSimulator"
xcodebuild -workspace "${WORKSPACE_PATH}" -scheme "${TARGET_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone XS' ONLY_ACTIVE_ARCH=NO ARCHS='i386 x86_64' BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" ENABLE_BITCODE=YES OTHER_CFLAGS="-fembed-bitcode" BITCODE_GENERATION_MODE=bitcode clean build

# Step 1. Copy the framework structure (from iphoneos build) to the universal folder
echo "Copying to output folder"
cp -R "${ARCHIVE_PRODUCTS_PATH}${INSTALL_PATH}/" "${UNIVERSAL_OUTPUTFOLDER}"

# Step 2. Copy Swift modules from iphonesimulator build (if it exists) to the copied framework directory
SIMULATOR_SWIFT_MODULES_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework/Modules/${TARGET_NAME}.swiftmodule/."
if [ -d "${SIMULATOR_SWIFT_MODULES_DIR}" ]; then
cp -R "${SIMULATOR_SWIFT_MODULES_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/${TARGET_NAME}.framework/Modules/${TARGET_NAME}.swiftmodule"
fi

# Step 3. Create universal binary file using lipo and place the combined executable in the copied framework directory
echo "Combining executables"
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${EXECUTABLE_PATH}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${EXECUTABLE_PATH}" "${ARCHIVE_PRODUCTS_PATH}${INSTALL_PATH}/${EXECUTABLE_PATH}"

echo "Combining executables end"

# Step 4. Create universal binaries for embedded frameworks
for SUB_FRAMEWORK in $( ls "${UNIVERSAL_OUTPUTFOLDER}/${TARGET_NAME}.framework/Frameworks" ); do
BINARY_NAME="${SUB_FRAMEWORK%.*}"
echo "${ARCHIVE_PRODUCTS_PATH}${INSTALL_PATH}/${TARGET_NAME}.framework/Frameworks/${SUB_FRAMEWORK}/${BINARY_NAME}"
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${TARGET_NAME}.framework/Frameworks/${SUB_FRAMEWORK}/${BINARY_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${SUB_FRAMEWORK}/${BINARY_NAME}" "${ARCHIVE_PRODUCTS_PATH}${INSTALL_PATH}/${TARGET_NAME}.framework/Frameworks/${SUB_FRAMEWORK}/${BINARY_NAME}"
done

# Step 5. Convenience step to copy the framework to the project's directory
echo "Copying to project dir"
yes | cp -Rf "${UNIVERSAL_OUTPUTFOLDER}/${FULL_PRODUCT_NAME}" "${PROJECT_DIR}"

open "${PROJECT_DIR}"

fi