[cfe-dev] RFC: Supporting private module maps for non-framework headers

Vassil Vassilev vvasilev at cern.ch
Wed Nov 12 12:48:58 PST 2014


On 11/11/14 04:48, Richard Smith wrote:
> On Mon, Nov 10, 2014 at 4:00 PM, Argyrios Kyrtzidis 
> <kyrtzidis at apple.com <mailto:kyrtzidis at apple.com>> wrote:
>
>     Hi all,
>
>     For frameworks Clang currently supports adding a separate module
>     map file for the private headers of the framework. It looks
>     specifically for the presence of 'module.private.modulemap' inside
>     the .framework and parses both the public and the private module
>     maps when it processes its module. We would like to extend support
>     for private module maps for non-framework headers as well.
>
>     In the Darwin platform, the public SDK headers are located in
>     '/usr/include', while the associated private SDK headers are
>     located in '/usr/local/include'. '/usr/local/include' comes before
>     '/usr/include' in the header search paths.
>
>
> I worry that this will be fragile. If for any reason we look in 
> /usr/include but not in /usr/local/include, we'll not load the private 
> extension map and things will probably go quite badly from that point 
> onwards. If the presence of the /usr/local/include headers is a 
> fundamental part of a /usr/include module, then it seems better to me 
> to specify that within the /usr/include module map.
>
> So here's one possibility: allow 'extern module' declarations to be 
> nested within other modules, then write your /usr/include module map as:
>
> module MyModule {
>   <...>
>   extern module SomethingPrivate "/usr/local/include/module.private.map"
> }
Maybe off topic (sorry if I misunderstood): would that 'somehow' allow 
placing a modulemap outside the /usr folder? (For cases like /gcc's 
libstdc++/).

Vassil
>
> (in addition to the other changes you suggest here). Then only allow a 
> module to be extended if the extension is listed via an 'extern 
> module' in the definition of the module.
>
>     We propose to make the following changes to Clang's module mechanism:
>
>     - When looking up a module through the search paths, in addition
>     to 'module.modulemap' also lookup for a standalone
>     'module.private.modulemap' file. I will refer to this as the
>     "private extension" module map.
>     - When parsing a private extension map allow extending a module
>     that was not defined before, without providing the full
>     definition. To clarify, I refer to a module definition as this:
>
>     module MyModule {
>      <...>
>     }
>
>     while an extension is this:
>
>     module MyModule.SomethingPrivate {
>      <...>
>     }
>
>     An extension is a nested module with any depth.
>     We can reuse the "extern module" syntax to indicate that we are
>     extending a module whose definition is in a different module map:
>
>     extern module MyModule
>     module MyModule.SomethingPrivate {
>      <...>
>     }
>
>     - After parsing the private extension map, we are still missing
>     the module definition so module lookup will continue looking in
>     the following header search paths. If the module we are looking
>     for is not found then Clang will a emit a "module not found" error.
>
>     - It may seem backwards that module search will find and parse the
>     private extension ahead of the public one, but it is actually
>     advantageous because this allows us to continue searching only
>     until we find the module definition, at which point we will stop
>     looking. If module search worked the other way then, after we had
>     the module definition, we would need to always keep looking
>     through the rest of the search paths in case there is a private
>     extension map that we need to take into account, or treat certain
>     paths specially and only look for private extensions in those.
>     By finding the extension map early on, we keep the current
>     semantics of doing the minimal search necessary to find and
>     complete the module definition, without treating any particular
>     search path specially.
>
>     - After Clang finds and parses the public module map for
>     'MyModule', the module definition will be complete. Clang will
>     keep track that there is a private extension map associated with
>     the module and it will pass the paths of both the public module
>     map and the private extension one to the module building
>     invocation. This will result in one module file containing both
>     the public and private APIs, similar to what we do with frameworks.
>
>     - A module definition inside a private extension will be
>     disallowed. The rationale is that otherwise it will be a very
>     common mistake for users to write
>
>     *module.modulemap:*
>     module Foo {
>       <public headers>
>     }
>
>     *module.private.modulemap:*
>     module Foo {
>       <private headers>
>     }
>
>     and then be left scratching their heads wondering why things are
>     broken (things missing, headers included textually, etc.). Being
>     more strict in private extension maps will be beneficial.
>
>
>     Let me know what you think!
>
>
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20141112/7c6ad0fe/attachment.html>


More information about the cfe-dev mailing list