如何在 xcode 4.5 中同时支持 armv6 和 armv7s 进行发布构建

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12619124/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 04:35:08  来源:igfitidea点击:

How to support both armv6 and armv7s for release build in xcode 4.5

xcodexcode4.5armv7armv6

提问by schystz

I know that this is not possible and Apple planned it this way to force the users to upgrade their devices. But I just want to know if there is some workaround or hacks in able to do this? The client insists that we should still support armv6 because of a still "large" percentage of the app users.

我知道这是不可能的,Apple 计划以这种方式强制用户升级他们的设备。但我只想知道是否有一些解决方法或黑客能够做到这一点?客户坚持认为我们仍然应该支持 armv6,因为应用程序用户的比例仍然“很大”。

I know a command called lipoto merge static libraries and I read somewhere that we can also use it to merge ipa files but I'm not sure how its exactly done. I did a couple of searching around already on google and this site, buts its hard to find a concrete answer.

我知道一个叫做lipo合并静态库的命令,我在某处读到我们也可以用它来合并 ipa 文件,但我不确定它是如何完成的。我已经在谷歌和这个网站上进行了几次搜索,但很难找到具体的答案。

回答by Mike

I've been able to do this successfully with my app that's in the App Store. It supports armv6, armv7, and armv7s and iOS versions from 4.2 to 6.0. I've verified that it runs on older devices (iPhone 3G, iPod touch 2g) all the way through the iPhone 5.

我已经能够使用 App Store 中的应用程序成功地做到这一点。它支持 armv6、armv7 和 armv7s 以及从 4.2 到 6.0 的 iOS 版本。我已经验证它可以在旧设备(iPhone 3G、iPod touch 2g)上运行到 iPhone 5。

This method requires having both Xcode 4.5 and an older version of Xcode installed simultaneously. I'm still on 4.3.2 for my older version, but 4.4 should work as well.

此方法需要同时安装 Xcode 4.5 和旧版本的 Xcode。我的旧版本仍然使用 4.3.2,但 4.4 应该也可以使用。

