ios 提交到 App Store 问题:不支持的架构 x86

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30547283/
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-08-31 06:09:09  来源:igfitidea点击:

Submit to App Store issues: Unsupported Architecture x86

iosxcode

提问by Saurabh Jain

So I am trying to use the Shopify API. When I archive the app and validate it then there are no issues but when I submit it to the app store then it gives me the following issues.

所以我正在尝试使用 Shopify API。当我存档应用程序并验证它时,没有问题,但是当我将它提交到应用程序商店时,它给了我以下问题。

  1. ERROR ITMS-90087: "Unsupported Architecture. Your executable contains unsupported architecture '[x86_64, i386]'."
  2. ERROR ITMS-90209: "Invalid segment Alignment. The App Binary at SJAPP.app/Frameworks/Buy.framework/Buy does not have proper segment alignment. Try rebuilding the app with the latest Xcode version." (I am already using the latest version.)
  3. ERROR ITMS-90125: "The Binary is invalid. The encryption info in the LC_ENCRYPTION_INFO load command is either missing or invalid, or the binary is already encrypted. This binary does not seem to have been built with Apple's Linker."
  4. WARNING ITMS-90080: "The Executable Payload/..../Buy.framework is not a Position Independent Executable. Please ensure that ur build settings are configured to create PIE executables."
  1. 错误 ITMS-90087:“不支持的架构。您的可执行文件包含不受支持的架构 '[x86_64, i386]'。”
  2. 错误 ITMS-90209:“无效的段对齐。SJAPP.app/Frameworks/Buy.framework/Buy 中的应用程序二进制文件没有正确的段对齐。尝试使用最新的 Xcode 版本重建应用程序。” (我已经在使用最新版本了。)
  3. 错误 ITMS-90125:“二进制文件无效。LC_ENCRYPTION_INFO 加载命令中的加密信息丢失或无效,或者二进制文件已经加密。这个二进制文件似乎不是用 Apple 的链接器构建的。”
  4. 警告 ITMS-90080:“可执行有效负载/..../Buy.framework 不是位置无关的可执行文件。请确保您的构建设置已配置为创建 PIE 可执行文件。”

回答by pAkY88

The problem is that the Buy framework contains a build for both the simulator (x86_64) and the actual devices (ARM).

问题是 Buy 框架包含模拟器 (x86_64) 和实际设备 (ARM) 的构建。

Of course, you aren't allowed to submit to the App Store a binary for an unsupported architecture, so the solution is to "manually" remove the unneeded architectures from the final binary, before submitting it.

当然,您不允许向 App Store 提交不受支持的架构的二进制文件,因此解决方案是在提交之前“手动”从最终二进制文件中删除不需要的架构。

Daniel Kennett came up with a nice solution and provides this scriptto add to the build phase:

Daniel Kennett 提出了一个很好的解决方案,并提供了这个脚本来添加到构建阶段:

APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"

# This script loops through the frameworks embedded in the application and
# removes unused architectures.
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
    FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
    FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
    echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"

    EXTRACTED_ARCHS=()

    for ARCH in $ARCHS
    do
        echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
        lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
        EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
    done

    echo "Merging extracted architectures: ${ARCHS}"
    lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
    rm "${EXTRACTED_ARCHS[@]}"

    echo "Replacing original executable with thinned version"
    rm "$FRAMEWORK_EXECUTABLE_PATH"
    mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"

done

I used it and it worked perfectly.

我使用了它,它工作得很好。

EDIT: make sure you look at the modified script posted by Varrry, as this one has some minor issues.

编辑:确保您查看 Varrry 发布的修改后的脚本,因为这个脚本有一些小问题。

回答by Varrry

Answergiven by pAkY88 works, but I faced the same problem as Mario A Guzman in https://stackoverflow.com/a/35240555/5272316: once we cut off unused architectures we can't run script any more since it tries to remove not existing slices, because xcode doesn't re-embed binary every time. Idea was - just remove i386 and x86_64 slices when building for archive, so I modified script:

答案由pAkY88给出的作品,但我面临着同样的问题,因为马里奥·古斯曼在https://stackoverflow.com/a/35240555/5272316:一旦我们切断了,我们不能运行脚本任何更多的未使用的架构,因为它试图删除不存在切片,因为 xcode 不会每次都重新嵌入二进制文件。想法是 - 在构建存档时删除 i386 和 x86_64 切片,所以我修改了脚本:

echo "Target architectures: $ARCHS"

APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"

find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"
echo $(lipo -info "$FRAMEWORK_EXECUTABLE_PATH")

FRAMEWORK_TMP_PATH="$FRAMEWORK_EXECUTABLE_PATH-tmp"

# remove simulator's archs if location is not simulator's directory
case "${TARGET_BUILD_DIR}" in
*"iphonesimulator")
    echo "No need to remove archs"
    ;;
*)
    if $(lipo "$FRAMEWORK_EXECUTABLE_PATH" -verify_arch "i386") ; then
    lipo -output "$FRAMEWORK_TMP_PATH" -remove "i386" "$FRAMEWORK_EXECUTABLE_PATH"
    echo "i386 architecture removed"
    rm "$FRAMEWORK_EXECUTABLE_PATH"
    mv "$FRAMEWORK_TMP_PATH" "$FRAMEWORK_EXECUTABLE_PATH"
    fi
    if $(lipo "$FRAMEWORK_EXECUTABLE_PATH" -verify_arch "x86_64") ; then
    lipo -output "$FRAMEWORK_TMP_PATH" -remove "x86_64" "$FRAMEWORK_EXECUTABLE_PATH"
    echo "x86_64 architecture removed"
    rm "$FRAMEWORK_EXECUTABLE_PATH"
    mv "$FRAMEWORK_TMP_PATH" "$FRAMEWORK_EXECUTABLE_PATH"
    fi
    ;;
esac

echo "Completed for executable $FRAMEWORK_EXECUTABLE_PATH"
echo $(lipo -info "$FRAMEWORK_EXECUTABLE_PATH")

done

This script simply removes i386 and x86_64 slices from fat binary (if they exist) if running not for simulator (that means destination folder isn't like "Debug-iphonesimulator").

如果不是为模拟器运行(这意味着目标文件夹不像“Debug-iphonesimulator”),此脚本只是从胖二进制文件(如果存在)中删除 i386 和 x86_64 切片。

Sorry, I'm not familiar with shell scripts, so may be someone could write it more elegant way. But it works)

抱歉,我不熟悉 shell 脚本,所以可能有人可以用更优雅的方式编写它。但它有效)

回答by odlp

If you're using Carthagethen you may experience this issue because the project is:

如果您使用的是Carthage,那么您可能会遇到此问题,因为该项目是:

  • Missing the carthage copy-frameworksbuild phase.
  • Or the build phase doesn't include all the frameworks (incomplete list).
  • 缺少carthage copy-frameworks构建阶段。
  • 或者构建阶段不包括所有框架(不完整列表)。

This action filters frameworks to a list of valid architectures (code).

此操作将框架过滤为有效架构(代码)列表。

Setting up the copy-frameworks build phase

设置复制框架构建阶段

From the Carthage building for iOS steps:

来自Carthage building for iOS 步骤

On your application targets' “Build Phases” settings tab, click the “+” icon and choose “New Run Script Phase”. Create a Run Script in which you specify your shell (ex: bin/sh), add the following contents to the script area below the shell:

/usr/local/bin/carthage copy-frameworks

and add the paths to the frameworks you want to use under “Input Files”, e.g.:

$(SRCROOT)/Carthage/Build/iOS/Box.framework$(SRCROOT)/Carthage/Build/iOS/Result.framework$(SRCROOT)/Carthage/Build/iOS/ReactiveCocoa.framework

This script works around an App Store submission bug triggered by universal binaries and ensures that necessary bitcode-related files and dSYMs are copied when archiving.

在应用程序目标的“构建阶段”设置选项卡上,单击“+”图标并选择“新建运行脚本阶段”。创建一个运行脚本,在其中指定您的外壳(例如:bin/sh),将以下内容添加到外壳下方的脚本区域:

/usr/local/bin/carthage copy-frameworks

并在“输入文件”下添加您要使用的框架的路径,例如:

$(SRCROOT)/Carthage/Build/iOS/Box.framework$(SRCROOT)/Carthage/Build/iOS/Result.framework$(SRCROOT)/Carthage/Build/iOS/ReactiveCocoa.framework

该脚本解决了由通用二进制文件触发的 App Store 提交错误,并确保在归档时复制必要的与位码相关的文件和 dSYM。

回答by Bart van Kuik

I resolved the error ITMS-90080 by removing a framework (the excellent SVProgressHUD) from the Embedded Binaries section (Xcode target -> General tab).

