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

Richard Smith richard at metafoo.co.uk
Tue Nov 11 19:38:23 PST 2014


On Tue, Nov 11, 2014 at 6:49 PM, Argyrios Kyrtzidis <kyrtzidis at apple.com>
wrote:

>
> On Nov 11, 2014, at 6:37 PM, Richard Smith <richard at metafoo.co.uk> wrote:
>
> On Tue, Nov 11, 2014 at 3:45 PM, Argyrios Kyrtzidis <kyrtzidis at apple.com>
> wrote:
>
>>
>> On Nov 11, 2014, at 12:34 PM, Richard Smith <richard at metafoo.co.uk>
>> wrote:
>>
>> On Tue, Nov 11, 2014 at 10:00 AM, Argyrios Kyrtzidis <kyrtzidis at apple.com
>> > wrote:
>>
>>>
>>> On Nov 10, 2014, at 7:48 PM, Richard Smith <richard at metafoo.co.uk>
>>> wrote:
>>>
>>> On Mon, Nov 10, 2014 at 4:00 PM, Argyrios Kyrtzidis <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"
>>> }
>>>
>>>
>>> This has drawbacks:
>>>
>>> - Details of the private SDK, “leak out” to the public one. It should
>>> work similar to frameworks, in that the public SDK remains the same
>>> irrespective if there is or not a private API, and the private API is a
>>> straight addition on top of the public one without needing to modify
>>> something in the public SDK.
>>> - It is a bit weak as guarantee anyway because the public module map
>>> must necessarily function even when the extension map is missing, which
>>> means pointing at the wrong path or missing the private map when you really
>>> need it will not be detected.
>>> - Flexibility to extend a module from any path may be valuable for
>>> testing.
>>>
>>
>> OK, I'm not sure I understand what problem you're solving. If the
>> /usr/local/include stuff works as a layer on top of /usr/include, why do
>> you need them to be built as part of the same module? (Do your
>> /usr/local/include headers override / #include_next some of the
>> /usr/include headers, perhaps? If so, do you need the #includes in
>> /usr/include to find the /usr/local/include headers rather than the
>> /usr/include headers?)
>>
>>
>> There are some cases of cycles between public/private headers which would
>> be accommodated by a single module build but the primary motivation is that
>> we would like the module public/private interface to be under the same
>> namespace, so you’d do
>>
>> @import Dispatch;
>> @import Dispatch.Private;
>>
>> @import Darwin.POSIX.Foo.Bar;
>> @import Darwin.POSIX.Foo.Bar.Private;
>>
>> and generally any kind of private extension:
>>
>> @import Dispatch.SuperCoolButPrivate;
>>
>
> Do you want / need them to be built as a single module file, or not?
>
>
> As I said, cycles may make things difficult for separate module files, but
> how are we going to get new submodules under the same module name with
> separate module files ?
>

Well, the restriction that module files correspond to top-level module
names is arbitrary and artificial. (It's also a bad idea for a few reasons.
It makes incremental refactoring very hard, for instance, because you're
required to have no cycles at any point between things in different
top-level modules.)

Splitting up the description of how to build a module file across various
module maps seems like a very error-prone strategy, especially if you're
intending to be able to stop looking before you've read all of the relevant
module maps.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20141111/0da3890f/attachment.html>


More information about the cfe-dev mailing list