I had screenshots for this answer, but Stack Overflow won't let me post them because I'm new. :(

我有这个答案的截图,但 Stack Overflow 不允许我发布它们,因为我是新手。:(

Setup in Xcode 4.5

在 Xcode 4.5 中设置

  1. Add a new build configuration for your armv6 build. I duplicated the Release config and named it Release_armv6.

  2. Set the Architectures and Valid Architectures for your build configurations. For all but Release_armv6, use the default. For Release_armv6, manually set it to armv6. http://i.stack.imgur.com/h8Mpl.png

  3. If you're using iOS 6 features that Xcode 4.4 and below won't understand, you'll need to #ifdef these out for your armv6 build. In Build Settings under Other C Flags and Other C++ Flags I added -DARMV6_ONLYto my Release_armv6 config. Then wherever the code uses a new iOS 6 API, I do something like #ifndef ARMV6_ONLY / #endif as appropriate. http://i.stack.imgur.com/czF6J.png

  4. Add a new scheme and set it to use the Release_armv6 build configuration in all cases.

  5. Under Build Phases, add a Run Script Build Phase with the following script (set the Shell to /bin/csh). This is where the magic happens. Edit the Configuration section:Determine your full path to the Release_armv6 build and substitute it for ARMV6_EXECUTABLE_PATH. Also set MINIMUM_OS.

  1. 为您的 armv6 构建添加新的构建配置。我复制了 Release 配置并将其命名为 Release_armv6。

  2. 为您的构建配置设置架构和有效架构。对于除 Release_armv6 之外的所有版本,使用默认值。对于 Release_armv6,手动将其设置为armv6http://i.stack.imgur.com/h8Mpl.png

  3. 如果您使用的是 Xcode 4.4 及更低版本无法理解的 iOS 6 功能,则需要为 armv6 构建 #ifdef 这些功能。在其他 C 标志和其他 C++ 标志下的构建设置中,我将-DARMV6_ONLY添加到我的 Release_armv6 配置中。然后在代码使用新的 iOS 6 API 的任何地方,我都会根据需要执行 #ifndef ARMV6_ONLY / #endif 之类的操作。 http://i.stack.imgur.com/czF6J.png

  4. 添加一个新方案并将其设置为在所有情况下都使用 Release_armv6 构建配置。

  5. 在 Build Phases 下,使用以下脚本添加 Run Script Build Phase(将 Shell 设置为/bin/csh)。这就是魔法发生的地方。编辑配置部分:确定 Release_armv6 构建的完整路径并将其替换为 ARMV6_EXECUTABLE_PATH。还要设置 MINIMUM_OS。



    #
    # Script to add armv6 architecture to iOS executable built with Xcode 4.5
    #

    #################
    # Configuration #
    #################
    # Change this to the full path where Xcode 4.4 (or below) puts your armv6 output
    setenv ARMV6_EXECUTABLE_PATH "$BUILD_ROOT/Release_armv6-iphoneos/$EXECUTABLE_PATH"

    # Your "real" minimum OS version since Xcode 4.5 wants to make it iOS 4.3
    # Must be 4.2 or below if you are supporting armv6...
    setenv MINIMUM_OS 4.2
    #####################
    # End configuration #
    #####################


    # For debugging
    echo CURRENT_ARCH = $CURRENT_ARCH
    echo CONFIGURATION = $CONFIGURATION

    # Don't need to do this for armv6 (built in older Xcode), simulator (i386), or debug build
    if ("$CURRENT_ARCH" == "armv6") exit 0
    if ("$CURRENT_ARCH" == "i386") exit 0
    if ("$CONFIGURATION" != "Release" && "$CONFIGURATION" != "Beta Test") exit 0

    # Paths
    setenv LIPO_PATH "$CODESIGNING_FOLDER_PATH/${EXECUTABLE_NAME}.lipo"
    setenv FINAL_PATH "$CODESIGNING_FOLDER_PATH/$EXECUTABLE_NAME"
    setenv FULL_INFO_PLIST_PATH "$CONFIGURATION_BUILD_DIR/$INFOPLIST_PATH"

    # Debug / sanity check
    lipo -info "$FINAL_PATH"
    ls -l "$ARMV6_EXECUTABLE_PATH"

    # Make sure something exists at $LIPO_PATH even if the next command fails
    cp -pv "$FINAL_PATH" "$LIPO_PATH"

    # If rebuilding without cleaning first, old armv6 might already be there so remove it
    # If not, lipo won't output anything (thus the cp command just above)
    lipo -remove armv6 -output "$LIPO_PATH" "$FINAL_PATH"

    # Add armv6 to the fat binary, show that it worked for debugging, then remove temp file
    lipo -create -output "$FINAL_PATH" "$ARMV6_EXECUTABLE_PATH" "$LIPO_PATH"
    lipo -info "$FINAL_PATH"
    rm -f "$LIPO_PATH"

    # Change Info.plist to set minimum OS version to 4.2 (instead of 4.3 which Xcode 4.5 wants)
    /usr/libexec/PlistBuddy -c "Set :MinimumOSVersion $MINIMUM_OS" "$FULL_INFO_PLIST_PATH"
    plutil -convert binary1 "$FULL_INFO_PLIST_PATH"

Build Process

构建过程

When you're ready to create a release build, do it in the following order:

当您准备好创建发布版本时,请按以下顺序进行:

  1. Close Xcode 4.5 and open Xcode 4.4 or below. Select your armv6 scheme and build it.

  2. Close Xcode 4.4 or below and open Xcode 4.5. Select your Release scheme and build it.

  1. 关闭 Xcode 4.5 并打开 Xcode 4.4 或更低版本。选择您的 armv6 方案并构建它。

  2. 关闭 Xcode 4.4 或更低版本并打开 Xcode 4.5。选择您的发布方案并构建它。

That's pretty much it. Check the build output to verify that you got what you want - an executable with three architectures in it. The last output from the run script should tell you this.

差不多就是这样。检查构建输出以验证您是否获得了所需内容 - 一个包含三种架构的可执行文件。运行脚本的最后输出应该告诉你这一点。

If anyone has ideas to improve this, please feel free. I imagine you might be able to get fancy and call Xcode 4.4's "xcodebuild" command from within the build script, alleviating the need to switch between Xcode versions at all. But this works well enough for me. ;)

如果有人有改进这一点的想法,请随意。我想您可能会喜欢并从构建脚本中调用 Xcode 4.4 的“xcodebuild”命令,从而完全减少在 Xcode 版本之间切换的需要。但这对我来说已经足够了。;)

Caveats:

注意事项:

  • Just to be safe, you might want to edit your xib files in the older version of Xcode. So far it seems like 4.5 is backwards compatible, but you never know.

  • In fact, you might consider just doing most of your development, except for iOS 6-specific stuff, in the older Xcode. Depends on whatever's easiest for you.

  • 为安全起见,您可能希望在旧版本的 Xcode 中编辑您的 xib 文件。到目前为止,4.5 似乎是向后兼容的,但你永远不知道。

  • 事实上,您可能会考虑在旧版 Xcode 中完成大部分开发工作,iOS 6 特定的内容除外。取决于对您来说最简单的方法。

回答by ??u??

There is a another way as gcc-4.2 still supports armv6, which won't require you to close Xcode 4.5 an open a previous version (for compilation, but not for running app on a 4.2 device) :

还有另一种方式,因为 gcc-4.2 仍然支持 armv6,它不需要您关闭 Xcode 4.5 并打开以前的版本(用于编译,但不适用于在 4.2 设备上运行应用程序):

  • Add armv6 to both valid archs and archs :
  • 将 armv6 添加到有效的 archs 和 archs :

Archs : $(ARCHS_STANDARD_32_BIT) armv6

拱门:$(ARCHS_STANDARD_32_BIT) armv6

Valid Architectures : armv6 armv7 armv7s

有效架构:armv6 armv7 armv7s

  • Vim (or TextEdit) your project.pbxproj file to replace IPHONEOS_DEPLOYMENT_TARGET to 4.0 - 4.1 - 4.2 as you need, Xcode 4.5 won't let you get below 4.3.
  • Vim(或 TextEdit)你的 project.pbxproj 文件,根据需要将 IPHONEOS_DEPLOYMENT_TARGET 替换为 4.0 - 4.1 - 4.2,Xcode 4.5 不会让你低于 4.3。

Then, if you build your project, you will see warnings :

然后,如果您构建项目,您将看到警告:

warning: no rule to process file '$(PROJECT_DIR)/App/AppDelegate.m' of type sourcecode.c.objc for architecture armv6
warning: no rule to process file '$(PROJECT_DIR)/App/SomeFile.c' of type sourcecode.c.c for architecture armv6
  • Add a Build Rulefor source files with names matching : *.[mc]that will use LLVM GCC 4.2
  • 添加Build Rule名称匹配的源文件:*.[mc]将使用LLVM GCC 4.2

It works for static libraries, but not for apps :

它适用于静态库,但不适用于应用程序:

ld: file is universal (4 slices) but does not contain a(n) armv6 slice: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/lib/crt1.3.1.o for architecture armv6
  • For making it works for apps, we need to add the armv6 slice to this object file (which comes with the 5.1 SDK) :
  • 为了使其适用于应用程序,我们需要将 armv6 切片添加到此对象文件(随 5.1 SDK 一起提供):
lipo /path/to-4.4/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/usr/lib/crt1.3.1.o -extract armv6 -output /tmp/crt1.3.1-armv6.o
lipo /Applications/Xcode.app/Contents//Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/lib/crt1.3.1.o /tmp/crt1.3.1-armv6.o -create -output /tmp/crt1.3.1-armv677s.o
mv /Applications/Xcode.app/Contents//Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/lib/crt1.3.1.o /Applications/Xcode.app/Contents//Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/lib/crt1.3.1.o.bkp
mv /tmp/crt1.3.1-armv677s.o /Applications/Xcode.app/Contents//Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/lib/crt1.3.1.o

Compile your project and check that your app contains all archs :

编译您的项目并检查您的应用程序是否包含所有 archs :

$ file DerivedData/TestApp/Build/Products/Debug-iphoneos/TestApp.app/TestApp 
DerivedData/TestApp/Build/Products/Debug-iphoneos/TestApp.app/TestApp: Mach-O universal binary with 3 architectures
DerivedData/TestApp/Build/Products/Debug-iphoneos/TestApp.app/TestApp (for architecture armv6): Mach-O executable arm
DerivedData/TestApp/Build/Products/Debug-iphoneos/TestApp.app/TestApp (for architecture armv7): Mach-O executable arm
DerivedData/TestApp/Build/Products/Debug-iphoneos/TestApp.app/TestApp (for architecture cputype (12) cpusubtype (11)):  Mach-O executable arm

Note that the dSYM file also contains all archs (useful for crash report symbolification) :

请注意,dSYM 文件还包含所有拱形(用于崩溃报告符号化):

$ file DerivedData/TestApp/Build/Products/Debug-iphoneos/TestApp.app.dSYM/Contents/Resources/DWARF/TestApp 
DerivedData/TestApp/Build/Products/Debug-iphoneos/TestApp.app.dSYM/Contents/Resources/DWARF/TestApp: Mach-O universal binary with 3 architectures
DerivedData/TestApp/Build/Products/Debug-iphoneos/TestApp.app.dSYM/Contents/Resources/DWARF/TestApp (for architecture armv6):   Mach-O dSYM companion file arm
DerivedData/TestApp/Build/Products/Debug-iphoneos/TestApp.app.dSYM/Contents/Resources/DWARF/TestApp (for architecture armv7):   Mach-O dSYM companion file arm
DerivedData/TestApp/Build/Products/Debug-iphoneos/TestApp.app.dSYM/Contents/Resources/DWARF/TestApp (for architecture cputype (12) cpusubtype (11)):    Mach-O dSYM companion file arm

I've sucessfully installed and launched the app on an iOS 4.2 2gen iPod touch by opening xcode 4.4.1, then Product-> Run without building.

我已经成功地在 iOS 4.2 2gen iPod touch 上安装并启动了该应用程序,方法是打开 xcode 4.4.1,然后Product-> Run without building

  • When you Archiveyour product, you may experience again the Apple Mach-O Linker error, this time involving other files, such as libarclite_iphoneos.aor libclang_rt.ios.a:
  • 当您存档产品时,您可能会再次遇到 Apple Mach-O 链接器错误,这次涉及其他文件,例如libarclite_iphoneos.alibclang_rt.ios.a
ld: file is universal (2 slices) but does not contain a(n) armv6 slice: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphoneos.a for architecture armv6
ld: file is universal (2 slices) but does not contain a(n) armv6 slice: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/4.1/libclang_rt.ios.a for architecture armv6

The procedure used for crt1.3.1.o applies to these files too, and will fix the error allowing Xcode to successfully archive your project: you can use the path printed by ldto find the file and join the armv6 slice with lipo; just keep in mind that libclang_rt.ios.a in the previous versions of Xcode isn't located in Xcode.app/[...]/usr/lib/clang/4.1but in Xcode.app/[...]/usr/lib/clang/4.0.

用于 crt1.3.1.o 的过程也适用于这些文件,并将修复允许 Xcode 成功归档您的项目的错误:您可以使用ld打印的路径查找文件并使用lipo加入 armv6 切片;只是要记住,libclang_rt.ios.a在Xcode的以前版本没有位于Xcode.app/[...]/usr/lib/clang/4.1但是在Xcode.app/[...]/usr/lib/clang/4.0

I've successfully archived the file, deployed it with an ad-hoc distribution profile, and tested on iPhone 3G (4.2.1) and iPhone 3GS (6.0).

我已成功归档文件,使用临时分发配置文件部署它,并在 iPhone 3G (4.2.1) 和 iPhone 3GS (6.0) 上进行了测试。

  • Last issue : we can't launch app. In the Organizer, there is the message : Devices of type “iPhone 3G” are not supported by this version of Xcode.
  • 最后一个问题:我们无法启动应用程序。在 中Organizer,有消息:此版本的 Xcode 不支持类型为“iPhone 3G”的设备。

But an lsin the DeviceSupportshows :

但是lsDeviceSupport节目中:

 ls /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/ 
4.2          4.3          5.0          5.1          6.0 (10A403)

With no diffs in the 4.2 directory from Xcode 4.4.1.

与 Xcode 4.4.1 的 4.2 目录中没有差异。

The question is now : how Xcode detect is device is supported or not ?

现在的问题是:Xcode 如何检测设备是否受支持?

Opening /Applications/Xcode.app/Contents/Developer//Platforms/iPhoneOS.platform/Developer//Library/PrivateFrameworks/DTDeviceKitBase.framework/DTDeviceKitBasewith Hex Fiend(or another hex editor), and replacing ascii 4.3with 4.2make the error message disappear, and app installed on the device are listed (but device bullet in the device list is still red).

打开/Applications/Xcode.app/Contents/Developer//Platforms/iPhoneOS.platform/Developer//Library/PrivateFrameworks/DTDeviceKitBase.framework/DTDeviceKitBaseHex Fiend(或其他十六进制编辑器),并取代ASCII4.34.2化妆错误消息消失,并安装在设备上的应用程序中列出(但在设备列表设备子弹仍是红色)。

Then we need to edit /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks//DTDeviceKit.framework/Versions/Current/DTDeviceKitand replace :

然后我们需要编辑/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks//DTDeviceKit.framework/Versions/Current/DTDeviceKit和替换:

Expired.deviceArchitecture.iPhone1,1.iPhone1,2.iPod1,1.iPod2,1.iPod2,2.armv6

Expired.deviceArchitecture.iPhone1,1.iPhone1,2.iPod1,1.iPod2,1.iPod2,2.armv6

to :

到 :

Expired.deviceArchitecture.iPhone0,1.iPhone0,2.iPod0,1.iPod0,1.iPod0,2.armv5

Expired.deviceArchitecture.iPhone0,1.iPhone0,2.iPod0,1.iPod0,1.iPod0,2.armv5

Then we have an orange bullet in the Organizer (Xcode 4.5.1) :

然后我们在管理器(Xcode 4.5.1)中有一个橙色的子弹:

The version of iOS on “iPhone” is too old for use with this version of the iOS SDK. Please restore the device to a version of the OS listed below.

OS Installed on iPhone
4.2.1 (8C148)

Xcode Supported iOS Versions
6.0 (10A403)
5.1
5.0
4.3

The question is now : where Xcode Supported iOS Versions are defined ?

现在的问题是:Xcode 支持的 iOS 版本在哪里定义?

As there is a 4.2directory in /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/, it should already be supported...

由于 中有一个4.2目录/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/,它应该已经被支持...

Tried to copy iPhoneOS4.2.sdkfrom Xcode 4.4.1 to /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/, but it don't make device supported.

试图iPhoneOS4.2.sdk从 Xcode 4.4.1复制到/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/,但它不支持设备。

So haven't found how to add 4.2 device support in Xcode 4.5. Any ideas ?

所以还没有找到如何在 Xcode 4.5 中添加 4.2 设备支持。有任何想法吗 ?

Conclusion : compiling for armv6/7/7s within Xcode 4.5 is possible. But it is not possible to start an app on a 4.2 armv6 device without starting Xcode 4.4.

结论:在 Xcode 4.5 中编译 armv6/7/7s 是可能的。但是,如果不启动 Xcode 4.4,则无法在 4.2 armv6 设备上启动应用程序。

Big update : it works with Xcode 4.5.2 !

重大更新:它适用于 Xcode 4.5.2!

Now the bullet is green in Xcode 4.5.2 :-) The device appear in the drop down list near the Run button. But when trying to run the app, got the message :

