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
Submit to App Store issues: Unsupported Architecture x86
提问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。当我存档应用程序并验证它时,没有问题,但是当我将它提交到应用程序商店时,它给了我以下问题。
- ERROR ITMS-90087: "Unsupported Architecture. Your executable contains unsupported architecture '[x86_64, i386]'."
- 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.)
- 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."
- 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."
- 错误 ITMS-90087:“不支持的架构。您的可执行文件包含不受支持的架构 '[x86_64, i386]'。”
- 错误 ITMS-90209:“无效的段对齐。SJAPP.app/Frameworks/Buy.framework/Buy 中的应用程序二进制文件没有正确的段对齐。尝试使用最新的 Xcode 版本重建应用程序。” (我已经在使用最新版本了。)
- 错误 ITMS-90125:“二进制文件无效。LC_ENCRYPTION_INFO 加载命令中的加密信息丢失或无效,或者二进制文件已经加密。这个二进制文件似乎不是用 Apple 的链接器构建的。”
- 警告 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-frameworks
build 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
回答by Maciej Swic
If you are using Carthage
make sure your Embed Frameworks
Build Step
is before the Carthage
copy-frameworks
如果您正在使用,请Carthage
确保您Embed Frameworks
Build Step
在Carthage
copy-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]用于模拟器。
Open
Terminal
open your project drag path of respective framework to Terminal
example :
cd /Users/MAC/Desktop/MyProject/Alamofire.framework
set your Framework name in below command and run
打开
Terminal
打开相应框架的项目拖动路径到终端
例子 :
cd /Users/MAC/Desktop/MyProject/Alamofire.framework
在下面的命令中设置您的框架名称并运行
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
- Now open your project again, Clean, Build & Run and Create Archive...
- 现在再次打开您的项目,清理、构建和运行并创建存档...
回答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 Frameworks
directory as documented by Apple. The only way we have been able to make them work is by pulling the .framekwork
right into the project directory and linking the Embedded Frameworks
and Link Binary with Libraries
manually in Build Settings. This seem to have worked without any issues, however, as with any fat library they come with the extraneous Simulator Architectures i386
and x86_64
along with the arm
architectures.
我将在这里添加我的 2 美分(以一种不那么可怕的方式:-)。我遇到了很多来自供应商的胖库,它们(出于某种原因)通过将它们添加到Frameworks
Apple 记录的目录中而无法正常工作。我们能够使它们工作的唯一方法是将.framekwork
权利拉入项目目录并在构建设置中手动链接Embedded Frameworks
和Link 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 Frameworks
directory. 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_64
architectures from the framework.
现在,这里的所有答案(或至少部分答案)都提供了这些精彩的运行脚本,我确信它们确实可以很好地工作,但前提是您的框架位于该Frameworks
目录中。现在,除非您是 shell 脚本迷,否则那些未经修改的脚本将不适用于我上面解释的场景。但是,有一种非常简单的方法可以摆脱框架中的i386
&x86_64
架构。
- Open terminal in your project's directory.
Change directory directly into the
.framekwork
, likecd YourProjectDir/YourProject/YourLibrary.framework
Run the series of commands as shown below-
- 在项目目录中打开终端。
将目录直接更改为
.framekwork
,例如cd YourProjectDir/YourProject/YourLibrary.framework
运行一系列命令,如下所示 -
$ 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 -remove
has to be done once for each architecture to remove. lipo
does not modify the input file, it only produces a file so you have to run lipo -remove
once for x86_64
and 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 -remove
为x86_64
和运行一次i386
。上面的命令只是通过首先重命名可执行文件,然后最终删除所需的拱形,然后清理剩余的文件来完成此操作。就是这样,您现在应该在 Application Loader Archival 上传到 iTunesConnect 中看到一个绿色的复选标记。
Things to keep in mind: The above steps should only be done while production build, since the .framework
will 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 .framework
file since you want to be able to test on both Simulator and a physical device. If your fat library resides in the Frameworks
folder 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 中,脚本在嵌入后添加到最后。我想我不小心将脚本移到了嵌入式框架之前。
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