<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<p style="margin-top:0;margin-bottom:0"></p>
<div><span style="font-size: 12pt;">The last thread wandered off topic pretty quickly, so I'll try this again and be more aggressive in telling people to take off-topic conversations to another thread.</span><br>
</div>
<div><br>
</div>
<div>I would like to find a way for users to decouple the upgrading of tools from the migration to modules.&nbsp; This is not intended as a long term idealized solution, but as a way to ease migration pains.&nbsp; We should also work on the ideal solution, but in parallel
 to the legacy solution.&nbsp; I think this has the potential to make the upgrade from C&#43;&#43;17 to C&#43;&#43;20 roughly the same cost to users as the upgrade from a C&#43;&#43;14 to C&#43;&#43;17.&nbsp; This was discussed some in the impromptu tooling session on Friday at Kona 2019.</div>
<div><br>
</div>
<div>The no-build-system-upgrade constraint implies other constraints:</div>
<div>1. No up-front scanning of the source to find module name and dependency information, because a lot of current build systems don't currently have a scan step.</div>
<div>2. No dynamic dependencies between TUs.&nbsp; Many current build systems assume that the .cpp -&gt; .o[bj] transformation is trivially parallelizable.</div>
<div>3. No upgrade of build tool executables.&nbsp; This has to work with versions of &quot;make&quot;, &quot;ninja&quot;, and &quot;scons&quot; from 10&#43; years ago.</div>
<div>4. You _can_ add compiler / linker flags.</div>
<div><br>
</div>
<div>Some quick notes on this implementation strategy:</div>
<div>* Uses TEXTUAL inclusion</div>
<div>* Compiler assumes that the build system knows nothing of BMIs</div>
<div>* Compiler needs to be able to do module mapping with minimal input from users.</div>
<div><br>
</div>
<div>The scheme I have in mind would result in no build throughput improvements with the old bad build systems, but I think it would still provide the isolation benefits of modules and be conforming.&nbsp; When the user is able to upgrade their build system, they
 can start getting the build throughput improvements.</div>
<div><br>
</div>
<div>The general idea is to treat the module interface file as a glorified header (Gaby has mentioned this possibility in various venues).&nbsp; When the user passes --strawman-slow-modules (or perhaps -frewrite-imports...) to the compiler, the compiler does a textual
 inclusion of the module interface file (no BMI involved at all).&nbsp; The textual inclusion would likely involve placing a #pragma strawman-module begin(name-of-module) directive, with a #pragma strawman-module end(name-of-module) directive at the end of the module
 text.&nbsp; Each TU will duplicate this work.&nbsp; If the compiler can emit this text file, then it can be distributed using existing technologies that are expecting preprocessed files.&nbsp; This is similar in nature to clang's -frewrite-imports.</div>
<div><br>
</div>
<div>So this requires that compilers support this textual modules approach.&nbsp; It also requires that the compiler be able to find the module interface files without requiring the (dumb) build system to scan in advance.&nbsp; The &quot;easiest&quot; (and slow) way to make this
 happen is to require that module names correspond to file names, and that compilers provide a search path.&nbsp; I am well aware that this isn't fast, but this general scheme is intended for build system compatibility.&nbsp; Vendors should also provide a faster thing
 that can be used by newer build systems.&nbsp; Compilers can also provide a command line override to say where a creatively named module can be found.</div>
<div><br>
</div>
<div>Example input:</div>
<div>// ~/all_libs/my_lib/data.cpp</div>
<div>// interface &#43; implementation</div>
<div>export module data;</div>
<div>export int x;</div>
<div><br>
</div>
<div>// ~/all_libs/my_lib/foo.cpp</div>
<div>// interface</div>
<div>export module foo;</div>
<div>import data;</div>
<div>export int func();</div>
<div><br>
</div>
<div>// ~/all_libs/my_lib/foo_impl.cpp</div>
<div>// implementation</div>
<div>module foo;</div>
<div>int func() {return x;};</div>
<div><br>
</div>
<div>// ~/my_exe/bar.cpp</div>
<div>// non-modular</div>
<div>import foo;</div>
<div>int main() {return func();}</div>
<div><br>
</div>
<div>Example invocation 1 (give me object files for all implementations):</div>
<div>my_compiler --strawman-slow-modules -I ~/all_libs/my_lib bar.cpp -o bar.o</div>
<div>my_compiler --strawman-slow-modules -I ~/all_libs/my_lib ~/all_libs/my_lib/foo_impl.cpp -o ~/all_libs/my_lib/foo_impl.o</div>
<div>my_compiler --strawman-slow-modules -I ~/all_libs/my_lib ~/all_libs/my_lib/data.cpp -o ~/all_libs/my_lib/data.o</div>
<div><br>
</div>
<div>Example invocation 2 (give me textually processed files for tooling / distribution):</div>
<div>my_compiler --strawman-slow-modules -E -I ~/all_libs/my_lib bar.cpp -o bar.i</div>
<div>my_compiler --strawman-slow-modules -E -I ~/all_libs/my_lib ~/all_libs/my_lib/foo_impl.cpp -o ~/all_libs/my_lib/foo_impl.i</div>
<div>my_compiler --strawman-slow-modules -E -I ~/all_libs/my_lib ~/all_libs/my_lib/data.cpp -o ~/all_libs/my_lib/data.i</div>
<div><br>
</div>
<div>Example outputs:</div>
<div>// ~/my_exe/bar.i</div>
<div>#pragma strawman-module begin(foo)</div>
<div>export module foo;</div>
<div>#pragma strawman-module begin(data)</div>
<div>export module data;</div>
<div>export int x;</div>
<div>#pragma strawman-module end(data)</div>
<div>export int func();</div>
<div>#pragma strawman-module end(foo)</div>
<div>int main() {return func();}</div>
<div><br>
</div>
<div>//~/all_libs/my_lib/foo_impl.i</div>
<div>module foo;</div>
<div>#pragma strawman-module begin(foo)</div>
<div>export module foo;</div>
<div>#pragma strawman-module begin(data)</div>
<div>export module data;</div>
<div>export int x;</div>
<div>#pragma strawman-module end(data)</div>
<div>export int func();</div>
<div>#pragma strawman-module end(foo)</div>
<div>int func() {return 42;};</div>
<div><br>
</div>
<div>//~/all_libs/my_lib/data.i</div>
<div>export module data;</div>
<div>export int x;</div>
<div><br>
</div>
<div>Users would still need to build each module implementation file (just as they have to build each .cpp today) in order for all symbols to get defined.&nbsp; This might disappoint some people that think that textual modules will provide behavior similar to &quot;unity&quot;
 / &quot;blob&quot; builds.&nbsp; Non-inline function definitions in an imported module wouldn't have object code emitted in importers... the object could would only be provided in the TU that defines that module.</div>
<div><br>
</div>
<div>All of this is intended to allow a fully conforming modules implementation.&nbsp; It also does not preclude additional build options intended for new, smart, fast, build systems.&nbsp; To the contrary, this is an area that I encourage investigation and research.</div>
<div><br>
</div>
<div>Let me know if there are holes in this plan, and if it sounds reasonable to implement.&nbsp; Also let me know if this sounds like it won't help in keeping your existing tool or build system chugging along.</div>
<div><br>
</div>
<br>
<p></p>
</div>
</body>
</html>