现在 Xcode 4.5.2 中的项目符号是绿色的 :-) 该设备出现在“运行”按钮附近的下拉列表中。但是在尝试运行该应用程序时,收到消息:

Xcode cannot run using the selected device.
Choose a destination with a supported architecture in order to run on this device.

Simply add armv6 to the valid architectures :-)

只需将 armv6 添加到有效架构中即可:-)

Other note : the Build Rulefor source files with names matching : *.[mc]can use LLVM GCC 4.2or Apple LLVM compiler 4.1, or Default compiler

其他注意事项:Build Rule对于名称匹配的源文件:*.[mc]可以使用LLVM GCC 4.2Apple LLVM compiler 4.1,或Default compiler

回答by Jerome

Thanks for this useful script !

感谢这个有用的脚本!

I successfully combined all infos from this entire post, the resulting complete script is below. This script requires having both Xcode 4.5.x and a previous Xcode version supporting armv6 (Xcode 4.4.1 for instance, installed in /Applications/Xcode 4.4.1.app)

我成功地结合了整篇文章中的所有信息,生成的完整脚本如下。此脚本需要 Xcode 4.5.x 和支持 armv6 的先前 Xcode 版本(例如 Xcode 4.4.1,安装在 /Applications/Xcode 4.4.1.app 中)

