Cycle in dependency when adding `module.modulemap`

I have a static library, C, with mix of obj-c and Swift code in it. My main app, target A references this library. There are many other dependencies and static libraries also in the project. Since I added module.modulemap file to my static library project so I can use it in Swift code in my main app, the project build fails with following error message:

error: Cycle in dependencies between targets 'A' and 'C'; building could produce unreliable results. This usually can be resolved by moving the target's Headers build phase before Compile Sources.
Cycle path: A → B → C → A
Cycle details:
→ Target 'A' has target dependency on Target 'B'
→ Target 'B' has compile command for Swift source files
→ Target 'C' has copy command from 'path_to_project/Resources/module.modulemap' to 'path_to_build_folder/Build/Products/Debug-iphonesimulator/include/{ProjectName}/module.modulemap'
○ Target 'C' has compile command with input 'path_to_target_C/{ProjectName}/Somefile.mm'
○ Target 'C' has compile command for Swift source files

It seems it's due to the new modulemap file and the copy phase that I added to my static library, but can't tell why that copy phase is adding a dependency cycle. Specifically, why there's a dependency between the static library and the app?

I have followed steps mentioned in swift-static-library-in-objective-c for adding this support.

Thanks in advance.

1 Like

Did you ever find a solusion to this?

@alexpell00 Not for this specific error, still trying to figure out why adding mobulemap copy causes this error message and the root cause. But if you're getting cycle in dependencies error message, https://help.apple.com/xcode/mac/current/#/dev621201fb0 has a good write-up on how to debug and steps to take. The error message is different for each case so just look for that.

There's no silver bullet solution for this issue. Based on my experience, following steps have helped to fix some of these

  • Use framework / library to share code between your app and your extensions instead of adding the same files to both targets
  • Read the error message and try to see what those targets having in common. Are all dependencies taken care of properly?
  • Check if a same file exists in both projects Compile Source
1 Like

@alexpell00 Also, forgot to mention, try to move the modulemap copy phase above below Dependencies and above Compile Sources.

1YxDg

That helped with one case of cycles in dependencies.

@maniramezan Thanks for the replies! I finally found the issue last night, one of my frameworks was being built with an objc bridging header. Removing the bridging header and using a proper public framework header did the trick.

I didn't think frameworks were allowed to have bridging headers, so I'm not sure how I was able to build it. I still need to explore that a bit more.

1 Like

Still having this issue with different permutations of the error message, none of which makes much sense and are helpful to get to the root cause. The current version is:

error: Cycle in dependencies between targets 'DynamicFrameworkWithObjcAndSwift' and 'StaticLibrary'; building could produce unreliable results.
Cycle path: DynamicFrameworkWithObjcAndSwift → StaticLibrary → DynamicFrameworkWithObjcAndSwift
Cycle details:
→ Target 'DynamicFrameworkWithObjcAndSwift' has link command with output 'path_to_deriveddata/Debug-iphonesimulator/DynamicFramework.framework/DynamicFramework'
○ Target 'DynamicFrameworkWithObjcAndSwift' has compile command with input 'path_to/Frameworks/DynamicFrameworkWithObjcAndSwift/Apple/DynamicFramework/TheOnyObjcCFile.m'
○ Target 'DynamicFrameworkWithObjcAndSwift' has compile command for Swift source files
→ Target 'StaticLibrary' has copy command from 'path_to/StaticFrameworkResources/module.modulemap' to 'path_to_deriveddata/Debug-iphonesimulator/include/StaticFramework/module.modulemap'
○ Target 'StaticLibrary' has target dependency on Target 'DynamicFrameworkWithObjcAndSwift'

Was wondering if there's a way to grab more information from compiler / build system regarding what is causing the cycle in dependencies? For example, in this case, there's no link between the dynamic framework and static framework. The dynamic framework is a simple class with one .m and one .swift file with some private headers. And this issue has started happening after .modulemap has been added. So my assumption is something between copying .modulemap for the static library dosn't sit well with creation of dynamic framework which itself also has .modulemap file in its .framework structure.

For anybody reading this thread later, for this issue, moving away from using static library and replacing it with static framework which removes the requirement for having a modulemap file and manually copying it into destination folder solves the issue in our case.

1 Like