{"id":28553,"date":"2021-08-10T17:23:41","date_gmt":"2021-08-10T17:23:41","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cppblog\/?p=28553"},"modified":"2021-08-10T17:38:04","modified_gmt":"2021-08-10T17:38:04","slug":"moving-a-project-to-cpp-named-modules","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/moving-a-project-to-cpp-named-modules\/","title":{"rendered":"Moving a project to C++ named Modules"},"content":{"rendered":"<p>There is a lot of hype (and perhaps restraint) to using modules in projects. The general blocker tends to be build support, but even with good build support there is a distinct lack of useful resources for practices around moving projects to using named modules (not just header units). In this blog we will take a small project I created, analyze its components, draft up a plan for modularizing it, and execute that plan.<\/p>\n<h2>Overview<\/h2>\n<ul>\n<li><a href=\"#tools-used\">Tools used.<\/a><\/li>\n<li><a href=\"#project-description\">Project description.<\/a><\/li>\n<li><a href=\"#cpp-today\">Ball Pit! in C++ without modules.<\/a><\/li>\n<li><a href=\"#ungluing\">Ungluing from <code>#include<\/code><\/a>\n<ul>\n<li><a href=\"#starting-small\">Starting small&#8230;<\/a><\/li>\n<li><a href=\"#visibility\">Choosing visibility<\/a><\/li>\n<li><a href=\"#3rd-party-pain\">3rd party pain.<\/a><\/li>\n<li><a href=\"#polish\">Polishing with modules.<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#all-together\">All together now.<\/a><\/li>\n<\/ul>\n<h4><span id=\"tools-used\">Tools used<\/span><\/h4>\n<p>For the purposes of this project, we will be using the following tools:<\/p>\n<ul>\n<li>CMake &#8211; Version: <code>3.20.21032501-MSVC_2<\/code>. <em>Note:<\/em> this is the installed version of CMake which comes with Visual Studio 2019.<\/li>\n<li>Visual Studio 2019 &#8211; Version: <code>16.11<\/code>.<\/li>\n<\/ul>\n<h4><span id=\"project-description\">Project description<\/span><\/h4>\n<p>I remember when I was younger, I used to love doing kid things like eating terrible fast food, but going to these restaurants had an additional perk: the play places! One of my favorite things to do was go to the ball pit, dive in, and make a giant splash of color.<\/p>\n<p><a style=\"display: block; margin-left: auto; margin-right: auto; width: 50%;\" title=\"Rachmaninoff, CC BY-SA 4.0 &lt;https:\/\/creativecommons.org\/licenses\/by-sa\/4.0&gt;, via Wikimedia Commons\" href=\"https:\/\/commons.wikimedia.org\/wiki\/File:Ball_pit_with_playground_slide.jpg\"><img decoding=\"async\" src=\"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/3\/3b\/Ball_pit_with_playground_slide.jpg\/512px-Ball_pit_with_playground_slide.jpg\" alt=\"Ball pit with playground slide\" width=\"512\" \/><\/a><\/p>\n<p>I shudder to think of going into one nowadays, but I have not forgotten how much fun they were. I have also recently become very inspired by OneLoneCoder on YouTube and his <a href=\"https:\/\/www.youtube.com\/watch?v=LPzyNOHY3A4\">series on programming simple physics engines<\/a>. I decided I would try to take this simple physics engine and make something a little bit fun and a lot more colorful, introducing &#8220;Ball Pit!&#8221;:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2021\/08\/ball-pit.gif\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-28558\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2021\/08\/ball-pit.gif\" alt=\"Image ball pit\" width=\"320\" height=\"240\" \/><\/a><\/p>\n<p>&#8220;Ball Pit!&#8221; is a quite simple program built using the following discrete components:<\/p>\n<ul>\n<li>OneLoneCoder <a href=\"https:\/\/github.com\/OneLoneCoder\/olcPixelGameEngine\">PixelGameEngine<\/a> (PGE) &#8211; Drives graphics.<\/li>\n<li>A simple physics engine for managing all the objects on screen.<\/li>\n<li>A data structure related to handling collisions between objects, a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Quadtree\">quad-tree<\/a>.<\/li>\n<li>A world object to contain our beautiful orbs.<\/li>\n<li>Utilities such as common types and functions on those types.<\/li>\n<li>The main game object which is responsible for the primary game loop and polling user input.<\/li>\n<\/ul>\n<h4><span id=\"cpp-today\">Ball Pit! in C++ without modules<\/span><\/h4>\n<p>Since we established a basic design layout in the previous section, let us see what we can produce using C++20 without any modules whatsoever. Without further ado, here is the code in all its <code>#include<\/code> glory: <a href=\"https:\/\/github.com\/cdacamar\/ball_pit\/tree\/ce90e45245bf7981fd797d992389693bdd586c0b\">Ball Pit! Without modules<\/a>. The easiest way to build this project is to\u00a0 use <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/build\/open-folder-projects-cpp?view=msvc-160\">Visual Studio&#8217;s open folder<\/a> support.<\/p>\n<p>Alternatively you can do the following (in a VS2019 developer command prompt):<\/p>\n<pre>$ mkdir build &amp; cd build &amp; cmake -G\"Visual Studio 16 2019\" -Ax64 ..\\<\/pre>\n<p>Once CMake has generated the solution for you can open it using Visual Studio 2019, use the familiar F5 loop and off you go!<\/p>\n<h5>Traditional C++ Structure<\/h5>\n<p>Let us talk briefly about the traditional project structure of this code. We have the following, familiar, breakdown:<\/p>\n<pre>ball_pit\/\r\n\u251c\u2500 include\/\r\n\u251c\u2500 src\/<\/pre>\n<p>As you might expect the <code>include\/<\/code> directory is almost a mirror of some files under <code>src\/<\/code>. You also end up with a sizeable set of includes in our primary <code>ball-pit.cpp<\/code> to pull all the pieces together:<\/p>\n<pre>#include \"bridges\/pge-bridge.h\"\r\n\r\n#include \"physics\/physics-ball.h\"\r\n#include \"physics\/physics-engine.h\"\r\n#include \"physics\/quad-tree.h\"\r\n#include \"util\/basic-types.h\"\r\n#include \"util\/enum-utils.h\"\r\n#include \"util\/random-generator.h\"\r\n#include \"world\/world.h\"<\/pre>\n<p>You might notice that these includes directly reflect the design we set out to have:<\/p>\n<ul>\n<li>PGE for graphics: <code>\"bridges\/pge-bridge.h\"<\/code><\/li>\n<li>Physics engine: <code>\"physics\/physics-engine.h\"<\/code><\/li>\n<li>Quad-tree: <code>\"physics\/quad-tree.h\"<\/code><\/li>\n<li>World object: <code>\"world\/world.h\"<\/code><\/li>\n<li>Utilities: <code>\"util\/*<\/code><\/li>\n<li>Main game: (the current source file: <a href=\"https:\/\/github.com\/cdacamar\/ball_pit\/blob\/ce90e45245bf7981fd797d992389693bdd586c0b\/src\/ball-pit.cpp\"><code>ball-pit.cpp<\/code><\/a>)<\/li>\n<\/ul>\n<p>Since we made the decision to use header files you will notice that we get some declarations like this:<\/p>\n<pre>inline RandomNumberGenerator&amp; random_generator()<\/pre>\n<p>Where there is a strong desire not to implement this simple function in its own <code>.cpp<\/code> file for simplicity&#8217;s sake, but if you forget the critical <code>inline<\/code> keyword or, even worse, mark it as <code>static<\/code> you will not get the behavior you expect from this function.<\/p>\n<p>Another thing which I like to do on my projects is separate 3rd party headers from the rest of the project using these &#8220;bridge&#8221; header files. The reason is so that I can easily control warning suppression\/isolated requirements for that header. The PGE header is isolated into its own bridge called <a href=\"https:\/\/github.com\/cdacamar\/ball_pit\/blob\/ce90e45245bf7981fd797d992389693bdd586c0b\/include\/bridges\/pge-bridge.h\"><code>pge-bridge.h<\/code><\/a>.<\/p>\n<p>Finally, for projects which utilize <code>#include<\/code> as a code sharing mechanism, I like to employ the idea that each header file should stand completely on its own, meaning that if a header uses something like <code>std::vector<\/code> it cannot rely on that container being introduced through some other header, it must include it itself. This is good practice; it makes maintaining headers minimal as you move them around and use them in more places.<\/p>\n<h4><span id=\"ungluing\">Ungluing from <code>#include<\/code><\/span><\/h4>\n<p>At the beginning it was mentioned that we are using CMake as our configuration system but, as of publishing, CMake&#8217;s support for modules is still experimental. What we <em>can<\/em> do is generate build system output for a build system which <em>does<\/em> support modules: MSBuild&#8217;s! All we need to do is tell MSBuild that there are module interfaces in this project and &#8220;Presto!&#8221; we have a modules-compatible project! By default, MSBuild will key off any source files with a <code>.ixx<\/code> extension to automatically support named modules\u2014exactly what we want! Now, how do we get there?<\/p>\n<p>If we examine the <code>include\/<\/code> tree we get a surprisingly promising idea of what module interfaces we need:<\/p>\n<pre>ball_pit\/\r\n\u251c\u2500 include\/\r\n\u2502  \u251c\u2500 bridges\/\r\n\u2502  \u2502  \u251c\u2500 pge-bridge.h\r\n\u2502  \u251c\u2500 physics\/\r\n\u2502  \u2502  \u251c\u2500 physics-ball.h\r\n\u2502  \u2502  \u251c\u2500 physics-engine.h\r\n\u2502  \u2502  \u251c\u2500 physics-utils.h\r\n\u2502  \u2502  \u251c\u2500 quad-tree.h\r\n\u2502  \u251c\u2500 util\/\r\n\u2502  \u2502  \u251c\u2500 basic-types.h\r\n\u2502  \u2502  \u251c\u2500 enum-utils.h\r\n\u2502  \u2502  \u251c\u2500 random-generator.h\r\n\u2502  \u2502  \u251c\u2500 stopwatch.h\r\n\u2502  \u251c\u2500 world\/\r\n\u2502  \u2502  \u251c\u2500 world.h<\/pre>\n<p>It is common for mature projects to have a similar structure and breakdown of components and it makes sense for maintainability reasons. As a goal for modularizing this project let us aim to remove the entire directory tree of <code>include\/<\/code> and take advantage of modules as much as possible. Let us do exactly that by introducing some new files into the directory tree which reflects our header file layout (making them empty for now):<\/p>\n<pre>ball_pit\/\r\n\u251c\u2500 modules\/\r\n\u2502  \u251c\u2500 bridges\/\r\n\u2502  \u2502  \u251c\u2500 pge-bridge.ixx\r\n\u2502  \u251c\u2500 physics\/\r\n\u2502  \u2502  \u251c\u2500 physics-ball.ixx\r\n\u2502  \u2502  \u251c\u2500 physics-engine.ixx\r\n\u2502  \u2502  \u251c\u2500 physics-utils.ixx\r\n\u2502  \u2502  \u251c\u2500 quad-tree.ixx\r\n\u2502  \u251c\u2500 util\/\r\n\u2502  \u2502  \u251c\u2500 basic-types.ixx\r\n\u2502  \u2502  \u251c\u2500 enum-utils.ixx\r\n\u2502  \u2502  \u251c\u2500 random-generator.ixx\r\n\u2502  \u2502  \u251c\u2500 stopwatch.ixx\r\n\u2502  \u251c\u2500 world\/\r\n\u2502  \u2502  \u251c\u2500 world.ixx<\/pre>\n<p>Now the process of moving everything over to using modules begins!<\/p>\n<h5><span id=\"starting-small\">Starting small&#8230;<\/span><\/h5>\n<p>When tackling a project of any size you want to start as small as you possibly can. In the case of &#8220;Ball Pit!&#8221; I started with <a href=\"https:\/\/github.com\/cdacamar\/ball_pit\/blob\/ce90e45245bf7981fd797d992389693bdd586c0b\/include\/util\/enum-utils.h\"><code>include\/util\/enum-utils.ixx<\/code><\/a> because it did not depend on anything besides a STL header. The first thing you need to do is add the content to your module interface:<\/p>\n<pre>module;\r\n#include &lt;type_traits&gt;\r\nexport module Util.EnumUtils;\r\n\r\ntemplate &lt;typename T&gt;\r\nconcept Enum = std::is_enum_v&lt;T&gt;;\r\n\r\ntemplate &lt;Enum E&gt;\r\nusing PrimitiveType = std::underlying_type_t&lt;E&gt;;\r\n\r\ntemplate &lt;Enum E&gt;\r\nconstexpr auto rep(E e) { return PrimitiveType&lt;E&gt;(e); }<\/pre>\n<p>This is <em>almost<\/em> a 1-to-1 copy-paste of the header but with the following exceptions:<\/p>\n<ul>\n<li>Our STL headers are injected into the <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/cpp\/modules-cpp?view=msvc-160#modules-and-header-files\">global module fragment<\/a> (the region between <code>module;<\/code> and <code>export module ...)<\/code>.<\/li>\n<li>We have given a proper name to our module: <code>Util.EnumUtils<\/code>. <em>Note:<\/em> the <code>.<\/code> separated names do not indicate any filesystem structure.<\/li>\n<li>We no longer need header include guards.<\/li>\n<\/ul>\n<p>There is one last thing missing: we did not actually export anything! Since all these names are used around the project, we need to export everything, and the easiest way to export lots of declarations at once is to use the <code>export { ... }<\/code> syntax. Take a look:<\/p>\n<pre>module;\r\n#include &lt;type_traits&gt;\r\nexport module Util.EnumUtils;\r\n\r\nexport\r\n{\r\n\r\ntemplate &lt;typename T&gt;\r\nconcept Enum = std::is_enum_v&lt;T&gt;;\r\n\r\ntemplate &lt;Enum E&gt;\r\nusing PrimitiveType = std::underlying_type_t&lt;E&gt;;\r\n\r\ntemplate &lt;Enum E&gt;\r\nconstexpr auto rep(E e) { return PrimitiveType&lt;E&gt;(e); }\r\n\r\n} \/\/ export<\/pre>\n<p>The next logical step for us is to replace any instance of <code>#include \"util\/enum-utils.h\"<\/code> with <code>import Util.EnumUtils;<\/code>. This part is largely mechanical and to play off <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/cpp\/import-export-module?view=msvc-160#import\">guidance around mixing <code>import<\/code> and <code>#include<\/code><\/a> I ensured to place any <code>import<\/code> after any <code>#include<\/code>&#8216;s. Finally, we add this new interface to the <code>CMakeLists.txt<\/code> <a href=\"https:\/\/github.com\/cdacamar\/ball_pit\/blob\/ce90e45245bf7981fd797d992389693bdd586c0b\/CMakeLists.txt#L27\">here<\/a>, configure, build and run again. Things should run the same as before except that we are one step closer to modularizing the project!<\/p>\n<h5><span id=\"visibility\">Choosing visibility<\/span><\/h5>\n<p>Named modules are all about defining the surface area of your API. Now that we have a tool which allows us to hide implementation details that would otherwise be unnecessary for consumers, we can start to think about what the accessible parts of the API should be. Let us look at modularizing <a href=\"https:\/\/github.com\/cdacamar\/ball_pit\/blob\/ce90e45245bf7981fd797d992389693bdd586c0b\/include\/util\/random-generator.h\"><code>include\/util\/random-generator.h<\/code><\/a>. In this file we have the following declarations:<\/p>\n<pre>enum class RandomSeed : decltype(std::random_device{}()) { };\r\n\r\ntemplate &lt;std::integral I&gt;\r\nusing IntDistribution = std::uniform_int_distribution&lt;I&gt;;\r\n\r\ntemplate &lt;std::floating_point I&gt;\r\nusing RealDistribution = std::uniform_real_distribution&lt;I&gt;;\r\n\r\nclass RandomNumberGenerator\r\n{\r\n   ...\r\n};\r\n\r\ninline RandomNumberGenerator&amp; random_generator()\r\n{\r\n   ...\r\n}<\/pre>\n<p>Of these declarations the ones we use outside of the header are <code>IntDistribution<\/code>, <code>RealDistribution<\/code>, and <code>random_generator()<\/code> (not even the class name directly). As such we can define the module like so:<\/p>\n<pre>export module Util.RandomGenerator;\r\n\r\nimport Util.EnumUtils;\r\n\r\nenum class RandomSeed : decltype(std::random_device{}()) { };\r\n\r\nexport\r\ntemplate &lt;std::integral I&gt;\r\nusing IntDistribution = std::uniform_int_distribution&lt;I&gt;;\r\n\r\nexport\r\ntemplate &lt;std::floating_point I&gt;\r\nusing RealDistribution = std::uniform_real_distribution&lt;I&gt;;\r\n\r\nclass RandomNumberGenerator\r\n{\r\n    ...\r\n};\r\n\r\nexport\r\nRandomNumberGenerator&amp; random_generator()\r\n{\r\n    ...\r\n}<\/pre>\n<p>Notice that we do not even need to export the declaration of the class <code>RandomNumberGenerator<\/code>. We do not need its name; we only need its functionality, and we can prevent users from creating extra instances of it by allowing its use through <code>random_generator()<\/code> only.<\/p>\n<p>Furthermore, we no longer need <code>random_generator()<\/code> to be marked as <code>inline<\/code> because there is now only one definition in any given translation unit. Do not be afraid to put compiled code in an interface, it is its own translation unit and obeys the rules of compiled code.<\/p>\n<h5><span id=\"3rd-party-pain\">3rd party pain<\/span><\/h5>\n<p>In C++ we deal with sharing code all the time and a lot of the time that code has a distinctive style, compiler requirements, default warning settings, etc. When we move code into a modules world, and in particular 3rd party code, we need to take some things into consideration: what part of the library do we want to expose? What runtime requirements are in the library if it is header only? Do we want to &#8220;seal&#8221; off bad parts of the library? With modules we start to have answers to these questions based on the requirements of our project. Integrating 3rd party library functionality into modularized projects is one of the most interesting parts of using modules because modules give us tools we never had before to deal with ODR (One Definition Rule) and name resolution. In this section we will focus on modularizing the <a href=\"https:\/\/github.com\/cdacamar\/ball_pit\/blob\/ce90e45245bf7981fd797d992389693bdd586c0b\/include\/bridges\/pge-bridge.h\"><code>include\/bridges\/pge-bridge.h<\/code><\/a>.<\/p>\n<p>The OneLoneCoder PixelGameEngine is a nice library if you are just starting out exploring games programming. It is easy to integrate into projects (because it is a single header file) and the interfaces are simple&#8211;which plays to our advantage in deciding what parts of the library we want to expose. In &#8220;Ball Pit!&#8221; we use the following functionality from PGE:<\/p>\n<ul>\n<li><code>olc::PixelGameEngine<\/code> &#8212; For the main program.<\/li>\n<li><code>olc::Key<\/code> &#8212; For user input.<\/li>\n<li><code>olc::Pixel<\/code> &#8212; For coloring pixels.<\/li>\n<li><code>olc::vf2d<\/code>\/<code>olc::vi2d<\/code> &#8212; Standard vector classes (<code>float<\/code> and <code>int<\/code> respectively).<\/li>\n<li><code>olc::BLACK<\/code>, <code>olc::WHITE<\/code>, <code>olc::BLUE<\/code>, and <code>olc::RED<\/code> &#8212; Color constants.<\/li>\n<\/ul>\n<p>We can, by default, export each of the above with a using-declaration:<\/p>\n<pre>module;\r\n#pragma warning(push)\r\n#pragma warning(disable: 4201) \/\/ nonstandard extension used: nameless struct\/union\r\n#pragma warning(disable: 4245) \/\/ 'argument': conversion from 'int' to 'uint8_t', possible loss of data\r\n#include \"olcPixelGameEngine.h\"\r\n#pragma warning(pop)\r\nexport module Bridges.PGE;\r\n\r\nexport\r\nnamespace olc\r\n{\r\n    \/\/ For game.\r\n    using olc::PixelGameEngine;\r\n    using olc::Key;\r\n\r\n    \/\/ For basic types.\r\n    using olc::Pixel;\r\n    using olc::vf2d;\r\n    using olc::vi2d;\r\n\r\n    \/\/ Allow using the multiply operator from olc::v2d_generic.\r\n    using olc::operator*;\r\n}<\/pre>\n<p>The reason we use a using-declaration is because we do not want the module to own all these objects\/functions. By injecting the names through a using-declaration their linkage remains tied to the global module so we can separately compile them in <a href=\"https:\/\/github.com\/cdacamar\/ball_pit\/blob\/ce90e45245bf7981fd797d992389693bdd586c0b\/src\/3rd_party\/olcPixelGameEngine.cpp\"><code>src\/3rd_party\/olcPixelGameEngine.cpp<\/code><\/a> as before.<\/p>\n<p>You will immediately notice that the color constants are mysteriously missing. This is because these constants are defined with <code>static<\/code> linkage in the header file so we cannot export them directly and the reason is <a href=\"http:\/\/eel.is\/c%2B%2Bdraft\/basic.link#18\">buried in standardese<\/a>. It is simpler to remember that you cannot export an internal linkage entity (i.e. one declared <code>static<\/code>). The way to get around this is wrap them in a function which has module linkage:<\/p>\n<pre>export\r\nnamespace olc\r\n{\r\n    ...\r\n    \/\/ Note: Because these color constants are defined to be static in the header they cannot be\r\n    \/\/ directly exported.  Instead we export their values through a module-owned variable.\r\n    namespace ModuleColors\r\n    {\r\n        auto Black()\r\n        {\r\n            return olc::BLACK;\r\n        }\r\n\r\n        auto White()\r\n        {\r\n            return olc::WHITE;\r\n        }\r\n\r\n        auto Blue()\r\n        {\r\n            return olc::BLUE;\r\n        }\r\n\r\n        auto Red()\r\n        {\r\n            return olc::RED;\r\n        }\r\n    }\r\n    ...\r\n}<\/pre>\n<p>Once we have these functions, we need to replace any instance of <code>olc::COLOR<\/code> with its respective call to our exported color function.<\/p>\n<p>And that is it! We have successfully exported exactly what we need from PGE for our &#8220;Ball Pit!&#8221; app! Just as before, you add this to the <code>CMakeLists.txt<\/code>, replace <code>#include \"bridges\/pge-bridge.h\"<\/code> with <code>import Bridges.PGE;<\/code>.<\/p>\n<h5><span id=\"polish\">Polishing with modules<\/span><\/h5>\n<p>Once you have gone through the exercise of modularizing more and more of the project you might find that your main program begins to reflect the header file version:<\/p>\n<pre>import Bridges.PGE;\r\n\r\nimport Physics.Ball;\r\nimport Physics.Engine;\r\nimport Physics.QuadTree;\r\nimport Util.BasicTypes;\r\nimport Util.EnumUtils;\r\nimport Util.RandomGenerator;\r\nimport World;<\/pre>\n<p>Dandy! Modules also give us similar tools as header files do in that we can group common sets of modules together into a &#8220;package&#8221;. To understand what I am talking about let us look at a header file equivalent of grouping common functionality. Here is what a grouping of all the headers under <code>include\/physics\/*<\/code> might look like:<\/p>\n<p><code>include\/physics\/physics.h<\/code><\/p>\n<pre>#ifndef PHYSICS_H\r\n#define PHYSICS_H\r\n\r\n#include \"physics\/physics-ball.h\"\r\n#include \"physics\/physics-engine.h\"\r\n#include \"physics\/physics-utils.h\"\r\n#include \"physics\/quad-tree.h\"\r\n\r\n#endif PHYSICS_H<\/pre>\n<p>The problem, of course, is while this is convenient and you do not need to think about which specific file to include for your current project, you end up paying the cost of every header file in the package regardless of if you use it or not. It flies in the face of C++&#8217;s core concept: pay for what you use. With the introduction of C++20 modules we no longer have this problem because modules do next to zero work when you import them, so we can safely create the following interface without negatively impacting the compile time of consumers:<\/p>\n<p><code>modules\/physics\/physics.ixx<\/code><\/p>\n<pre>export module Physics;\r\n\r\nexport import Physics.Ball;\r\nexport import Physics.Engine;\r\nexport import Physics.QuadTree;\r\nexport import Physics.Utils;<\/pre>\n<p>We can also do the same for anything under <code>Util.*<\/code>. This leads us to a rather, I think, respectable looking <code>ball-pit.cpp<\/code>:<\/p>\n<pre>import Bridges.PGE;\r\n\r\nimport Physics;\r\nimport Util;\r\nimport World;<\/pre>\n<h4><span id=\"all-together\">All together now<\/span><\/h4>\n<p>It was a little bit of a journey getting here, and there are learnings along the way. I will not dillydally any further, here is the complete, modularized, version of &#8220;Ball Pit!&#8221;: <a href=\"https:\/\/github.com\/cdacamar\/ball_pit\/tree\/565e3bff28b78b84ac3765d6c786e96980177867\"><code>ball_pit<\/code><\/a>. You can check out the code, configure, and build it the same as we <a href=\"#cpp-today\">covered earlier<\/a> using Visual Studio 2019 version 16.11.<\/p>\n<p>There is one thing I want to mention, because I can all but guarantee it is on everybody&#8217;s mind: what is the build throughput? With modules there is an up-front cost in building our interfaces. With the old inclusion model, we did not have to build our include files explicitly (only implicitly). We end up building more up front, but the result is that we can <a href=\"https:\/\/en.wikipedia.org\/wiki\/Read%E2%80%93eval%E2%80%93print_loop\">REPL<\/a> our main program and its components much, much faster. Here is a snapshot of the difference:<\/p>\n<p>Compiling <code>ball-pit.cpp<\/code>:<\/p>\n<table>\n<tbody>\n<tr>\n<td>Without modules<\/td>\n<td>With modules<\/td>\n<\/tr>\n<tr>\n<td>3.55275s<\/td>\n<td>0.15413s<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><em>Note:<\/em> these times were an average of 10 runs. You can see the results yourself by observing the <code>c1xx.dll<\/code> in the build log (left in for comparisons).<\/p>\n<p>Yep, that is a real ~23x speedup difference. That kind of compile time if you&#8217;re developing a game can make a dramatic difference if you are wanting to quickly test changes to your game or make mistakes, like I often do :).<\/p>\n<h4>Closing<\/h4>\n<p>The process of using named modules in complex projects can be time consuming, but this type of refactor pays off in both reducing development costs associated with recompiling and code hygiene. Named modules give us so much more than simply better compile times and in the above we have only scratched the surface of what is possible. Stay tuned for more modules educational content from us in the future!<\/p>\n<p>We urge you to go out and try using Visual Studio 2019\/2022 with Modules. Both Visual Studio 2019 and Visual Studio 2022 Preview are available through the <a href=\"https:\/\/visualstudio.microsoft.com\/downloads\/\">Visual Studio downloads<\/a> page!<\/p>\n<p>As always, we welcome your feedback. Feel free to send any comments through e-mail at <a href=\"mailto:visualcpp@microsoft.com\">visualcpp@microsoft.com<\/a> or through <a href=\"https:\/\/twitter.com\/visualc\">Twitter @visualc<\/a>. Also, feel free to follow me on Twitter <a href=\"https:\/\/twitter.com\/starfreakclone\">@starfreakclone<\/a>.<\/p>\n<p>If you encounter other problems with MSVC in VS 2019\/2022 please let us know via the <a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/ide\/how-to-report-a-problem-with-visual-studio?view=vs-2019\">Report a Problem<\/a> option, either from the installer or the Visual Studio IDE itself. For suggestions or bug reports, let us know through <a href=\"https:\/\/developercommunity.visualstudio.com\/\">DevComm.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>There is a lot of hype (and perhaps restraint) to using modules in projects. The general blocker tends to be build support, but even with good build support there is a distinct lack of useful resources for practices around moving projects to using named modules (not just header units). In this blog we will take [&hellip;]<\/p>\n","protected":false},"author":39620,"featured_media":28589,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1,512],"tags":[140,100,2064,246],"class_list":["post-28553","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus","category-general-cpp-series","tag-c","tag-c-language","tag-c20","tag-modules"],"acf":[],"blog_post_summary":"<p>There is a lot of hype (and perhaps restraint) to using modules in projects. The general blocker tends to be build support, but even with good build support there is a distinct lack of useful resources for practices around moving projects to using named modules (not just header units). In this blog we will take [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/28553","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/39620"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=28553"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/28553\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/28589"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=28553"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=28553"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=28553"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}