The script does NOT require to compile first in xcode 4.4.x, you just have to launch your latest Xcode, select the Release configuration and build. (the Release-armv6 configuration should have been defined like mentioned in the original post from Mike).

该脚本不需要首先在 xcode 4.4.x 中编译,您只需启动最新的 Xcode,选择 Release 配置并构建。(Release-armv6 配置应该像 Mike 的原始帖子中提到的那样定义)。

It will produce a .app compatible with armv6 armv7 and armv7s

它将生成与 armv6 armv7 和 armv7s 兼容的 .app

Thanks to Mike for the original script !

感谢 Mike 提供原始脚本!

#################
# Configuration #
#################
# Change this to the full path where Xcode 4.4 (or below) puts your armv6 output
setenv ARMV6_OUTPUT_PATH     "$BUILD_ROOT/Release-armv6-iphoneos/"
setenv ARMV6_EXECUTABLE_PATH "$ARMV6_OUTPUT_PATH$EXECUTABLE_PATH"

# Your "real" minimum OS version since Xcode 4.5 wants to make it iOS 4.3
# Must be 4.2 or below if you are supporting armv6...
setenv MINIMUM_OS 4.2
#####################
# End configuration #
#####################

# For debugging
echo CURRENT_ARCH = $CURRENT_ARCH
echo CONFIGURATION = $CONFIGURATION

