Swift package with foreign x86_64 library

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.

If the library only works on Intel, you should compile your package only for Intel and have your machine run it under Rosetta.

2 Likes

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:

  1. Where is 'swift build --arch x86_64' documented?
  2. How does one run tests with arch x86_64 on an arm64 computer and where is this documented?
  3. How does one specify the architecture in Xcode for a package?
  4. 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.

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