{"id":28323,"date":"2021-07-21T18:31:46","date_gmt":"2021-07-21T18:31:46","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cppblog\/?p=28323"},"modified":"2021-07-21T18:31:46","modified_gmt":"2021-07-21T18:31:46","slug":"using-cpp-modules-in-msvc-from-the-command-line-part-1","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/using-cpp-modules-in-msvc-from-the-command-line-part-1\/","title":{"rendered":"Using C++ Modules in MSVC from the Command Line Part 1: Primary Module Interfaces"},"content":{"rendered":"<p>In this three-part series we will explore how to build modules and header units from the command line as well as how to use\/reference them.<\/p>\n<p>The goal of this post is to serve as a brief tour of compiling and using primary module interfaces from the command line and the options we use.<\/p>\n<p><em>Note:<\/em> This tutorial will focus primarily on dealing with IFC and object file output. Other types of compiler output such as PDB info are not mentioned.<\/p>\n<h2>Overview<\/h2>\n<ul>\n<li><a href=\"#summary\">Summary of C++ modules options.<\/a><\/li>\n<li><a href=\"#interface-basics\">Basics of building a module interface.<\/a><\/li>\n<li><a href=\"#module-dependencies\">Modules with interface dependencies.<\/a><\/li>\n<\/ul>\n<h4><span id=\"summary\">Summary of C++ modules options<\/span><\/h4>\n<table>\n<tbody>\n<tr>\n<th>Option<\/th>\n<th>Brief Description<\/th>\n<\/tr>\n<tr>\n<td id=\"interface\"><code>\/interface<\/code><\/td>\n<td>Tells the compiler that the input file is a module interface unit.<\/td>\n<\/tr>\n<tr>\n<td><code>\/internalPartition<\/code><\/td>\n<td>Tells the compiler that the input file is an <a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/c-modules-conformance-improvements-with-msvc-in-visual-studio-2019-16-5\/#module-partitions\">internal partition unit<\/a>.<\/td>\n<\/tr>\n<tr>\n<td><code><a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/build\/reference\/module-reference?view=msvc-160\">\/reference<\/a><\/code><\/td>\n<td>Provides the compiler with an IFC file to reference for the nominated module interface name.<\/td>\n<\/tr>\n<tr>\n<td id=\"ifc-search-dir\"><code>\/ifcSearchDir<\/code><\/td>\n<td>When the compiler falls back to implicit module interface search, directories specified by this option will be used.<\/td>\n<\/tr>\n<tr>\n<td><code>\/ifcOutput<\/code><\/td>\n<td>Tells the compiler where the IFC resulting from compilation should go. If that destination is a directory the compiler will generate a name based on the interface name or the header unit name.<\/td>\n<\/tr>\n<tr>\n<td><code>\/ifcOnly<\/code><\/td>\n<td>Instructs the compiler to only produce an IFC as the result of compilation. No other outputs will be produced as the result of compilation even if other options are specified.<\/td>\n<\/tr>\n<tr>\n<td><code><a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/build\/reference\/module-exportheader?view=msvc-160\">\/exportHeader<\/a><\/code><\/td>\n<td>Instructs the compiler to create a header unit from the input.<\/td>\n<\/tr>\n<tr>\n<td><code><a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/build\/reference\/headername?view=msvc-160\">\/headerName<\/a><\/code><\/td>\n<td>Tells the compiler that the input designates the name of a header.<\/td>\n<\/tr>\n<tr>\n<td><code><a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/build\/reference\/translateinclude?view=msvc-160\">\/translateInclude<\/a><\/code><\/td>\n<td>Instructs the compiler to perform <code>#include<\/code> -&gt; <code>import<\/code> translation if the header-name nominates an importable header.<\/td>\n<\/tr>\n<tr>\n<td><code>\/showResolvedHeader<\/code><\/td>\n<td>When building a header unit, show the fully resolved path to that header unit after compilation.<\/td>\n<\/tr>\n<tr>\n<td><code>\/validateIfcChecksum[-]<\/code><\/td>\n<td>Off by default. Specifying this switch will enforce an extra security check using the stored content hash in the IFC.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4><span id=\"interface-basics\">Basics of building a module interface<\/span><\/h4>\n<p>For the content in this section, we will assume that you have an appropriate compiler environment command prompt set up and that you have navigated to the directory with your test files.<\/p>\n<p>Let&#8217;s look at the most basic scenario we can for starters:<\/p>\n<p><code>m.ixx<\/code>:<\/p>\n<pre class=\"\">export module MyModule;\r\n\r\nexport\r\nvoid f() { }<\/pre>\n<p><code>main.cpp<\/code>:<\/p>\n<pre class=\"\">import MyModule;\r\n\r\nint main() {\r\n  f();\r\n}<\/pre>\n<p>The simplest way to build this sample is the following:<\/p>\n<pre>$ cl \/c \/std:c++latest m.ixx\r\n$ cl \/std:c++latest \/reference MyModule=MyModule.ifc main.cpp m.obj\r\n$ .\\main.exe<\/pre>\n<p>One quick note about the name of file <code>m.ixx<\/code> above, the <code>.ixx<\/code> extension is the default module interface extension for MSVC. If you wish to use a different extension then you must use <a href=\"#interface\"><code>\/interface<\/code><\/a> along with <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/build\/reference\/tc-tp-tc-tp-specify-source-file-type?view=msvc-160\"><code>\/TP<\/code><\/a> in order to compile the input as both C++ and as a module interface. Here&#8217;s a quick example of compiling the module interface if the name were <code>my-module.cppm<\/code>:<\/p>\n<pre>$ cl \/c \/std:c++latest \/interface \/TP my-module.cppm<\/pre>\n<p>In the first line we compile the module interface, and two things happen implicitly:<\/p>\n<ol>\n<li>The compiler will derive a name for the resulting object file based on the <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/build\/reference\/specifying-the-pathname?view=msvc-160\">base name of the input file<\/a>. The resulting object file in this case is derived from <code>m.ixx<\/code> transformed into <code>m.obj<\/code>.<\/li>\n<li>The compiler will derive a name for the resulting IFC file based on the <em>module interface name<\/em>. The resulting IFC in this case is derived from the module name <code>MyModule<\/code> transformed into <code>MyModule.ifc<\/code>. Note that the name of the input file has no bearing on the exported module interface name, they are completely orthogonal to each other so if this file were named <code>foobar.ixx<\/code> the generated IFC name would still be <code>MyModule.ifc<\/code>.<\/li>\n<\/ol>\n<p>If we take away the two implicit points above, we will end up with a command line which looks like this:<\/p>\n<pre>$ cl \/c \/std:c++latest m.ixx \/ifcOutput MyModule.ifc \/Fom.obj<\/pre>\n<p>On the import side we could take advantage of the compiler&#8217;s implicit lookup behavior to find the module interface:<\/p>\n<pre>$ cl \/std:c++latest main.cpp m.obj\r\n$ .\\main.exe<\/pre>\n<p>Whoa! Hold on there! What happened? Well, in MSVC the compiler implements a well-coordinated lookup to find the module interface implicitly. Because the compiler generates a module interface IFC based on the module name it can safely be assumed that if there is no direct <code>\/reference<\/code> option on the command line then there could be an IFC somewhere on disk which is named after the module interface name. In the scenario above we are trying to import a module interface named <code>MyModule<\/code> so there might be a <code>MyModule.ifc<\/code> on disk, and indeed there is! It is worth pointing out that this implicit lookup behavior will search the current directory along with any directory added using <a href=\"#ifc-search-dir\"><code>\/ifcSearchDir<\/code><\/a>.<\/p>\n<p>Let&#8217;s consider a scenario where the destination for the resulting IFC is not in the immediate directory. Consider the following directory structure:<\/p>\n<pre>.\/\r\n\u251c\u2500 src\/\r\n\u2502  \u251c\u2500 m.ixx\r\n\u2502  \u251c\u2500 main.cpp\r\n\u251c\u2500 bin\/<\/pre>\n<p>And let&#8217;s assume that our compiler command prompt is rooted at <code>.\/<\/code> and that we want all output to go into the <code>bin\\<\/code> folder. Here&#8217;s what the fully explicit command lines look like:<\/p>\n<pre>$ cl \/c \/std:c++latest src\\m.ixx \/Fobin\\m.obj \/ifcOutput bin\\MyModule.ifc\r\n$ cl \/std:c++latest \/reference MyModule=bin\\MyModule.ifc src\\main.cpp \/Fobin\\m.obj \/Febin\\main.exe bin\\m.obj<\/pre>\n<p>There are a lot of things going on so let&#8217;s narrow the scope of noise to just the command line options required to compile <code>main.cpp<\/code> and not link it.<\/p>\n<pre>$ cl \/c \/std:c++latest \/reference MyModule=bin\\MyModule.ifc src\\main.cpp \/Fobin\\m.obj<\/pre>\n<p><em>Note:<\/em> The <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/build\/reference\/fo-object-file-name?view=msvc-160\"><code>\/Fo<\/code><\/a> tells the compiler where to put the resulting object file. Further, in order to ensure that the compiler can properly detect that the destination is a directory, please append the trailing &#8216;<code>\\<\/code>&#8216; at the end of the argument.<\/p>\n<p>If we wanted to take advantage of the compiler&#8217;s implicit naming mechanisms the command lines would be the following:<\/p>\n<pre>$ cl \/c \/std:c++latest src\\m.ixx \/Fobin\\ \/ifcOutput bin\\\r\n$ cl \/std:c++latest \/ifcSearchDir bin\\ src\\main.cpp \/Fobin\\ \/Febin\\ bin\\m.obj<\/pre>\n<p>Notice that the difference here is we simply provide a directory as the argument to each of our command line options.<\/p>\n<h4><span id=\"module-dependencies\">Modules with interface dependencies<\/span><\/h4>\n<p>Often, we don&#8217;t want to build a single module interface and call it a day, it is frequently the case that sufficiently large projects will be composed of many module interfaces which describe various parts of the system. In this section we&#8217;ll explore how to build translation units which depend on one or more interfaces.<\/p>\n<p>Let&#8217;s consider a slightly more sophisticated directory layout:<\/p>\n<pre>.\/\r\n\u251c\u2500 src\/\r\n\u2502  \u251c\u2500 types\/\r\n\u2502  \u2502  \u251c\u2500 types.ixx\r\n\u2502  \u251c\u2500 util\/\r\n\u2502  \u2502  \u251c\u2500 util.ixx\r\n\u2502  \u251c\u2500 shop\/\r\n\u2502  \u2502  \u251c\u2500 shop.ixx\r\n\u2502  \u2502  \u251c\u2500 shop-unit.cpp\r\n\u2502  \u251c\u2500 main.cpp\r\n\u251c\u2500 bin\/<\/pre>\n<p>The code for these files can be found <a href=\"https:\/\/gist.github.com\/cdacamar\/8226c1893dd8c8a81974c939be52809f\">here<\/a>.<\/p>\n<p>As you explore the code you will find that many of these modules\/source files contain references to module interfaces and those interfaces may reference yet another interface. At its core, the most basic dependency graph looks like the following:<\/p>\n<pre>   types.ixx\r\n   \/       \\\r\nutil.ixx  shop.ixx\r\n  \\        \/\r\nshop-unit.cpp\r\n      |\r\n   main.cpp<\/pre>\n<p>Without further ado, here are the explicit command lines in all their glory:<\/p>\n<pre>$ cl \/c \/EHsc \/std:c++latest src\\types\\types.ixx \/Fobin\\types.obj \/ifcOutput bin\\types.ifc\r\n$ cl \/c \/EHsc \/std:c++latest \/reference types=bin\\types.ifc src\\util\\util.ixx \/Fobin\\util.obj \/ifcOutput bin\\util.ifc\r\n$ cl \/c \/EHsc \/std:c++latest \/reference types=bin\\types.ifc src\\shop\\shop.ixx \/Fobin\\shop.obj \/ifcOutput bin\\shop.ifc\r\n$ cl \/c \/EHsc \/std:c++latest \/reference types=bin\\types.ifc \/reference util=bin\\util.ifc \/reference shop=bin\\shop.ifc src\\shop\\shop-unit.cpp \/Fobin\\shop-unit.obj\r\n$ cl \/EHsc \/std:c++latest \/reference shop=bin\\shop.ifc \/reference types=bin\\types.ifc src\\main.cpp \/Fobin\\main.obj \/Febin\\main.exe bin\\types.obj bin\\util.obj bin\\shop.obj bin\\shop-unit.obj<\/pre>\n<p>That is quite a mouthful. One thing you might notice is that when we built <code>src\\shop\\shop-unit.cpp<\/code> we needed a reference to both <code>types<\/code> and <code>shop<\/code> even though there&#8217;s no explicit import of either interface. The reason for this is because <code>util<\/code> has an implicit dependency on <code>types<\/code> to resolve <code>Product<\/code> properly and because it is a module unit the line <code>module shop;<\/code> implicitly imports the module interface <code>shop<\/code>, this behavior is defined by the C++ standard.<\/p>\n<p>Applying some techniques learned above we can drastically reduce the noise by using implicit naming\/lookup:<\/p>\n<pre>$ cl \/c \/EHsc \/std:c++latest src\\types\\types.ixx \/Fobin\\ \/ifcOutput bin\\\r\n$ cl \/c \/EHsc \/std:c++latest \/ifcSearchDir bin\\ src\\util\\util.ixx \/Fobin\\ \/ifcOutput bin\\\r\n$ cl \/c \/EHsc \/std:c++latest \/ifcSearchDir bin\\ src\\shop\\shop.ixx \/Fobin\\ \/ifcOutput bin\\\r\n$ cl \/c \/EHsc \/std:c++latest \/ifcSearchDir bin\\ src\\shop\\shop-unit.cpp \/Fobin\\\r\n$ cl \/EHsc \/std:c++latest \/ifcSearchDir bin\\ src\\main.cpp \/Fobin\\ \/Febin\\ bin\\types.obj bin\\util.obj bin\\shop.obj bin\\shop-unit.obj<\/pre>\n<p>This is looking much better. We can take it a step further by taking advantage of the fact that <code>cl.exe<\/code> will process each source file in a linear sequence:<\/p>\n<pre>$ cl \/EHsc \/std:c++latest \/ifcSearchDir bin\\ src\\types\\types.ixx src\\util\\util.ixx src\\shop\\shop.ixx src\\shop\\shop-unit.cpp src\\main.cpp \/Fobin\\ \/Febin\\main.exe \/ifcOutput bin\\<\/pre>\n<p>The command above uses implicit naming\/lookup along with <code>cl.exe<\/code>&#8216;s linear source processing behavior.<\/p>\n<p><em>Note:<\/em> the above command line will <strong>not<\/strong> work if the option <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/build\/reference\/mp-build-with-multiple-processes?view=msvc-160\"><code>\/MP<\/code><\/a> is used (compiling multiple inputs in parallel).<\/p>\n<p>Just to be complete, we could also use explicit naming for our module interfaces in the single command line above:<\/p>\n<pre>$ cl \/EHsc \/std:c++latest \/reference shop=bin\\shop.ifc \/reference types=bin\\types.ifc \/reference util=bin\\util.ifc src\\types\\types.ixx src\\util\\util.ixx src\\shop\\shop.ixx src\\shop\\shop-unit.cpp src\\main.cpp \/Fobin\\ \/Febin\\main.exe \/ifcOutput bin\\<\/pre>\n<p>The reason either of these command lines work is that the compiler will not try to do anything special with a <code>\/reference<\/code> option unless the name designating the IFC is used and there is no extra cost to add <code>\/reference<\/code> options for a command line if you know the module will be generated at some point in the input sequence.<\/p>\n<h4>Closing<\/h4>\n<p>In part 2 we will cover how to handle module interface partitions. Finally, in part 3 we will cover how to handle header units.<\/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>In this three-part series we will explore how to build modules and header units from the command line as well as how to use\/reference them. The goal of this post is to serve as a brief tour of compiling and using primary module interfaces from the command line and the options we use. Note: This [&hellip;]<\/p>\n","protected":false},"author":39620,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[140,2064,3897,246,282],"class_list":["post-28323","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus","tag-c","tag-c20","tag-compiler-command-line","tag-modules","tag-msvc"],"acf":[],"blog_post_summary":"<p>In this three-part series we will explore how to build modules and header units from the command line as well as how to use\/reference them. The goal of this post is to serve as a brief tour of compiling and using primary module interfaces from the command line and the options we use. Note: This [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/28323","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=28323"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/28323\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=28323"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=28323"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=28323"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}