Private module map for a framework

Rich picture Rich · Dec 14, 2015 · Viewed 17k times · Source

I'm using this answer to create a module map to create a module for CommonCrypto so I can use it in a framework.

Doing this however means that any projects that I use this framework in have access to CommonCrypto with import CommonCrypto - and even worse, declaring CommonCrypto in another framework and importing this into the project results in Redefinition of module 'CommonCrypto' errors.

I.e. the following setup:

MainProject
    |--> import FrameworkA - module map for CommonCrypto
    |--> import FrameworkB - module map for CommonCrypto

Is there a way to create a module map but have it private to that Framework its created/used in? (Much like the internal access attribute in Swift for a Framework). The llvm Clang docs show a private attribute but I can't work out where to put this in my module map, and it might not even be for this purpose! There's also an export attribute but again I'm not entirely sure how to use this...!

This is my module map I'm using for CommonCrypto - the $(SDKROOT) gets swapped out in a build phase to the correct location (for iphoneos or iphonesimulator SDKs):

module CommonCrypto [system] [extern_c] {
    umbrella header "$(SDKROOT)/usr/include/CommonCrypto/CommonCrypto.h"
    export *
}

This works fine (except you can't "go to definition" but I don't mind that) for use in FrameworkA / FrameworkB.

Answer

tmpz picture tmpz · Feb 3, 2016

Disclaimer: I have not tried this for CommonCrypto but it works for my case with libz

A possible solution to this is to create a module.private.modulemap as described in the Clang documentation

So for example in FrameworkA you can write a module.modulemap file for FrameworkA like so:

module FrameworkACommon {
}

Then you would create a module.private.modulemap file like so

explicit  FrameworkACommon.Crypto [system] [extern_c] {
   header "/Applications/Xcode6-Beta5.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.0.sdk/usr/include/CommonCrypto/CommonCrypto.h"
    link "CommonCrypto"
    export *
}

Then repeat for FrameworkB.

Now CommonCrypto is a private module in both FrameworkA and FrameworkB and the names won't clash.