Xcode – 找不到架构x86_64(iOS Lib)的符号

我正在build立一个静态库。 构build设置的体系结构设置为: $(ARCHS_STANDARD) ,显示为Standard Architectures (armv7, armv7s, arm64)我构build的libselectiOS设备,然后使用模拟器(例如iPhone视网膜)。

现在我有两个版本(一个在Debug-iphoneos ,另一个在Debug-iphonesimulator ,我使用lipo -create Debug-iphonesimulator来创build聚集的lib:

 lipo -create path/to/first/lib /path/to/second/lib -o MyLib.a 

如果我在另一个项目中使用这个库在任何具有64位体系结构的iOS设备上进行模拟,那么它将给symbol(s) not found for architecture x86_64 。 真正让我如此生气的是,lib项目本身在另一个使用lib的项目的工作区内。 我可以在64位iOS模拟器上模拟! (在所有的模拟器和设备上)。 我究竟做错了什么?

笔记:

  1. 这是不重复的Q.在指责我之前(因为这是我第二天试图解决这个愚蠢的问题),我search了Stack和Google。 所有的答案都没有帮助。
  2. 我正在使用Xcode 5.1.1。

我在构build静态库时遇到同样的问题。
最后我find了基本的解决办法。 (您需要为x86_64 / armv7 / armv7s / arm64构build通用库)

在这里输入图像说明

1)点击项目文件
2)点击目标
3)打开"Build Phases"
4)打开"Run Script"
5)添加"/bin/sh"和下面的脚本

 ##########################################
 #
 #cf http://stackoverflow.com/questions/3520977/build-fat-static-library-device-simulator-using-xcode-and-sdk-4
 #
 #版本2.7
 #
 #最新变化:
 # - 支持iPhone 5 / iPod Touch 5(使​​用苹果公司的解决方法来修补缺陷)
 #
 #目的:
 #在XCode中自动为iPhone + iPad + iPhone模拟器创build通用静态库
 #
 #作者:亚当·马丁 -  http://twitter.com/redglassesapps
 #基于:来自Eonil的原始脚本(主要更改:Eonil的脚本在Xcode GUI中不起作用 - 它将会破坏您的计算机)
 #

设置-e
设置-o pipefail

 ################# [testing:帮助解决在Xcode中的任何未来错误] ########
 #
 DEBUG_THIS_SCRIPT = “假”

如果[$ DEBUG_THIS_SCRIPT =“true”]
然后
 echo“########### TESTS #############”
回声“debugging此脚本时使用下列variables;请注意,它们可能会更改recursion”
回声“BUILD_DIR = $ BUILD_DIR”
 echo“BUILD_ROOT = $ BUILD_ROOT”
回声“CONFIGURATION_BUILD_DIR = $ CONFIGURATION_BUILD_DIR”
回声“BUILT_PRODUCTS_DIR = $ BUILT_PRODUCTS_DIR”
回声“CONFIGURATION_TEMP_DIR = $ CONFIGURATION_TEMP_DIR”
回声“TARGET_BUILD_DIR = $ TARGET_BUILD_DIR”
科幻

 #####################[ 第1部分 ]##################
 #首先,制定BASESDK版本号(注意:苹果应该报告这个,但是它们隐藏了它)
 #(附带:在sh中search子串是一个噩梦!Sob)

 SDK_VERSION = $(echo $ {SDK_NAME} | grep -o'。\ {3 \} $')

 #接下来,如果我们在SIM或DEVICE中,请解决

如果[$ {PLATFORM_NAME} =“iphonesimulator”]
然后
 OTHER_SDK_TO_BUILD =的iPhoneOS $ {} SDK_VERSION
其他
 OTHER_SDK_TO_BUILD = iphonesimulator $ {} SDK_VERSION
科幻

 echo“XCodeselect了SDK:$ {PLATFORM_NAME},版本号为:$ {SDK_VERSION}(尽pipe返回目标:$ {IPHONEOS_DEPLOYMENT_TARGET})”
回声“...因此,OTHER_SDK_TO_BUILD = $ {OTHER_SDK_TO_BUILD}”
 #
 ##################### [part 1结束] ##################

 #####################[ 第2部分 ]##################
 #
 #如果这是原始调用,则调用WHATEVER其他构build是必需的
 #
 #Xcode已经build立了一个目标...
 #
 #...但这是一个图书馆,所以苹果是错误的设置它build立一个。
 #...我们需要build立所有的目标
 #...我们不能重新构build已经构build的目标:如果你尝试这个(无限recursion!),Xcode将会破坏你的计算机!
 #
 #
所以:只build立缺less的平台/configuration。

 if [“true”== $ {ALREADYINVOKED:-false}]
然后
回声“RECURSION:我不是根调用,所以我不会递解”
其他
 # 危急:
 #防止无限recursion(Xcode糟糕)
 export ALREADYINVOKED =“true”

