rrsum
(Rick Summerhill)
1
This is another attempt to find out how to include an x86_64 library in a command line Swift package on an Apple M2 computer. I've asked this before, on both this forum and on the apple developers forum, but got no response. I have written a swift command line program that has worked fine for roughly four years. It is compiled and linked with an foreign x86_64 library. I recently updated my mac to an M2 Mac Mini and now I'd like to update the program, but use the same library. Everything compiles fine, in both Xcode and with Swift on the command line, but it fails to link, reporting that the external library is the wrong architecture. Note that the previously compiled program runs fine even on the M2 computer.
Running:
swift build --arch arm64 --arch x86_64
Results in:
...
100%: Build succeeded
But test says: found architecture 'x86_64', required architecture 'arm64', and then a bunch of undefined symbols. I have no idea what options to use for the test, and especially what to use in Xcode.
I've read through a lot of posts on this issue, but found nothing that helps.
Can someone indicate how this done, from both the command line and from Xcode, or point to the solution. Thanks in advance.
Jon_Shier
(Jon Shier)
2
If the library only works on Intel, you should compile your package only for Intel and have your machine run it under Rosetta.
3 Likes
rrsum
(Rick Summerhill)
3
Okay, I didn't realize that. To test all this, I created a near empty library package that has one test and that simply writes out the string "Hello World". Running 'swift build' and 'swift test' does exactly what one would think - builds the arm64 library and runs the test, printing out "Hello World". Doing 'swift build --arch x86_64' appears to build an x86_64 version of the library, but 'swift test --arch x86_64' appears to build a test version, but executes no test.
So, here are some very specific questions:
- Where is 'swift build --arch x86_64' documented?
- How does one run tests with arch x86_64 on an arm64 computer and where is this documented?
- How does one specify the architecture in Xcode for a package?
- How does one run tests in Xcode with a different architecture for a package?
Sorry if all these are stupid questions and/or well known, but I've done a lot of searching and have found no answers.
Start a new shell under Rosetta and run swift test in that shell:
arch -x86_64 zsh
Alternatively, you can create a copy of your terminal app and run that under Rosetta as described in this Rosetta support document.
eskimo
(Quinn “The Eskimo!”)
5
Alternatively, you can create a copy of your terminal app
That approach no longer works, because modern versions of macOS won’t let you run platform code from non-platform locations. This is why the Finder prevents you from copying Terminal, and you can’t even get around that with ditto:
% sudo ditto /System/Applications/Utilities/Terminal.app Terminal.app
ditto: /Users/quinn/Test/Terminal.app/Contents/_CodeSignature/CodeResources: Operation not permitted
…
This trick does still work for third-party terminal apps.
Share and Enjoy
Quinn “The Eskimo!” @ DTS @ Apple
rrsum
(Rick Summerhill)
6
I'm oppening this topic again - I had to put my project aside for a few months and am now back to it. In the mean time, xcode was updated to 15.4. I now longer see the rosetta option under destinations in xcode, and tests no longer succeed under xcode, although on my intel mac, everything works fine.
To review, I have a library package that imports a foreign x86_64 c library and everything works fine on my intel mac, but not on my M2 mac. How do I compile and test under xcode on the M2 mac?
If there's no x86_64 emulation (Rosetta), I believe there is no way to run x86_64 binary on an Apple Silicon processor. Rosetta was a temporary solution for easier transition from x86_64 to the new different processor architecture. It well may be that Apple has already removed it from macOS (or just removed the option to use it from Xcode, and will remove from macOS later).
Your best option would be to recompile the foreign library from source code, if available.
Jon_Shier
(Jon Shier)
8
On Xcode 15.3+ your best best is to stop relying on Xcode's automatic x86 detection and set your project to build for only the x86 arch, then set your build scheme to allow the project's architecture to override your dependencies architectures. This is a new capability in Xcode 15.3+.
1 Like
rrsum
(Rick Summerhill)
9
I understand this, but how does one build a package for only x86_64 iin xcode?
Jon_Shier
(Jon Shier)
10
Oh, I thought you were in an app or other Xcode target. You can also force the Rosetta options to appear again by going to the Product menu, Destination, Show All Run Destinations. Then the appropriate targets should appear again.
1 Like
rrsum
(Rick Summerhill)
11
That worked, thanks, albeit a bit obscure. 