制作多架构iOS和Mac OS框架 [英] Making Multi-Architecture iOS and Mac OS Frameworks

查看:146
本文介绍了制作多架构iOS和Mac OS框架的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



基本上,我需要与旧方法相同的结果(在本教程中解释得非常好)。



我试过这个,但问题是只有框架生成几个ARM二进制文件。我还需要有i386 / x86_64二进制文件,所以它将是一个完整的框架。



我确定我忽略了一些东西。有没有人对这个无能为力的人有线索?

解决方案

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

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



这具有作为头等公民框架的显着优势;不是由新目标生成的仅限iOS8的动态版本。

 #! / bin / sh 

#这是从这里得到的:http://www.raywenderlich.com/65964/create-a-framework-for-ios

#这个脚本将为$ FRAMEWORK_PRODUCT_NAME环境变量引用的项目构建多平台框架。
#此变量需要在此目标的构建设置中设置为用户定义的值(仅运行此脚本的聚合目标)。
#项目必须有一个静态lib目标,其名称由$ FRAMEWORK_PRODUCT_NAME定义,并且该目标的输出必须是
#静态库,即lib $ {FRAMEWORK_PRODUCT_NAME} .a 。静态lib目标需要具有Debug和Release配置,其中
#debug配置嵌入符号/分析信息(而不是单独的DSYM文件)。
#在任一配置中都不应对非调试进行剥离(但建议在Release中剥离调试符号)。
#聚合目标还应定义$ DELIVERABLE_DIRECTORY环境变量。这是从$ {BUILD_DIR}
#位置到用户想要传递框架的位置的相对POSIX路径。该脚本将在那里创建一个Framework目录,其中包含Debug和
#Release目录;每个都包含框架的副本。
#静态lib目标需要创建一个带有导出头的Headers目录和一个Resources目录(即使它是空的)。

set -e

#如果我们已经在这个脚本中,那么如果[-n$ MULTIPLATFORM_BUILD_IN_PROGRESS]则死掉
;然后
退出0
fi
导出MULTIPLATFORM_BUILD_IN_PROGRESS = 1

#此函数实际上在请求的配置中运行静态lib目标构建。
#INPUT:SDK,配置(Debug或Release),目标名称

函数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
}

#此函数将构建框架的iphoneos和iphonesimulator版本,并且
#使用lipo合并它们一起成为包含x86和ARM代码的胖二进制文件。
#它还将复制框架的头文件和资源,因此静态lib目标需要创建
#带有导出头的Headers目录和一个Resources目录(即使它是空的)。
#INPUT:配置(例如:Release或Debug)。

function buildTwoArchitectures
{
#1 - 如果[[$ SDK_NAME=〜([A],从SDK名称
中提取平台(iphoneos / iphonesimulator) -Za-z] +)]];然后
SDK_PLATFORM = $ {BASH_REMATCH [1]}
其他
echo找不到SDK_NAME的平台名称:$ SDK_NAME
退出1
fi

#2 - 如果[[$ SDK_NAME=〜([0-9] +。* $)]],则从SDK
中提取版本。然后
SDK_VERSION = $ {BASH_REMATCH [1]}
其他
echo找不到SDK_NAME的sdk版本:$ SDK_NAME
退出1
fi

if [$ SDK_PLATFORM==iphoneos];那么
OTHER_PLATFORM =iphonesimulator
else
OTHER_PLATFORM =iphoneos
fi

#构建另一个平台。
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 }

#创建真实标题目录的路径
mkdir -p$ {BUILD_DIR} / $ {FRAMEWORK_PRODUCT_NAME} .framework / Versions / A / Headers
mkdir -p$ {BUILD_DIR} / $ {FRAMEWORK_PRODUCT_NAME} .framework / Versions / A / Resources

#创建所需的符号链接
ln -sfh$ {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 -sfhVersions / Current / $ {FRAMEWORK_PRODUCT_NAME}$ {BUILD_DIR} / $ {FRAMEWORK_ PRODUCT_NAME} .framework / $ {FRAMEWORK_PRODUCT_NAME}

#将公共标题复制到框架中
cp -a$ {BUILT_PRODUCTS_DIR} / Headers /$ {BUILD_DIR} / $ { FRAMEWORK_PRODUCT_NAME} .framework / Versions / A / Headers

#将资源复制到框架中。
cp -a$ {BUILT_PRODUCTS_DIR} / Resources /$ {BUILD_DIR} / $ {FRAMEWORK_PRODUCT_NAME} .framework / Versions / A / Resources

#将2个静态库添加到1并推入.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}

#将结果框架移至我们的投放位置。
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} /
}

#实现它,numbah one ...
buildTwoArchitecturesDebug
buildTwoArchitecturesrelease


I'm having issues developing a Framework with the new Xcode 6 Dynamic Framework target.

Basically, I need the same result as the old way (Explained very well in this tutorial).

I tried this, but the problem is that the framework only produces a couple of ARM binaries. I need to have the i386/x86_64 binaries in there, as well, so it will be a complete framework.

I'm sure I'm overlooking something. Does anyone have a clue for this clueless person?

解决方案

Yeah, looks like this isn't very interesting to most folks.

Ah, well. I did get it going with a better version of the Wenderlich script, which I'll post here.

This has the significant advantage of being a "First Class Citizen" framework; not the iOS8-only dynamic version produced by the new target.

#! /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"

这篇关于制作多架构iOS和Mac OS框架的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