# Don't need to do this for armv6 (built in older Xcode), simulator (i386), or debug build
#if ("$CURRENT_ARCH" == "armv6") exit 0
if ("$CURRENT_ARCH" == "i386") exit 0
if ("$CONFIGURATION" != "Release" && "$CONFIGURATION" != "Beta Test") exit 0

# Paths
setenv LIPO_PATH "$CODESIGNING_FOLDER_PATH/${EXECUTABLE_NAME}.lipo"
setenv FINAL_PATH "$CODESIGNING_FOLDER_PATH/$EXECUTABLE_NAME"
setenv FULL_INFO_PLIST_PATH "$CONFIGURATION_BUILD_DIR/$INFOPLIST_PATH"

#log file for armv6 build
echo "------------------------- BUILDING ARMV6 NOW -------------------------"
setenv LOGFILE "$BUILD_ROOT/buildarmv6.txt"
setenv CONFIGURATION_ARMV6 "${CONFIGURATION}-armv6"
#build armv6 version
echo "Building $FULL_PRODUCT_NAME armv6         CONFIG=$CONFIGURATION-armv6            target=$TARGETNAME"
"/Applications/Xcode 4.4.1.app/Contents/Developer/usr/bin/xcodebuild" -project         "${PROJECT_FILE_PATH}" -target "${TARGETNAME}" -sdk "${PLATFORM_NAME}" -configuration "$CONFIGURATION-armv6" CONFIGURATION_BUILD_DIR="$ARMV6_OUTPUT_PATH" >> "$LOGFILE"
echo "---------------------------- ARMV6 BUILT  -------------------------"
# to check for armv6 build errors
open "$LOGFILE"

