Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Private module map for a framework

Tags:

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.

like image 966
Rich Avatar asked Dec 14 '15 11:12

Rich


People also ask

What is a module map?

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.

What is an umbrella header?

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.

What are modules in Xcode?

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.


1 Answers

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.

like image 74
tmpz Avatar answered Sep 29 '22 04:09

tmpz