回声“RECURSION:我是根...现在recursion所有缺less的构build目标...”
 echo“RECURSION:...即将调用:xcodebuild -configuration \”$ {CONFIGURATION} \“-project \”$ {PROJECT_NAME} .xcodeproj \“-target \”$ {TARGET_NAME} \“-sdk \”$ { OTHER_SDK_TO_BUILD} \“$ {ACTION} RUN_CLANG_STATIC_ANALYZER = NO”BUILD_DIR = \“$ {BUILD_DIR} \”BUILD_ROOT = \“$ {BUILD_ROOT} \”SYMROOT = \“$ {SYMROOT} \”

 xcodebuild -configuration“$ {CONFIGURATION}”-project“$ {PROJECT_NAME} .xcodeproj”-target“$ {TARGET_NAME}”-sdk“$ {OTHER_SDK_TO_BUILD}”$ {ACTION} RUN_CLANG_STATIC_ANALYZER = NO BUILD_DIR =“$ {BUILD_DIR}” BUILD_ROOT =“$ {BUILD_ROOT}”SYMROOT =“$ {SYMROOT}”

 ACTION = “打造”

 #将所有平台二进制文件作为每个configuration的胖二进制文件。

 #计算(多个)构build文件来自哪里:
 CURRENTCONFIG_DEVICE_DIR = $ {SYMROOT} / $ {}configuration-iphoneos
 CURRENTCONFIG_SIMULATOR_DIR = $ {SYMROOT} / $ {}configuration-iphonesimulator

回声“以设备构build:$ {CURRENTCONFIG_DEVICE_DIR}”
回声“以模拟器构build:$ {CURRENTCONFIG_SIMULATOR_DIR}”

 CREATING_UNIVERSAL_DIR = $ {SYMROOT} / $ {}configuration - 通用
回声“...我将输出一个通用的构build:$ {CREATING_UNIVERSAL_DIR}”

 #...删除此脚本以前运行的产品
 #注意:这个目录只能由这个脚本创build - 删除应该是安全的!

 rm -rf“$ {CREATING_UNIVERSAL_DIR}”
 mkdir“$ {CREATING_UNIVERSAL_DIR}”

 #
 echo“lipo:用于当前configuration($ {CONFIGURATION})创build输出文件:$ {CREATING_UNIVERSAL_DIR} / $ {EXECUTABLE_NAME}”
 xcrun -sdk iphoneos lipo -create -output“$ {CREATING_UNIVERSAL_DIR} / $ {EXECUTABLE_NAME}”“$ {CURRENTCONFIG_DEVICE_DIR} / $ {EXECUTABLE_NAME}”“$ {CURRENTCONFIG_SIMULATOR_DIR} / $ {EXECUTABLE_NAME}”

 #########
 #
 #增加:StackOverflowbuild议也复制“包含”文件
 #(未经testing,但应工作正常)
 #
回声“从$ {PUBLIC_HEADERS_FOLDER_PATH}中获取标题”
回声“(如果你在另一个项目中embedded你的图书馆项目,你将需要添加”
回声“一个”用户search头“的build立设置:( NB包括下面的双引号!)”
 echo'“$(TARGET_BUILD_DIR)/ usr / local / include /”'
 if [-d“$ {CURRENTCONFIG_DEVICE_DIR} $ {PUBLIC_HEADERS_FOLDER_PATH}”]
然后
 mkdir -p“$ {CREATING_UNIVERSAL_DIR} $ {PUBLIC_HEADERS_FOLDER_PATH}”
 #*需要在双引号之外?
 cp -r“$ {CURRENTCONFIG_DEVICE_DIR} $ {PUBLIC_HEADERS_FOLDER_PATH}”*“$ {CREATING_UNIVERSAL_DIR} $ {PUBLIC_HEADERS_FOLDER_PATH}”
科幻
科幻

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

7)在Finder打开产品

在这里输入图像说明

8)向上导航1个目录(“cmd +↑”),你会看到"Release-universal"目录。 在这里输入图像说明

将有你的"fat/universal"图书馆,你准备好去!

我在我的一个应用程序中使用了一个框架lib,当我尝试在iPhone Retina 64bit模拟器中testing它时遇到了这个问题。

我只是将x86_64作为一个架构来添加,并将其设置为始终为所有架构构build。 工作的魅力。

在这里输入图像说明

lipo工具不仅可以创buildfat-o二进制文件,还可以检查它们: xcrun lipo -info /path/to/libThing.a

这将输出文件中的体系结构。 在使用lipojoin二进制文件之前,运行这个文件以确保您期望的体系结构存在。 在胖二进制连接的产品上运行这也是一个好主意。

在你的情况下,你需要:

iPhoneSDKconfiguration:armv7,armv7s,arm64

iPhoneSimulatorconfiguration:i386,x86_64

看来,iPhoneSimulator构build产品不是基于你的问题生产一个x86_64二进制文件。 检查你的构buildconfiguration – 特别是,“只有构build活动架构”( ONLY_ACTIVE_ARCH )应该设置为NO。 对于Release来说,默认是NO,但是对于debugging是YES。 如果是YES,则构build产品中只有一个架构。

转到您的应用程序项目目标并查找库searchpath

现在检查你的库文件path应该用双引号写成:

 "$(SRCROOT)/MyAppTest/TestFlight" 

如果没有双引号,只需添加它们并编译项目。

希望它能为你工作。