# Debug / sanity check
lipo -info "$FINAL_PATH"
ls -l "$ARMV6_EXECUTABLE_PATH"

# Make sure something exists at $LIPO_PATH even if the next command fails
cp -pv "$FINAL_PATH" "$LIPO_PATH"

# If rebuilding without cleaning first, old armv6 might already be there so remove it
# If not, lipo won't output anything (thus the cp command just above)
lipo -remove armv6 -output "$LIPO_PATH" "$FINAL_PATH"

# Add armv6 to the fat binary, show that it worked for debugging, then remove temp file
lipo -create -output "$FINAL_PATH" "$ARMV6_EXECUTABLE_PATH" "$LIPO_PATH"
echo "------------------------- CHECK ARMV6 ARMV7 ARMV7S ARE MENTIONED BELOW -------------------------"
lipo -info "$FINAL_PATH"
echo "------------------------------------------------------------------------------------------------"
rm -f "$LIPO_PATH"

# Change Info.plist to set minimum OS version to 4.2 (instead of 4.3 which Xcode 4.5 wants)
/usr/libexec/PlistBuddy -c "Set :MinimumOSVersion $MINIMUM_OS" "$FULL_INFO_PLIST_PATH"
plutil -convert binary1 "$FULL_INFO_PLIST_PATH"

