I have created a tool to deal with Xcode's "building for iOS Simulator, but linking ..." error.


Hi, this is arasan01 (@arasan01_me). I installed a branch faucet in my dishwasher and it's so comfortable that I eat fried food more often.

What we made.

When using Xcode on an Apple Silicon Mac (M1 Mac) to build a project for the actual device and for the simulator, the build succeeds for the actual device, but when building for the simulator, it says "building for iOS Simulator, but linking in object file built for iOS, for architecture arm64" error. This is because the library used internally is not compatible with Simulator, which is used by Apple Silicon Mac's Xcode.

Specifically, Xcode and Simulator run on x86_64 architecture on Xcode running on Rosetta2 as well as on Intel Macs, whereas Xcode and Simulator run on arm64 architecture on Apple Silicon Macs in the normal boot method architecture. If you look at the libraries used internally, the above error occurs when there is an arm64 build for the machine and an x86_64 build for the simulator included in the package. On the other hand, normal startup fails because the arm64 simulator build cannot be found.

The way to deal with this is to prepare a build for the arm64 simulator, but this is quite difficult. If a pre-built library exists as a dependency of some tool, it must be made into an arm64 simulator build. The workflow so far has been to bundle the arm64 builds with the x86_64 simulator builds, but it is not possible to bundle the arm64 builds with the arm64 simulator builds; you must use the xcframework to do this. If the source code exists, you can create a build for the arm64 simulator on your own, but if not, you must ask the build source to provide a build for the simulator as well. When using this library, you need to rearrange your workflow so that you see one of the two libraries each time you select one for the simulator and one for the actual device, or you need to ask the provider to provide xcframwork and incorporate it into your project.

In contrast, tools existed to generate xcframework from frameworks. However, it is complicated because it requires rearrangement of the workflow. Therefore, we created a tool that can dynamically select the library itself.

To use it, simply write the binary you want to switch between builds for the arm64 simulator and builds for the real machine in a configuration file and add it to the Build Phase Script of your project. The configuration file must specify whether the binary is a static link or a dynamic link. You can use file -b <binary path> to check. If you have a mixture of architectures, you will see various results, but the following should be included.

$ file -b StaticBinary current ar archive random library $ file -b DynamicBinary Mach-O 64-bit dynamically linked shared library arm64 $ lipo -archs StaticBinary arm64 $ lipo -archs DynamicBinary arm64

When you use it, please use the build in Mint or SwiftPM.

For use Mint

$ mint install dmm-com/Ranasa@0.1.5 $ mint run dmm-com/Ranasa@0.1.5 <command argument>

For self-build (can be moved to any location as it will be a single binary after build)

$ git clone https://github.com/dmm-com/ranasa; cd ranasa; swift build -c release $ .build/release/ranasa <command argument>

The tool uses json files to manage which binaries to target. In this case, the Framework is placed at the top of the project, so it is described as follows.

[ { "linking": "dynamic", "path": "DynamicLib/DynamicBin" }, { "linking": "static", "path": "StaticLib/StaticBin" }, ]

Write the code that calls ranasa in the Build Phase Script.

  • The -s option can be used to specify where to store the automatically generated simulator builds and the builds for the real machine.
  • By using the -x option in the Build Phase Script, ranasa will automatically determine whether it is a simulator build or a build for the actual machine and select the most appropriate build.
  • The -v option outputs a detailed log. It does not affect the operation.

For more detailed options, see the help of the command or refer to the README of the repository.

ranasa/.build/release/ranasa -s .ranasa -x -v arm64sim.json

Conclusion

I think it would be good to try to use it so that it can be freely forked and used for projects, although it may fail if swiftmodule is present, or its behavior may be unstable sometimes, or various other problems. I have confirmed that it works normally with Static Library, but other than that, I didn't have any particular goal to use it, so I may not have debugged it enough.

Popular posts from this blog

I am preparing to become more active in personal activities.

How to start developing Flutter for windows plug-ins using the Win32 API