Xcode6创建通用iOS静态库框架

5
自从升级到Xcode和iOS8后,我一直在构建一个fat静态库时遇到了麻烦。有一些非常好的指令在这里在这里,但我认为第一组指令的某些部分和第二组指令都已经过时了。第一组指令说要使用Static iOS Framework,而第二组指令则说要使用Cocoa Touch Static Library。在Xcode6之前,我会使用Static iOS Framework,但现在他们把它改名为Cocoa Touch Framework,我不确定应该使用哪个。

所以,首先,我应该使用哪个来创建一个fat静态库?是Cocoa Touch Framework吗?还是Cocoa Touch Static Library

Cocoa Touch Framework

Cocoa Touch Static Library

然后我创建一个新的聚合目标:

Aggregate Target

然后我创建一个“运行脚本”:

Run Script


这是我使用的运行脚本(完整版):

# This script is based on Jacob Van Order's answer on apple dev forums 

https://devforums.apple.com/message/971277
# See also http://spin.atomicobject.com/2011/12/13/building-a-universal-framework-for-ios/ for the start


# To get this to work with a Xcode 6 Cocoa Touch Framework, create Framework
# Then create a new Aggregate Target. Throw this script into a Build Script Phrase on the Aggregate


######################
# Options
######################

REVEAL_ARCHIVE_IN_FINDER=true

FRAMEWORK_NAME="${PROJECT_NAME}"

SIMULATOR_LIBRARY_PATH="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${FRAMEWORK_NAME}.framework"

DEVICE_LIBRARY_PATH="${BUILD_DIR}/${CONFIGURATION}-iphoneos/${FRAMEWORK_NAME}.framework"

UNIVERSAL_LIBRARY_DIR="${BUILD_DIR}/${CONFIGURATION}-iphoneuniversal"

FRAMEWORK="${UNIVERSAL_LIBRARY_DIR}/${FRAMEWORK_NAME}.framework"


######################
# Build Frameworks
######################

xcodebuild -project ${PROJECT_NAME}.xcodeproj -sdk iphonesimulator -target ${PROJECT_NAME} -configuration ${CONFIGURATION} clean build CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-iphonesimulator | echo

xcodebuild -project ${PROJECT_NAME}.xcodeproj -sdk iphoneos -target ${PROJECT_NAME} -configuration ${CONFIGURATION} clean build CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-iphoneos | echo

#xcodebuild -target ${PROJECT_NAME} ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos  BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" | echo

#xcodebuild -target ${PROJECT_NAME} ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator  BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" | echo


######################
# Create directory for universal
######################

rm -rf "${UNIVERSAL_LIBRARY_DIR}"

mkdir "${UNIVERSAL_LIBRARY_DIR}"

mkdir "${FRAMEWORK}"


######################
# Copy files Framework
######################

cp -r "${DEVICE_LIBRARY_PATH}/." "${FRAMEWORK}"


######################
# Make fat universal binary
######################

lipo "${SIMULATOR_LIBRARY_PATH}/${FRAMEWORK_NAME}" "${DEVICE_LIBRARY_PATH}/${FRAMEWORK_NAME}" -create -output "${FRAMEWORK}/${FRAMEWORK_NAME}" | echo


######################
# On Release, copy the result to desktop folder
######################

if [ "${CONFIGURATION}" == "Release" ]; then
mkdir "${HOME}/Desktop/${FRAMEWORK_NAME}-${CONFIGURATION}-iphoneuniversal/"
cp -r "${FRAMEWORK}" "${HOME}/Desktop/${FRAMEWORK_NAME}-${CONFIGURATION}-iphoneuniversal/"
fi


######################
# If needed, open the Framework folder
######################

if [ ${REVEAL_ARCHIVE_IN_FINDER} = true ]; then
if [ "${CONFIGURATION}" == "Release" ]; then
open "${HOME}/Desktop/${FRAMEWORK_NAME}-${CONFIGURATION}-iphoneuniversal/"
else
open "${UNIVERSAL_LIBRARY_DIR}/"
fi
fi