我通过从嵌入式二进制文件部分(Xcode 目标 -> 常规选项卡)中删除框架(优秀的 SVProgressHUD)解决了错误 ITMS-90080。

enter image description here

在此处输入图片说明

回答by Maciej Swic

If you are using Carthagemake sure your Embed FrameworksBuild Stepis before the Carthagecopy-frameworks

如果您正在使用,请Carthage确保您Embed FrameworksBuild StepCarthagecopy-frameworks



In some unusual cases (example: Lottie-iOS framework):

在一些不寻常的情况下(例如:Lottie-iOS 框架):

  • you will have it simply in "Link Library" as usual.

  • Howeveryou have to alsoexplicitly add it in "Embed Frameworks" (even though that seems pointless, since it works perfectly when you have it only in "Embed Frameworks"),

  • andput it in copy-frameworks

  • andensure copy-frameworks is after"Embed Frameworks"

  • 您将像往常一样简单地在“链接库”中拥有它。

  • 但是,必须在“嵌入框架”中明确添加它(尽管这看起来毫无意义,因为只有在“嵌入框架”中才能完美运行),

  • 把它复制框架

  • 确保复制框架“嵌入框架”之后

回答by MAhipal Singh

Remove [x86_64, i386]from the framework using below step. [x86_64, i386]is used for simulator.

使用以下步骤从框架中删除[x86_64, i386][x86_64, i386]用于模拟器。

  1. Open Terminal

  2. open your project drag path of respective framework to Terminal

    example : cd /Users/MAC/Desktop/MyProject/Alamofire.framework

  3. set your Framework name in below command and run

  1. 打开 Terminal

  2. 打开相应框架的项目拖动路径到终端

    例子 : cd /Users/MAC/Desktop/MyProject/Alamofire.framework

  3. 在下面的命令中设置您的框架名称并运行

lipo -remove i386 Alamofire -o Alamofire && lipo -remove x86_64 Alamofire -o Alamofire

lipo -remove i386 Alamofire -o Alamofire && lipo -remove x86_64 Alamofire -o Alamofire

  1. Now open your project again, Clean, Build & Run and Create Archive...
  1. 现在再次打开您的项目,清理、构建和运行并创建存档...

回答by AnBisw

I will add my 2 cents here (in a less scary way :-). I have encountered quite a number of fat libraries from Vendors that (for some reason) do not work the normal way by adding them to the Frameworksdirectory as documented by Apple. The only way we have been able to make them work is by pulling the .framekworkright into the project directory and linking the Embedded Frameworksand Link Binary with Librariesmanually in Build Settings. This seem to have worked without any issues, however, as with any fat library they come with the extraneous Simulator Architectures i386and x86_64along with the armarchitectures.

我将在这里添加我的 2 美分(以一种不那么可怕的方式:-)。我遇到了很多来自供应商的胖库,它们(出于某种原因)通过将它们添加到FrameworksApple 记录的目录中而无法正常工作。我们能够使它们工作的唯一方法是将.framekwork权利拉入项目目录并在构建设置中手动链接Embedded FrameworksLink Binary with Libraries。这似乎已经没有任何问题不过工作,与他们与外来的仿真架构任何脂肪库i386,并x86_64伴随着arm架构。

A quick way to check the architectures on the fat library is

检查胖库架构的一种快速方法是

$ cd 'Project_dir/Project'
$ lipo -info 'YourLibrary.framework/YourLibExec`

Which should spit an output something like this

哪个应该吐出这样的输出

Architectures in the fat file: YourLibrary.framework/YourLibExec are: i386 x86_64 armv7 arm64

This confirms that you will need to "trim the fat" (namely i386& x86_64) from your framework prior to iTunesConnect Archival upload, which doesn't allow these architectures (since they are unsupported for iOS).

这确认您需要在 iTunesConnect 存档上传之前从您的框架中“修剪脂肪”(即i386& x86_64),这不允许这些架构(因为它们不受 iOS 支持)。

Now, all the answers (or atleast some of the answers) here provide these wonderful Run Scripts that I am sure works really well, but only if your Framework resides in the Frameworksdirectory. Now unless you are a shell script junkie, those scripts without modifications, won't work for the scenario I explain above. However, there is a very simple way to get rid of the i386& x86_64architectures from the framework.

