制作多架构iOS和Mac OS框架

时间:2014-10-24 13:05:17

标签: xcode frameworks ios8

我在使用新的Xcode 6动态框架目标开发框架时遇到了问题。

基本上,我需要与旧方法(Explained very well in this tutorial)相同的结果。

我试过this,但问题是该框架只生成了几个ARM二进制文件。我需要在那里拥有i386 / x86_64二进制文件,因此它将是一个完整的框架。

我确定我忽视了一些事情。有没有人对这个无能为力的人有线索?

1 个答案:

答案 0 :(得分:2)

是的,看起来这对大多数人来说并不是很有趣。

啊,好吧。我确实得到了更好的Wenderlich脚本版本,我将在这里发布。

这有一个显着优势,即成为一流的公民"框架;而不是由新目标生成的仅限iOS8的动态版本。

#! /bin/sh

# This was cribbed from here: http://www.raywenderlich.com/65964/create-a-framework-for-ios

# This script will build a multiplatform framework for the project referenced from the $FRAMEWORK_PRODUCT_NAME environment variable.
# This variable needs to be set as a user-defined value in the build settings of this target (an aggregate target that just runs this script).
# The project must have a static lib target, with the exact name defined by $FRAMEWORK_PRODUCT_NAME, and the output from that target needs to be
# a static lib that is "lib${FRAMEWORK_PRODUCT_NAME}.a". The static lib target needs to have a "Debug" and a "Release" configuration, with the
# debug configuration embedding symbols/profiling information (as opposed to a separate DSYM file).
# No stripping should be done for non-debug in either configuration (but it is advised to strip debug symbols in "Release").
# The aggregate target should also define the $DELIVERABLE_DIRECTORY environment variable. This is a relative POSIX path from the ${BUILD_DIR}
# location, to a place that the user wants to deliver the framework. The script will create a "Framework" directory there, with a "Debug" and
# a "Release" directory; each containing a copy of the framework.
# The static lib target needs to create a "Headers" directory with exported headers, and a "Resources" directory (even if it is empty).

set -e

# If we're already inside this script then die
if [ -n "$MULTIPLATFORM_BUILD_IN_PROGRESS" ]; then
    exit 0
fi
export MULTIPLATFORM_BUILD_IN_PROGRESS=1

# This function actually runs the static lib target build, in the configuration requested.
# INPUT: SDK, configuration (either "Debug" or "Release"), target name

function build_static_library
{
    xcrun xcodebuild -project "${PROJECT_FILE_PATH}" \
    -sdk "${1}" \
    -configuration "${2}" \
    -target "${3}" \
    ONLY_ACTIVE_ARCH=NO \
    BUILD_DIR="${BUILD_DIR}" \
    OBJROOT="${OBJROOT}" \
    BUILD_ROOT="${BUILD_ROOT}" \
    SYMROOT="${SYMROOT}" $ACTION
}

# This function will build the iphoneos and iphonesimulator versions of the framework, and will
# use lipo to merge them together into a "fat" binary that contains x86 and ARM code.
# It will also copy the headers and the resources for the framework, so the static lib target needs to create
# a "Headers" directory with exported headers, and a "Resources" directory (even if it is empty).
# INPUT: configuration (example: "Release" or "Debug").

function buildTwoArchitectures
{
    # 1 - Extract the platform (iphoneos/iphonesimulator) from the SDK name
    if [[ "$SDK_NAME" =~ ([A-Za-z]+) ]]; then
        SDK_PLATFORM=${BASH_REMATCH[1]}
    else
        echo "Could not find platform name from SDK_NAME: $SDK_NAME"
        exit 1
    fi

    # 2 - Extract the version from the SDK
    if [[ "$SDK_NAME" =~ ([0-9]+.*$) ]]; then
        SDK_VERSION=${BASH_REMATCH[1]}
    else
        echo "Could not find sdk version from SDK_NAME: $SDK_NAME"
        exit 1
    fi

    if [ "$SDK_PLATFORM" == "iphoneos" ]; then
        OTHER_PLATFORM="iphonesimulator"
    else
        OTHER_PLATFORM="iphoneos"
    fi

    # Build the other platform.
    build_static_library "${SDK_PLATFORM}${SDK_VERSION}" "${1}" "${FRAMEWORK_PRODUCT_NAME}"
    build_static_library "${OTHER_PLATFORM}${SDK_VERSION}" "${1}" "${FRAMEWORK_PRODUCT_NAME}"

    BUILT_PRODUCTS_DIR="${BUILD_DIR}/${1}-${SDK_PLATFORM}"
    OTHER_BUILT_PRODUCTS_DIR="${BUILD_DIR}/${1}-${OTHER_PLATFORM}"

    # Create the path to the real Headers dir
    mkdir -p "${BUILD_DIR}/${FRAMEWORK_PRODUCT_NAME}.framework/Versions/A/Headers"
    mkdir -p "${BUILD_DIR}/${FRAMEWORK_PRODUCT_NAME}.framework/Versions/A/Resources"

    # Create the required symlinks
    ln -sfh A "${BUILD_DIR}/${FRAMEWORK_PRODUCT_NAME}.framework/Versions/Current"
    ln -sfh Versions/Current/Headers "${BUILD_DIR}/${FRAMEWORK_PRODUCT_NAME}.framework/Headers"
    ln -sfh Versions/Current/Resources "${BUILD_DIR}/${FRAMEWORK_PRODUCT_NAME}.framework/Resources"
    ln -sfh "Versions/Current/${FRAMEWORK_PRODUCT_NAME}" "${BUILD_DIR}/${FRAMEWORK_PRODUCT_NAME}.framework/${FRAMEWORK_PRODUCT_NAME}"

    # Copy the public headers into the framework
    cp -a "${BUILT_PRODUCTS_DIR}/Headers/" "${BUILD_DIR}/${FRAMEWORK_PRODUCT_NAME}.framework/Versions/A/Headers"

    # Copy the resources into the framework.
    cp -a "${BUILT_PRODUCTS_DIR}/Resources/" "${BUILD_DIR}/${FRAMEWORK_PRODUCT_NAME}.framework/Versions/A/Resources"

    # Join the 2 static libs into 1 and push into the .framework
    lipo    -create "${BUILT_PRODUCTS_DIR}/libNKPTPF.a" "${OTHER_BUILT_PRODUCTS_DIR}/libNKPTPF.a" \
            -output "${BUILD_DIR}/${FRAMEWORK_PRODUCT_NAME}.framework/Versions/A/${FRAMEWORK_PRODUCT_NAME}"

    # Move the resultant framework to our delivery location.
    rm -drf "${BUILD_DIR}/${DELIVERABLE_DIRECTORY}/Framework/${1}/"
    mkdir -p "${BUILD_DIR}/${DELIVERABLE_DIRECTORY}/Framework/${1}/"
    mv -f "${BUILD_DIR}/${FRAMEWORK_PRODUCT_NAME}.framework" "${BUILD_DIR}/${DELIVERABLE_DIRECTORY}/Framework/${1}/"
}

# Make it so, numbah one...
buildTwoArchitectures "Debug"
buildTwoArchitectures "Release"