<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Nov 12, 2014 at 12:48 PM, Vassil Vassilev <span dir="ltr"><<a href="mailto:vvasilev@cern.ch" target="_blank">vvasilev@cern.ch</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div bgcolor="#FFFFFF" text="#000000"><span class="">
<div>On 11/11/14 04:48, Richard Smith wrote:<br>
</div>
<blockquote type="cite">
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">On Mon, Nov 10, 2014 at 4:00 PM,
Argyrios Kyrtzidis <span dir="ltr"><<a href="mailto:kyrtzidis@apple.com" target="_blank">kyrtzidis@apple.com</a>></span>
wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div style="word-wrap:break-word">
<div>Hi all,</div>
<div><br>
</div>
<div>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. </div>
<br>
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.<br>
</div>
</blockquote>
<div><br>
</div>
<div>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.</div>
<div><br>
</div>
<div>So here's one possibility: allow 'extern module'
declarations to be nested within other modules, then write
your /usr/include module map as:</div>
<div><br>
</div>
<div>module MyModule {</div>
<div> <...></div>
<div> extern module SomethingPrivate
"/usr/local/include/module.private.map"</div>
<div>}</div>
</div>
</div>
</div>
</blockquote></span>
Maybe off topic (sorry if I misunderstood): would that 'somehow'
allow placing a modulemap outside the /usr folder? (For cases like
<span> <em>gcc's libstdc++</em>).</span></div></blockquote><div><br></div><div>There are a few related problems with this. One is that we need to be able to map from a #included file's name to the module map file, if we're loading that module map lazily. Another is that files named in a module map file are found relative to that flie.</div><div><br></div><div>We can solve the first problem with -fmodule-map-file=<libstdc++ module map>. For the second half, I've been discussing with a few people the idea of allowing a module map file to specify a "module root" directory relative to which its files are found, which need not be the directory in which the map is placed. (This also helps with another problem: diagnostics when building or using a module point to files relative to the module map file, which can result in some rather contorted and unnatural paths.)</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div bgcolor="#FFFFFF" text="#000000"><span><span class="HOEnZb"><font color="#888888">
Vassil<br>
</font></span></span>
<blockquote type="cite"><span class="">
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">
<div><br>
</div>
<div>(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.</div>
<div><br>
</div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div style="word-wrap:break-word">We propose to make the
following changes to Clang’s module mechanism:<br>
<br>
- 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.<br>
- 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:<br>
<br>
module MyModule {<br>
<…><br>
}<br>
<br>
while an extension is this:<br>
<br>
module MyModule.SomethingPrivate {<br>
<…><br>
}<br>
<br>
An extension is a nested module with any depth.<br>
We can reuse the “extern module” syntax to indicate that
we are extending a module whose definition is in a
different module map:
<div><br>
</div>
<div>extern module MyModule</div>
<div>module MyModule.SomethingPrivate {<br>
<…><br>
}<br>
</div>
<div><br>
- 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.<br>
<br>
- 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.<br>
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.<br>
<br>
- 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.</div>
<div><br>
</div>
<div>- A module definition inside a private extension
will be disallowed. The rationale is that otherwise <span>it
will be a very common mistake for users to write</span></div>
<div style="margin:0px;min-height:14px"><br>
</div>
<div style="margin:0px"><b>module.modulemap:</b></div>
<div style="margin:0px">module Foo {</div>
<div style="margin:0px"> <public headers></div>
<div style="margin:0px">}</div>
<div style="margin:0px;min-height:14px"><br>
</div>
<div style="margin:0px"><b>module.private.modulemap:</b></div>
<div style="margin:0px">module Foo {</div>
<div style="margin:0px"> <private headers></div>
<div style="margin:0px">}</div>
<div style="margin:0px;min-height:14px"><br>
</div>
<div style="margin:0px">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.</div>
<div style="margin:0px"><br>
</div>
<div style="margin:0px"><br>
</div>
<div style="margin:0px">Let me know what you think!</div>
</div>
</blockquote>
</div>
<br>
</div>
</div>
<br>
<fieldset></fieldset>
<br>
</span><span class=""><pre>_______________________________________________
cfe-dev mailing list
<a href="mailto:cfe-dev@cs.uiuc.edu" target="_blank">cfe-dev@cs.uiuc.edu</a>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a>
</pre>
</span></blockquote>
<br>
</div>
</blockquote></div><br></div></div>