Linking against a fat dynamic framework fails in arm64

Hi,
I'm having issues when I try to compile a Swift file and link it against a fat dynamic framework in an arm64 environment. The library is built following the steps in this blog post:

swift build --configuration release --triple arm64-apple-macosx
swift build --configuration release --triple x86_64-apple-macosx
lipo -create -output package .build/arm64-apple-macosx/release/package .build/x86_64-apple-macosx/release/package

The output tha we get from that compilation is 4 files:

  • ProjectDescription.swiftdoc
  • ProjectDescription.swiftmodule
  • ProjectDescription.swiftinterface
  • libProjectDescription.dylib

Then, the compiler command that we use is the following:

/usr/bin/xcrun swift\
  --supress-warnings\
 -I include/search/path\
 -F framework/search/path\
 -L library/search/path
 -lProjectDescription
 -framework ProjectDescription

But it fails with the following error:

The 'swift' command exited with error code 1 and message:
/path/main.swift:1:8: error: module 'ProjectDescription' was created for incompatible target arm64-apple-macosx10.15: /path/to/module/ProjectDescription.swiftmodule
import ProjectDescription
       ^

Do I need any extra argument when compiling the Swift file? Of is it something related to the way the .swiftmodule of the framework is generated?

In the include path, you need to have the swiftmodule for the target you are compiling for. It seems like here you are compiling for x86_64 with the xcrun swift command, but your include path is ending up looking at the arm64 swiftmodule for ProjectDescription. Usually, the swiftmodule is a directory which contains individual swiftmodule files on a per-target basis (but it can also be a file). If you include that directory and it does have individual files for different targets, then it ought to work.

Thanks for the response @Varun_Gandhi. One question that I have regarding the .swiftmodule is how should the files be named inside the directory? Let's say I have the following .swiftomdule s:

.build/arm64-apple-macosx/release/MyFramework.swiftmodule
./build/x86_64-apple-macosx/release/MyFramework.swiftmodule

Should I copy them into a MyFramework.swiftmodule directory following the right naming convention?

Is it something like?

MyFramework.swiftmodule/
  arm64.swiftmodule
  x86_64.swiftmodule

What happens withe the .swiftinterface and .swiftdoc counterparts?

Usually it would use the full "triple" like so:

MyFramework.swiftmodule/
  arm64-apple-macosx.swiftmodule
  x86_64-apple-macosx.swiftmodule
1 Like

thanks for the awesome information.

I've tried the suggested full "triple" and now when I try to compile a Swift file and link it against that framework, I get the following error:

could not find module 'ProjectDescription' for target 'arm64-apple-macos'; found: x86_64-apple-macosx, arm64-apple-macosx
import ProjectDescription
       ^

Note the macos vs macosx difference that seems to be causing the issue. I'm not entirely sure where that is coming from.

Terms of Service

Privacy Policy

Cookie Policy