回答by K1w1Geek

Thanks for the post. We have a few apps to build so we automated the armv6 build using xcodebuild as you suggested. This is the part of our script (modified as we use bash) that does that, which can be added to your script above. This could be added before "# Debug / sanity check"

谢谢你的帖子。我们有几个应用程序要构建,因此我们按照您的建议使用 xcodebuild 自动化了 armv6 构建。这是我们脚本的一部分(在我们使用 bash 时进行了修改),可以将其添加到上面的脚本中。这可以在“#Debug / sanity check”之前添加

setenv LOGFILE "/Users/xyz/Desktop/buildarmv6.txt"

setenv CONFIGURATION_ARMV6 "${CONFIGURATION}_armv6"
echo "Building $FULL_PRODUCT_NAME armv6         CONFIG=$CONFIGURATION_ARMV6         target=$TARGETNAME"

"/Applications/Xcode 4.4.1.app/Contents/Developer/usr/bin/xcodebuild" -project "${PROJECT_FILE_PATH}" -target "${TARGETNAME}" -sdk "${PLATFORM_NAME}" -configuration "$CONFIGURATION_ARMV6" >> "$LOGFILE"

echo "Built armv6"
open "$LOGFILE" # to check for armv6 build errors

回答by Max_B

Thank to Mike for this useful tutorial and script. As mentioned by Piotr in comments, the script is failing if you run the archive command from Xcode since it use another build directory for archiving.

感谢 Mike 提供了这个有用的教程和脚本。正如 Piotr 在评论中提到的,如果您从 Xcode 运行存档命令,脚本将失败,因为它使用另一个构建目录进行存档。

Here below is my modification to the script to enable it for both normal release build and archive specific build.

下面是我对脚本的修改,以便为普通版本构建和特定于存档的构建启用它。

It assumes that the armv6 build is run before as per original instructions from Mike. It use bash syntax because it is easier for me to strip-out the common base build directory. So this implies translation of the original script to bash which is only a matter of replacing setenv by export and changing the if statements syntax.

它假定 armv6 构建之前已按照 Mike 的原始说明运行。它使用 bash 语法,因为我更容易剥离公共基础构建目录。因此,这意味着将原始脚本转换为 bash,这只是通过导出和更改 if 语句语法来替换 setenv 的问题。

# Find the common base directory for both build
XCODE_BUILD=${BUILD_ROOT%%/Build*}
# Change this to the full path where Xcode 4.4 (or below) puts your armv6 output, using the previously derived base
export ARMV6_EXECUTABLE_PATH="$XCODE_BUILD/Build/Products/Release_armv6-iphoneos/$EXECUTABLE_PATH"

回答by Chrysotribax

I would like to share my experience with kenji's answer. I think it's the best one and the best way to build a universal app which runs on armv6 / armv7 / armv7s, from iOS3.1 to iOS7.

