iosmodule-map

Are "link framework" lines necessary in a modulemap file?


Some framework files come with a module.modulemap that contain "link framework" lines. For example, here is the current content of Intercom's module.modulemap file:

framework module Intercom {
  umbrella header "Intercom.h"

  [...]

  link framework "Foundation"
  link framework "UIKit"
  link framework "Accelerate"
  [...]
}

I wanted to find out why the link framework lines are necessary, so I tried to create a new project for a framework target using on Xcode 10.2, but regardless of what I do, it seems like the module.modulemap file will simply be untouched (which is understandable, it seems like this file is meant to be manually modified).

What I want to know is, why is this necessary in the first place? The blame info + corresponding release notes seem to suggest that said lines were added to fix issues with dynamic frameworks and duplicate symbols, but not much more.


Solution

  • There are two ways to make a Objective-C framework be usable inside an swift project:

    1) Letting Xcode automatically create the module.modulemap file, which is the default option when you start a new framework project:

    Defines Module option

    So, when you compile the project, this file is generated with the default configuration:

    framework module MODULE_NAME {
      umbrella header "MODULE_NAME-umbrella.h"
    
      export *
      module * { export * }
    }
    

    And usually is enough for most of the projects.

    2) Manually generating the file, which is your project case.

    Acording with the CLANG's modulemap documentation:

    A link-declaration specifies a library or framework against which a program should be linked if the enclosing module is imported in any translation unit in that program.

    Link declarations within module maps are intended to be a hint to the toolchain what is the actual binary that contains the code of the module. Without this explicit definition, importing the framework on the main project may cause errors due the need of those source frameworks, mostly no such module error.

    So, if you have a swift project with the dynamic framework dependencies, and one of them has the same dependency list of your example framework, if you remove the explicit declaration from the .modulemap file, you will probably see the duplicate symbols error.

    For more information, I recommend this Apple thread response.