现在,这里的所有答案(或至少部分答案)都提供了这些精彩的运行脚本,我确信它们确实可以很好地工作,但前提是您的框架位于该Frameworks目录中。现在,除非您是 shell 脚本迷,否则那些未经修改的脚本将不适用于我上面解释的场景。但是,有一种非常简单的方法可以摆脱框架中的i386&x86_64架构。

  1. Open terminal in your project's directory.
  2. Change directory directly into the .framekwork, like

    cd YourProjectDir/YourProject/YourLibrary.framework

  3. Run the series of commands as shown below-

  1. 在项目目录中打开终端。
  2. 将目录直接更改为.framekwork,例如

    cd YourProjectDir/YourProject/YourLibrary.framework

  3. 运行一系列命令,如下所示 -

$ mv YourLibrary YourLibrary_all_archs
$ lipo -remove x86_64 YourLibrary_all_archs -o YourLibrary_some_archs
$ lipo -remove i386 YourLibrary_some_archs -o YourLibrary
$ rm YourLibrary_all_archs YourLibrary_some_archs

A few things to note here - lipo -removehas to be done once for each architecture to remove. lipodoes not modify the input file, it only produces a file so you have to run lipo -removeonce for x86_64and i386. The commands above is simply doing that by first renaming the executable and then eventually removing the desired archs, and then cleaning up the left over files. And that's it, you should now see a green check mark in Application Loader Archival upload to iTunesConnect.

这里需要注意一些事项 -lipo -remove必须为每个要删除的架构完成一次。lipo不修改输入文件,它只生成一个文件,因此您必须lipo -removex86_64和运行一次i386。上面的命令只是通过首先重命名可执行文件,然后最终删除所需的拱形,然后清理剩余的文件来完成此操作。就是这样,您现在应该在 Application Loader Archival 上传到 iTunesConnect 中看到一个绿色的复选标记。

Things to keep in mind: The above steps should only be done while production build, since the .frameworkwill be stripped off the simulator architectures, builds on simulators will stop working (which is expected). In development environment, there should be no need to strip the architectures off of the .frameworkfile since you want to be able to test on both Simulator and a physical device. If your fat library resides in the Frameworksfolder in the project then please look at the accepted answer.

要记住的事情:上述步骤应该只在生产构建时完成,因为.framework将从模拟器架构中剥离,在模拟器上构建将停止工作(这是预期的)。在开发环境中,不需要从.framework文件中剥离架构,因为您希望能够在模拟器和物理设备上进行测试。如果您的胖库位于Frameworks项目的文件夹中,请查看已接受的答案。

回答by Florin Dobre

I had same issue even after adding the script and updating the framework a few times.

即使在添加脚本并更新框架几次后,我也遇到了同样的问题。

Make sure in xCode the script is added at the end, after the embed. I think I accidentally moved the script before the embedded framework.

确保在 xCode 中,脚本在嵌入后添加到最后。我想我不小心将脚本移到了嵌入式框架之前。

enter image description here

在此处输入图片说明

Note: I have xCode 9.1

注意:我有 xCode 9.1

回答by Gurjinder Singh

Thanks to all the above answers. Here is a script working with swift 4.2 and 5. Replace Your_Framework_Name string with your Framework's original name.

感谢以上所有答案。这是一个使用swift 4.2 和 5的脚本。将 Your_Framework_Name 字符串替换为您的框架的原始名称。

APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
FRAMEWORK_NAME="Your_Framework_Name.framework"
# Check if Framework is present.
FRAMEWORK_LOCATION=$(find "$APP_PATH" -name "$FRAMEWORK_NAME" -type d)
if [ -z $FRAMEWORK_LOCATION ]; then
echo "Couldn't find Your_Framework_Name.framework in $APP_PATH. Make sure 'Embed Frameworks' build phase is listed before the 'Strip Unused Architectures' build phase."
exit 1
fi
# This script strips unused architectures
find "$APP_PATH" -name "$FRAMEWORK_NAME" -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"
EXTRACTED_ARCHS=()
for ARCH in $ARCHS
do
echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
done
echo "Merging extracted architectures: ${ARCHS}"
lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
rm "${EXTRACTED_ARCHS[@]}"
echo "Replacing original executable with thinned version"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"
done

回答by Kiran jadhav

Updated for Xcode 10.1, Below solution worked for me :

针对 Xcode 10.1 更新,以下解决方案对我有用:

Just you have to remove the framework from Embedded Binaries and just add it to the Linked Frameworks and Libraries.

只需从嵌入式二进制文件中删除框架,然后将其添加到链接框架和库中即可。

Refer below screenshot;

参考下面的截图;

enter image description here

在此处输入图片说明