但当我尝试构建时,收到以下消息:
fatal error: lipo: can't open input file: /Users/pdl/Library/Developer/Xcode/DerivedData/innerIDMobileLicense-blnxjfvoxnqfelftmzojgdwhvazk/Build/Products/Debug-iphonesimulator/innerIDMobileLicense.framework/innerIDMobileLicense (No such file or directory)

没错,文件不存在!请注意下面第一张图片中有一个Unix可执行文件IdAirOpenCv。然后看看第二张图片,注意IdAirOpenCv不在那里。

这是我升级前习惯看到的:

Old folder structure

这是我现在拥有的:

New folder structure

根据脚本,Unix可执行文件innerIDMobileLicense应该位于三个框架文件夹中的所有文件夹中,与Headers和Modules文件夹在同一级别。
有人知道我做错了什么吗?
1个回答

2
致命错误:lipo: 无法打开输入文件:/Users/pdl/Library/Developer/Xcode/DerivedData/innerIDMobileLicense-blnxjfvoxnqfelftmzojgdwhvazk/Build/Products/Debug-iphonesimulator/innerIDMobileLicense.framework/innerIDMobileLicense(没有那个文件或目录)
你遇到的这个lipo错误很可能是由于包含该目录不存在引起的。
当Xcode没有框架项目时,该脚本就会被创建。
Lipo基本上将两个不同架构的二进制构建链接在一起以构建一个fat one。
因此,首先,我应该使用哪个来创建fat静态库?Cocoa Touch Framework还是Cocoa Touch Static Library?
任何一个都可以。Lipo可以链接框架内部的二进制文件和简单的静态库。
我所做的是创建一个静态库项目和一个框架项目。将静态库目标设置为设备或模拟器(使用sdk iphoneos或iphonesimulator)。将Universal Framework脚本添加到框架项目中,以使用其他SDK构建静态库,并将fat二进制文件放入框架中。还需要将所需的头文件复制到框架项目中。框架不需要编译任何内容。

光彦网!我很想给你此问题的积分,但我需要更多的信息。 :-) 很抱歉耽搁了一会儿,因为我需要在Android上工作一段时间,所以现在才回来。我按照您建议的创建了一个模板。但我不明白两者之间的区别。Cocoa Touch框架表示它是创建使用UIKit的框架的模板。Cocoa Touch静态库表示它是构建连接到Foundation框架的静态库的模板。您能解释一下这两者之间的区别吗?谢谢。 - Patricia
要明确一点:我的项目是一个框架,供客户应用程序使用。然而,我的框架使用了OpenCV框架。因此,我正在尝试构建一个静态库框架,将二进制文件与opencv2.framework库链接起来。我注意到Cocoa Touch Framework生成了一个.framework文件,而Cocoa Touch Static Library生成了一个.a文件。最终,我想要的是一个包含其文件夹结构中所有内容的.framework文件。在Xcode 5中,脚本使用了.a产品,并最终生成了Release-iphoneuniversal产品。这有帮助吗? - Patricia
光彦网!我在这里找到了一个关于框架之间差异的解释:https://github.com/kstenerud/iOS-Universal-Framework#mk-8-is-now-out-of-beta。 - Patricia
1
@Lucy 你好。我对于“fat library”的理解是它包含了x64、x32模拟器和arm系列真实设备的二进制文件。而“.a”静态库只适用于其中一种架构,而非两者兼容。使用Lipo工具可以将两个静态库合并成一个“fat”库。在我的情况下,我创建了一个框架和一个“fat”静态库,将“fat”库与一些头文件一起放入框架中。但我不确定如何包含另一个框架。你可能可以将opencv2.framework包含在你的框架中。 - guangyan wang
嗨,guangyan wang:是的,我可以将opencv2.framework包含到我的框架中。我现在离构建更近了。实际上,我正在构建但是我没有将输出文件复制到iphoneuniversal产品文件夹中。你有能分享给我的可用脚本吗? - Patricia
1
@Lucy,我不能分享我的代码,但它与这个类似:https://github.com/jverkoey/iOS-Framework/blob/master/scripts/build_framework.sh - guangyan wang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接