我想与kenji的回答分享我的经验。我认为这是构建在 armv6 / armv7 / armv7s 上运行的通用应用程序的最佳方法,也是最好的方法,从 iOS3.1 到 iOS7。

Just do exactly as kenji suggests. You may ignore the parts about archiving the product, mainly if you send your app to apple via Application Loader (zipped).

完全按照kenji的建议去做。您可能会忽略有关归档产品的部分,主要是如果您通过 Application Loader(已压缩)将您的应用程序发送到苹果。

Few more advices :

还有一些建议:

When you build for "distribution" configuration, xcode will validate the product, and you will get two warnings :

当您为“分发”配置构建时,xcode 将验证产品,您将收到两个警告:

  • "architecture armv6 is not supported..."
  • "iOS deployment targets lower than 4.3 are not supported...".
  • “不支持架构 armv6..​​.”
  • “不支持低于 4.3 的 iOS 部署目标......”。

Of course, because you actually build for armv6 and you set the deployment target to 3.1 or 4.2, for example !

当然,因为您实际上是为 armv6 构建的,并且您将部署目标设置为 3.1 或 4.2,例如!

So... just ignore these warnings.

所以......只需忽略这些警告。

After sending your app to itunes connect, you will receive a warning email from apple, saying that your app is not "Position Independent Executable". Of course again, it's because your target is lower than 4.3. Just ignore this warning.

将您的应用程序发送到itunes connect 后,您将收到来自苹果的警告电子邮件,说您的应用程序不是“位置独立可执行文件”。当然又是因为你的目标低于4.3。只需忽略此警告。

At this date (2013 jul 03) I have successfully update an app to the appstore with this method, and it has passed validation. The app deployment target is iOS 3.1.2, and it supports armv6-armv7-armv7s.

在这一天(2013 年 7 月 3 日),我已使用此方法成功将应用程序更新到应用程序商店,并且已通过验证。应用部署目标为iOS 3.1.2,支持armv6-armv7-armv7s。

I would like to say also that :

我还想说:

  • If you make a brand new app, just set the deployment target to iOS6 or iOS5. Ignore old OS.
  • If you have an old app sold since 2010, with dozens of thousands of users, you actually may have much more people who use it on armv6 than Apple usually says. I think 3 years is a too short period to drop support for these old devices, mainly if your app CAN run on them.
  • 如果你做一个全新的应用程序,只需将部署目标设置为 iOS6 或 iOS5。忽略旧的操作系统。
  • 如果您有一款自 2010 年以来销售的旧应用,拥有数十万用户,那么实际上在 armv6 上使用它的人数可能比 Apple 通常所说的要多得多。我认为 3 年对于放弃对这些旧设备的支持太短了,主要是如果您的应用程序可以在它们上运行。

回答by jr19

Apple has stopped accepting builds that support pre iOS5 devices and contain an iPhone 5 launch image. Here is the email for the last build I submitted that was build on Xcode 4.4.1

Apple 已停止接受支持 iOS5 之前设备并包含 iPhone 5 启动图像的版本。这是我提交的最后一次构建的电子邮件,该构建是在 Xcode 4.4.1 上构建的

Dear developer,

We have discovered one or more issues with your recent delivery for "". To process your delivery, the following issues must be corrected:

Invalid Launch Image - Your app contains a launch image with a size modifier that is only supported for apps built with the iOS 6.0 SDK or later.

Once these issues have been corrected, go to the Version Details page and click "Ready to Upload Binary." Continue through the submission process until the app status is "Waiting for Upload." You can then deliver the corrected binary.

Regards,

The App Store team

亲爱的开发者,

我们发现您最近的“”交货有一个或多个问题。要处理您的交货,必须更正以下问题:

无效的启动图片 - 您的应用包含带有大小修饰符的启动图片,只有使用 iOS 6.0 SDK 或更高版本构建的应用才支持该图片。

更正这些问题后,请转到“版本详细信息”页面并单击“准备上传二进制文件”。继续提交过程,直到应用程序状态为“等待上传”。然后,您可以交付更正后的二进制文件。

问候,

应用商店团队