Framework internal ModuleMap leaks to App?

I have a "Objective-C" Framework that is mostly Swift based except for the primary headerfile. Because you cannot use a bridging header within the framework, somewhere I discovered the "trick" of using a "module.modulemap" file to expose some ObjectiveC based interfaces to the Swift code:


module ReachabilityPrivate {
  header "../../ThirdParty/Reachability/Reachability.h"
  export *
}
...


After doing this for a long time, for some reason we find that when "import MyFramework" is exposed to Swift files within the App itself, those files won't complile now due to


error: missing required modules: 'ReachabilityPrivate', ...


My framework has the "Defines Module Maps" set to yes, and neither of the two modulemap files defined in Build Settings. In this case, Xcode creates a modulemap for my framwork:


framework module MyFramework {
  umbrella header "MyFramework.h"

  export *
  module * { export * }
}

module MyFramework.Swift {
    header "MyFramework-Swift.h"
    requires objc
}


I've read the Clang page on modulemaps but I cannot discover the concept of nested modulemaps. Then, not really knowing what I was doing, I tried to play with what appear to be the free variables available to me:


- use a module.modulemap file along with a module.private.modulemap file

- define one or both of the "Module Map File" and "Private Module Map File"

- within a provided "Module Map File", delete the line "module * { export * }", which I guess is the root cause of all my problems

- try various combinations of the above


But, no matter what I try, I now get some form of build error just trying to build the framework making it impossible to see any affect on the primary app.


One of my coworkers has much more experience with modulemaps and he has no suggestions for resolving this - thus my post here!

Replies

There a several known issues with mixing interfaces across languages in a framework, and specifying custom module maps are not a viable workaround. The best course here is to open a bug report with your use case (and please post the bug number back here). The simplest way to work with in this scenario is to put the Swift and Objective-C code in different modules, and let Xcode automatically generate the proper interface.


For some related technical background, see the following Swift.org discussion.

I read your link to the Swift.org discussion - very interesting!


For the record (and for any reader also searching on this), I was able to get everything to build again by doing the following:

- remove the module.modulemap

- create a new file, MyFramework.modulemap

- add that new file to the Build Settings for "Module Map File"

- insure that every file mentioned in that new modulemap file was included in the "Headers" Build Phase (Public and Private)

- use this form for the module map file:


framework module MyFramework {
    umbrella header "MyFramework.h"

    header "SomeProtocol.h"

    export *
    module * { export * }

    explicit module ReachabilityPrivate {
      header "Reachability.h"
      export *
    }
    ...
}


Note that all my source files using "import ReachabilityPrivate" had to be changed to "import MyFramework.ReachabilityPrivate".

A bug report would still be appreciated. I've seen several solutions to this issue break over time, such as your earlier module map definition.

rdar://49607620


The only reason I made this an ObjectiveC framework is that from all I read I needed an umbrella header, which of course has to be Objective C. If there is a published how-to to make a mostly-Swift framework would love to know the URL! [But even if I had done this, I'd still need the modulemap to import a few ObjC classes]

Dear Edford,


As you requested, I did enter a rdar - the number is above.


I just an email - the bug is now closed, and the message below that notification says:


Apple Developer Relations
Your bug report and feedback are appreciated and have been forwarded to the appropriate engineering team.


I'm not quite sure what this means, as in the "old" days a bug stayed open until it was investigated, then either was fixed, was dupped, or was closed as "not a bug".


David


I've also entered a TSI on this issue with DSI (711716269), but no response other than it was received so far.

Hi David,

Thank you for filing the bug. I'm not party to the specific thinking that went into how this specific bug was handled, so I can't comment on that further.


One of my teammates has your TSI, and he and I have been discussing it. You will get a response from us with more detailed discussion of this topic soon.

Dear Ed,


I didn't expect you to give me any more info on the bug, just telling you what I was told! Not a problem!


Regarding the TSI, this is for future use and I am in no hurry for it now. I will if its OK I'll append any info to this ticket for future readers!


Best wishes!

Just for the record, DTS did get back to me through my company's email, but they were switching our system around and so it appears that message was lost (and so DTS did response quickly).

Hi dhoel,


I am compiling my framework including other sub-frameworks. When I got "error: missing required modules: ", I was looking for solution on internet and I found your post.


I followed all your steps. My explicit module is Firebase and it has Firebase.h header file itself. I made sure to include it in "Public Header" of my framework "Base Phases". Following is my modlue map file.


framework module MyFramework {
    umbrella header "MyFramework.h"
    export *
    module * { export * }
       explicit module Firebase {
            header "Firebase.h"
            export *
        }
}


But inside the Firebase.h file, there are other dependencies like "FirebaseCore.h", "FirebaseAnalytics.h", "FirebaseAuth.h" etc. Before I build my framework I also made sure to include that frameworks in "Link Binary With Libraies", "Copy Files" with destination with "Frameworks".


But when I embed my framework to a project, I got "FirebaseCore/FirebaseCore.h" file not found error. Previous was "Firebase" moudule not found error.


May I know do you have any clue for it?


Best Regards,

zaythu