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
.
Modulemap exposes C header files for external binaries. It is a bridge between module and headers. Modulemap helps to convert #include, #import -> @import because it has a mapping between module name and headers inside. Also modulemap helps to create standalone additional modules and submodules.
The umbrella header is the 'master' header file for a framework. Its use is that you can write #import <UIKit/UIKit.h> instead of #import <UIKit/UIViewController.h> #import <UIKit/UILabel.h> #import <UIKit/UIButton.h> #import <UIKit/UIDatePicker.h> and so on.
Module: A set of parts that can be assembled into a structure. To Xcode, that means you can have a group of lines of code that you can (re)use in different places without having to write that code again.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With