如何为 i386 和 x86_64 架构构建 Cocoa Touch 框架? [英] How to build Cocoa Touch Framework for i386 and x86_64 architecture?

查看:23
本文介绍了如何为 i386 和 x86_64 架构构建 Cocoa Touch 框架?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在构建 Cocoa Touch 框架(Swift 或 Object-C)并将其作为嵌入式二进制文件"添加到另一个项目后,当我尝试构建时收到以下错误消息

缺少所需的架构 i386...ld:未找到体系结构 i386 的符号clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)

根据现有的各种答案和扩展研究,我已将 i386 添加到 Architectures 构建设置中……

但是这似乎没有效果.当我检查使用时

lipo -info TesterFrameworkObjC

我只会得到

fat文件中的架构:TesterFrameworkObjC是:armv7 arm64

…i386(和x86_64)不应该也出现在这里吗?我错过了什么?

(我正在使用 Xcode 6.2 + 为 iOS 8.2 构建)

<小时>

一些新见解

使用此版本的 .

似乎这是一个 Xcode 错误,我通过添加构建脚本来解决它.它只会用所有架构编译你的库,然后 lipo 将其转换为胖二进制图像.

还要注意

<块引用>

查看模拟器的最终构建文件夹构建

Build/Products/Debug-iphoneos/TesterFrameworkSwift.framework/

您正在 iphone build 文件夹中查看 x86_64 和 i386 图像,它们应该在 Debug-iphonesimulator/TesterFrameworkSwift.framework/

您的脚本中还有一个递归问题,我已经更正了.

<上一页>UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-通用如果 [ "true" == ${ALREADYINVOKED:-false} ]然后回声递归:检测到,停止"别的导出 ALREADYINVOKED="true"# Step 1. 构建设备和模拟器版本xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" 干净构建xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" 干净构建# Step 2. 将框架结构(从 iphoneos build)复制到通用文件夹cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"# Step 3. 将 Swift 模块(从 iphonesimulator 构建)复制到复制的框架目录cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/."${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"# Step 4. 使用 lipo 创建通用二进制文件并将组合的可执行文件放在复制的框架目录中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. 将框架复制到项目目录的便捷步骤cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"# Step 6. 在Finder中打开项目目录的便捷步骤打开${PROJECT_DIR}"菲

6) 点击 "cmd + B"(构建项目)

7) 在Finder中打开产品

8)向上导航1个目录(cmd + ↑"),您将看到Release-universal"目录.

会有你的 "fat/universal" 库,你准备好了!

您可以通过以下方式查看

文件 test.dylibtest.dylib:具有 4 种架构的 Mach-O 通用二进制文件test.dylib(适用于 i386 架构):Mach-O 动态链接共享库 i386test.dylib(用于架构 x86_64):Mach-O 64 位动态链接共享库 x86_64test.dylib(用于架构 armv7):Mach-O 动态链接共享库 armtest.dylib(用于架构 arm64):Mach-O 64 位动态链接共享库

After building a Cocoa Touch framework (Swift or Object-C) and adding it to another project as "Embedded Binaries" I get the following error message when I try to build

missing required architecture i386
...
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Following various existing answers and extended research I already added i386 to the Architectures build settings …

However this doesn't seem to have an effect. When I check using

lipo -info TesterFrameworkObjC

I only get

Architectures in the fat file: TesterFrameworkObjC are: armv7 arm64

… shouldn't i386 (and x86_64) appear here as well? What am I missing?

(I am using Xcode 6.2 + building for iOS 8.2)


Some new insights

Using a version of this build script I am able to build the missing architectures for the Swift version of the framework.

However when I add this framework to my app and build I still get errors

Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$__TtC20TesterFrameworkSwift18TestFrameworkSwift", referenced from:
  objc-class-ref in ViewController.o
ld: symbol(s) not found for architecture x86_64

Looking at the final build folder building for the simulator

Build/Products/Debug-iphoneos/TesterFrameworkSwift.framework/

I can see that the architectures are still missing although they were part of the framework (as shown). How can I ensure all the right architecture builds of my framework are included when building the app?


Update

Looking at all the error messages to me it looks like the issue isn't actually to have the wrong products/archictures being built but one step later there the Linker isn't using the correct paths to them. Not sure how correct this.

解决方案

This is the same problem that I had.

Seems this is a Xcode bug, I workaround it by adding a build script. It will just compile your library with all architectures, and lipo it to fat binary image.

Also note

Looking at the final build folder building for the simulator

Build/Products/Debug-iphoneos/TesterFrameworkSwift.framework/

you are looking x86_64 and i386 images in iphone build folder, they should be in Debug-iphonesimulator/TesterFrameworkSwift.framework/

Also there is a recursion issue in your script, I've corrected it.

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

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

# Step 1. Build Device and Simulator versions
xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos  BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO 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}"

fi

6) Hit "cmd + B" (Build Project)

7) Open Product in Finder

8) Navigate 1 directory up ("cmd + ↑"), and you will see "Release-universal" directory.

There will be your "fat/universal" library, You are ready to go!

You can check it via

file test.dylib 
test.dylib: Mach-O universal binary with 4 architectures
test.dylib (for architecture i386): Mach-O dynamically linked shared library i386
test.dylib (for architecture x86_64):   Mach-O 64-bit dynamically linked shared library x86_64
test.dylib (for architecture armv7):    Mach-O dynamically linked shared library arm
test.dylib (for architecture arm64):    Mach-O 64-bit dynamically linked shared library

这篇关于如何为 i386 和 x86_64 架构构建 Cocoa Touch 框架?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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