building c++ modules

117
Building C++ Modules Boris Kolpackov Code Synthesis v1.3, September 2017 CODE SYNTHESIS -1-

Upload: others

Post on 15-Feb-2022

6 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Building C++ Modules

Building C++ Modules

Boris Kolpackov

Code Synthesis

v1.3, September 2017

CODE

SYNTHESIS

-1-

Page 2: Building C++ Modules

Practical C++ Modules

“acknowledged and acknowledgeable by the C++ standard”

A Module System for C++ (P0142R0)

-2-

Page 3: Building C++ Modules

Why Modules?

• Isolation from macros and symbols

• Physical design mechanism

• Step towards not needing the preprocessor

• Reliable distributed compilation

-3-

Page 4: Building C++ Modules

Speed!!!

Photo credit: bhmpics

-4-

Page 5: Building C++ Modules

What is a Module?

Three Perspectives

• module consumer

• module producer

• build system

-5-

Page 6: Building C++ Modules

What is a Module?

Language-level mechanism:

import hello.core;

Not preprocessor-level:

#import hello.core

-6-

Page 7: Building C++ Modules

Modules from Consumer Perspective

• Collection of external names

• Called module interface

• Become visible once imported

import hello.core;

-7-

Page 8: Building C++ Modules

Modules from Consumer Perspective

What does visible mean?

An import-declaration makes exported declarations [...]

visible to name lookup in the current translation unit,

in the same namespaces and contexts [...].

Note: The entities are not redeclared [...]

-8-

Page 9: Building C++ Modules

Modules and Namespaces

Modules and Namespace are Orthogonal

• Module can export names from any namespace(s)

• Module name and namespace name need not be related

• import does not imply using-directive

import hello.core; // Exports hello::f().f (); // Error.hello::f (); // Ok.using namespace hello;f (); // Ok.

-9-

Page 10: Building C++ Modules

Modules and Namespaces

Modules and Namespace are Orthogonal

• Module can export names from any namespace(s)

• Module name and namespace name need not be related

• import does not imply using-directive

import hello.core; // Exports hello::f().f (); // Error.hello::f (); // Ok.using namespace hello;f (); // Ok.

-9-

Page 11: Building C++ Modules

Module and Libraries

Modules provide Names not Symbols

• Satisfy symbols the usual way: link object file or library

• Make perfect sense in programs, not only libraries

• Library may have private/implementation modules

-10-

Page 12: Building C++ Modules

Modules from Producer Perspective

• module interface unit

• module implementation unit

• non-module translation unit

-11-

Page 13: Building C++ Modules

Modules from Producer Perspective

• Collection of module translation units

• Exactly one interface unit

• Zero or more implementation units

• Interface may define non-inline functions/variables

-12-

Page 14: Building C++ Modules

Modules Interface Unit

Contains exporting module declaration

export module hello.core;

-13-

Page 15: Building C++ Modules

Modules Implementation Unit

Contains non-exporting module declaration

module hello.core;

-14-

Page 16: Building C++ Modules

Interface File Extensions

Vendor suggested extensions:

Clang .cppmGCC .?VC .ixx

My recommendation:

.hpp/.cpp .mpp

.hxx/.cxx .mxx

Other? Switch!

-15-

Page 17: Building C++ Modules

Interface File Extensions

Vendor suggested extensions:

Clang .cppmGCC .?VC .ixx

My recommendation:

.hpp/.cpp .mpp

.hxx/.cxx .mxx

Other? Switch!

-15-

Page 18: Building C++ Modules

Module Purview

Module declaration starts module purview

Name declared in purview belongs to module

#include <string> // Not in purview.

export module hello.core; // Start of purview.

void say_hello (const std::string&); // In purview.

-16-

Page 19: Building C++ Modules

Module Export

Name belonging to module isinvisible unless exported

Name can only be exported inmodule interface unit

-17-

Page 20: Building C++ Modules

Export Specifier

export module hello.core;

export enum class volume {quiet, normal, loud};

export void say_hello (const char*, volume);

-18-

Page 21: Building C++ Modules

Exported Group

export module hello.core;

export{enum class volume {quiet, normal, loud};

void say_hello (const char*, volume);}

-19-

Page 22: Building C++ Modules

Exported Namespace

export module hello.core;

export namespace hello{enum class volume {quiet, normal, loud};

void say (const char*, volume);}

namespace hello{void impl (const char*, volume); // Not exported.

}

-20-

Page 23: Building C++ Modules

Module Ownership Model

• For exported names symbols are unchanged

• Non-exported names have module linkage:

• ...can only be resolved from module purview

• ...no clash with identical names in other modules

• (implemented by decorating with module name)

-21-

Page 24: Building C++ Modules

Module Ownership Model

Library built as modules can be used via headers

and even the other way around

-22-

Page 25: Building C++ Modules

Modules and Preprocessor

Modules do not export macros, only C++ names

Macros do not affect interfaces being imported

Import order is insignificant

-23-

Page 26: Building C++ Modules

Import Visibility

// hello.extra interface//export module hello.extra;

import hello.core; // Exports say_hello().

// hello.extra implementation//module hello.extra;

say_hello (”World”); // Ok.

-24-

Page 27: Building C++ Modules

Import Visibility

// hello.extra interface//export module hello.extra;

import hello.core; // Exports say_hello().

// hello.extra implementation//module hello.extra;

say_hello (”World”); // Ok.

-24-

Page 28: Building C++ Modules

Import Visibility

// hello.extra interface//export module hello.extra;

import hello.core; // Exports say_hello().

// hello.extra implementation//module hello.extra;

say_hello (”World”); // Ok.

-24-

Page 29: Building C++ Modules

Import Visibility

// hello.extra interface//export module hello.extra;

import hello.core; // Exports say_hello().

// hello.extra consumer//import hello.extra;

say_hello (”World”); // Error, hello.core import.

-25-

Page 30: Building C++ Modules

Import Visibility

// hello.extra interface//export module hello.extra;

import hello.core; // Exports say_hello().

// hello.extra consumer//import hello.extra;

say_hello (”World”); // Error, hello.core import.

-25-

Page 31: Building C++ Modules

Re-Export

// hello.extra interface//export module hello.extra;

export import hello.core;

// hello.extra consumer//import hello.extra;

say_hello (”World”); // Ok.

-26-

Page 32: Building C++ Modules

Re-Export and Submodules

Re-export is the mechanism for assemblingbigger modules out of submodules

export module hello;

export{import hello.core;import hello.basic;import hello.extra;

}

-27-

Page 33: Building C++ Modules

Modules from Build System Perspective

“The compiler should not become a build system.”

Richard Smith

• Binary Module Interface (BMI)

• Produced by compiling module interface unit

• Required when compiling importing translation units...

• ...as well as module’s implementation units

-28-

Page 34: Building C++ Modules

Hello Module

// hello.mxxexport module hello;export void say_hello (const char* name);

// hello.cxx#include <iostream>

module hello;

void say_hello (const char* n){std::cout << ”Hello, ” << n << ’!’ << std::endl;

}

// driver.cxximport hello;

int main () { say_hello (”Modules”); }-29-

Page 35: Building C++ Modules

Hello Module

// hello.mxxexport module hello;export void say_hello (const char* name);

// hello.cxx#include <iostream>

module hello;

void say_hello (const char* n){std::cout << ”Hello, ” << n << ’!’ << std::endl;

}

// driver.cxximport hello;

int main () { say_hello (”Modules”); }-29-

Page 36: Building C++ Modules

Hello Module

// hello.mxxexport module hello;export void say_hello (const char* name);

// hello.cxx#include <iostream>

module hello;

void say_hello (const char* n){std::cout << ”Hello, ” << n << ’!’ << std::endl;

}

// driver.cxximport hello;

int main () { say_hello (”Modules”); }-29-

Page 37: Building C++ Modules

Hello Module

// hello.mxxexport module hello;export void say_hello (const char* name);

// hello.cxx#include <iostream>

module hello;

void say_hello (const char* n){std::cout << ”Hello, ” << n << ’!’ << std::endl;

}

// driver.cxximport hello;

int main () { say_hello (”Modules”); }-29-

Page 38: Building C++ Modules

Compiling Modules

cl /D_CRT_SECURE_NO_WARNINGS -IC:\tmp\build\libodb-sqlite-2.5.0-b.6.1503567680.1432c5607115e465 -IC:\tmp\build\libodb-sqlite-2.5.0-b.6.1503567680.1432c5607115e465-DLIBODB_SQLITE_BUILD2 -DLIBODB_SQLITE_SHARED_BUILD -IC:\tmp\build\libodb-2.5.0-b.6.1503567043.6b15416ac28ada02-IC:\tmp\build\libodb-2.5.0-b.6.1503567043.6b15416ac28ada02 -DLIBODB_BUILD2 -DLIBODB_SHARED -IC:\tmp\build\libsqlite3-3.18.3-a.0.1503562393.3c9bf2b8ce40e258\libsqlite3 -DSQLITE_API=__declspec(dllimport) /W3 /WX /wd4251/wd4275 /nologo /EHsc/MD /Fo: libodb-sqlite-2.5.0-b.6.1503567680.1432c5607115e465\odb\sqlite\database.dll.obj /c /TP C:\tmp\build\libodb-sqlite-2.5.0-b.6.1503567680.1432c5607115e465\odb\sqlite\database.cxx

-30-

Page 39: Building C++ Modules

Compiling with GCC

$ ls -1hello.mxxhello.cxxdriver.cxx

$ g++ -std=c++1z -fmodules -x c++ -o hello.nms.o \-fmodule-output=hello.nms -c hello.mxx

$ g++ -std=c++1z -fmodules -x c++ -o hello.o \-fmodule-file=hello=hello.nms -c hello.cxx

$ g++ -std=c++1z -fmodules -x c++ -o driver.o \-fmodule-file=hello=hello.nms -c driver.cxx

$ g++ -o hello hello.nms.o driver.o hello.o

-31-

Page 40: Building C++ Modules

Compiling with GCC

$ ls -1hello.mxxhello.cxxdriver.cxx

$ g++ -std=c++1z -fmodules -x c++ -o hello.nms.o \-fmodule-output=hello.nms -c hello.mxx

$ g++ -std=c++1z -fmodules -x c++ -o hello.o \-fmodule-file=hello=hello.nms -c hello.cxx

$ g++ -std=c++1z -fmodules -x c++ -o driver.o \-fmodule-file=hello=hello.nms -c driver.cxx

$ g++ -o hello hello.nms.o driver.o hello.o

-31-

Page 41: Building C++ Modules

Compiling with GCC

$ ls -1hello.mxxhello.cxxdriver.cxx

$ g++ -std=c++1z -fmodules -x c++ -o hello.nms.o \-fmodule-output=hello.nms -c hello.mxx

$ g++ -std=c++1z -fmodules -x c++ -o hello.o \-fmodule-file=hello=hello.nms -c hello.cxx

$ g++ -std=c++1z -fmodules -x c++ -o driver.o \-fmodule-file=hello=hello.nms -c driver.cxx

$ g++ -o hello hello.nms.o driver.o hello.o

-31-

Page 42: Building C++ Modules

Compiling with GCC

$ ls -1hello.mxxhello.cxxdriver.cxx

$ g++ -std=c++1z -fmodules -x c++ -o hello.nms.o \-fmodule-output=hello.nms -c hello.mxx

$ g++ -std=c++1z -fmodules -x c++ -o hello.o \-fmodule-file=hello=hello.nms -c hello.cxx

$ g++ -std=c++1z -fmodules -x c++ -o driver.o \-fmodule-file=hello=hello.nms -c driver.cxx

$ g++ -o hello hello.nms.o driver.o hello.o

-31-

Page 43: Building C++ Modules

Compiling with GCC

$ ls -1hello.mxxhello.cxxdriver.cxx

$ g++ -std=c++1z -fmodules -x c++ -o hello.nms.o \-fmodule-output=hello.nms -c hello.mxx

$ g++ -std=c++1z -fmodules -x c++ -o hello.o \-fmodule-file=hello=hello.nms -c hello.cxx

$ g++ -std=c++1z -fmodules -x c++ -o driver.o \-fmodule-file=hello=hello.nms -c driver.cxx

$ g++ -o hello hello.nms.o driver.o hello.o

-31-

Page 44: Building C++ Modules

Compiling with GCC

$ ls -1hello.mxxhello.cxxdriver.cxx

$ g++ -std=c++1z -fmodules -x c++ -o hello.nms.o \-fmodule-output=hello.nms -c hello.mxx

$ g++ -std=c++1z -fmodules -x c++ -o hello.o \-fmodule-file=hello=hello.nms -c hello.cxx

$ g++ -std=c++1z -fmodules -x c++ -o driver.o \-fmodule-file=hello=hello.nms -c driver.cxx

$ g++ -o hello hello.nms.o driver.o hello.o

-31-

Page 45: Building C++ Modules

Compiling with Clang

$ clang++ -std=c++2a -fmodules-ts --precompile \-x c++-module [...] -o hello.pcm hello.mxx

$ clang++ -std=c++2a -fmodules-ts -o hello.pcm.o \-c hello.pcm

$ clang++ -std=c++2a -fmodules-ts -x c++ -o hello.o \-fmodule-file=hello.pcm -c hello.cxx

$ clang++ -std=c++2a -fmodules-ts -x c++ -o driver.o \-fmodule-file=hello=hello.pcm -c driver.cxx

$ clang++ -o hello hello.pcm.o driver.o hello.o

[...] = -Xclang -fmodules-embed-all-files \-Xclang -fmodules-codegen \-Xclang -fmodules-debuginfo

-32-

Page 46: Building C++ Modules

Compiling with Clang

$ clang++ -std=c++2a -fmodules-ts --precompile \-x c++-module [...] -o hello.pcm hello.mxx

$ clang++ -std=c++2a -fmodules-ts -o hello.pcm.o \-c hello.pcm

$ clang++ -std=c++2a -fmodules-ts -x c++ -o hello.o \-fmodule-file=hello.pcm -c hello.cxx

$ clang++ -std=c++2a -fmodules-ts -x c++ -o driver.o \-fmodule-file=hello=hello.pcm -c driver.cxx

$ clang++ -o hello hello.pcm.o driver.o hello.o

[...] = -Xclang -fmodules-embed-all-files \-Xclang -fmodules-codegen \-Xclang -fmodules-debuginfo

-32-

Page 47: Building C++ Modules

Compiling with VC

> cl.exe /std:c++latest /experimental:module /TP /EHsc ^/MD /module:interface /Fo: hello.ifc.obj ^/module:output hello.ifc /c hello.mxx

> cl.exe /std:c++latest /experimental:module /TP /EHsc ^/MD /module:reference hello.ifc /Fo: hello.obj ^/c hello.cxx

> cl.exe /std:c++latest /experimental:module /TP /EHsc ^/MD /module:reference hello.ifc /Fo: driver.obj ^/c driver.cxx

> link.exe /OUT:hello.exe hello.ifc.obj driver.obj ^hello.obj

-33-

Page 48: Building C++ Modules

Modules from Build System Perspective

• Figure out the order of compilation

• Make sure every compilation can find BMIs it needs

-34-

Page 49: Building C++ Modules

Compilation of Header Project

time

hello.cxx

driver.cxx

-35-

Page 50: Building C++ Modules

Compilation of Module Project

time

hello.mxx

hello.cxx

driver.cxx

-36-

Page 51: Building C++ Modules

More Complex Module Project

$ ls -1core.mxxextra.mxx # imports hello.corehello.mxx # re-exports hello.core and hello.extra

core.cxxextra.cxx

driver.cxx # imports hello

-37-

Page 52: Building C++ Modules

Compilation of Complex Module Project

time

core.mxx

extra.mxx

core.cxx

hello.mxx

extra.cxx driver.cxx

-38-

Page 53: Building C++ Modules

Compilation of Generated Header Project

time

hello.hxx

hello.cxx

driver.cxx

-39-

Page 54: Building C++ Modules

Compilation of Generated Header Project

time

hello.hxx

hello.cxx

driver.cxx

-39-

Page 55: Building C++ Modules

Modules Support via Ad Hoc Pre-Build Step

Does not work well

• Binary module interfaces depend on each other

• Manual module dependency specification does not scale

-40-

Page 56: Building C++ Modules

Compilation via Ad Hoc Pre-Build Step

time

core.mxx extra.mxx hello.mxx

core.cxx

extra.cxx

driver.cxx

-41-

Page 57: Building C++ Modules

What’s in a BMI?

• Compiler specific, can be anything between

• ...stream of preprocessed tokens and

• ...something close to object code

• Sensitive to compiler options

• Build system may have to side-build

-42-

Page 58: Building C++ Modules

What to Install/Distribute?

Not a distribution mechanism

• BMIs should not be installed/distributed

• Install/distribute module interface units instead

• Build system has to side-build

-43-

Page 59: Building C++ Modules

Standard Library Modules (P0581R0)

Note: Very Experimental

std.fundamental <cstd*> <utility> <type_traits> ...std.core <string> <functional> containers ...std.io <iostream> <locale> ...std.threading <mutex> <thread> ...

-44-

Page 60: Building C++ Modules

Module Design Guidelines

“brave new module world”

A Module System for C++ (P0142R0)

• Explicit exportation

• Module purview

• Module building

-45-

Page 61: Building C++ Modules

Module Granularity

• Cost of importing modules is negligible

• Mega-Modules cause unnecessary recompilation

• Mini-Modules are tedious to import

-46-

Page 62: Building C++ Modules

Module Granularity

Combine related and commonly-used entities

(generally good design)

• xml.parser

• xml.serializer

• xml (aggregate module)

-47-

Page 63: Building C++ Modules

Module Partitioning into Units

Opportunity to get rid of header/source divide?

• Unnecessary recompilation

• Reduced interface readability

• Extra dependencies (implementation imports)

-48-

Page 64: Building C++ Modules

Module Partitioning into Units

Have a separate module implementation unit

(except for simple/inline/template implementations)

-49-

Page 65: Building C++ Modules

Module-Only Libraries

The Holy Grail?

export module hello;

import std.core;import std.io;

using namespace std;

export void say_hello (const string& n){cout << ”Look, ” << n << ”, I am not inline!” << endl;

}

-50-

Page 66: Building C++ Modules

Module-Only Libraries

Or a better Foot Gun?

• ODR violations

• Incompatible versions

• Where are the tests?

-51-

Page 67: Building C++ Modules

First Real Module

• Where to put #include directives?

• Where to put import declarations?

• In what order?

-52-

Page 68: Building C++ Modules

First Real Module

// Old rules.

[export] module hello; // Start or module purview.

// New rules.

-53-

Page 69: Building C++ Modules

First Real Module

What’s wrong with this?

export module hello;

#include <string>

...

-54-

Page 70: Building C++ Modules

Where to Include?

Including headers in module purview is bad idea

(except for certain special headers)

-55-

Page 71: Building C++ Modules

First Real Module

#include <string>

export module hello;

#include <libhello/export.hxx>

export namespace hello{...

}

#include <libhello/hello.ixx>

-56-

Page 72: Building C++ Modules

Where to Import?

What about import?

• Merely makes names visible

• For implementation units exact location does not matter

• For interface units only imports in module purview:

• ... are visible in implementation units

• ... can be re-exported

-57-

Page 73: Building C++ Modules

Where to Import?

In interface units import in module purview

(unless a good reason not too)

Do likewise in implementation for consistency

-58-

Page 74: Building C++ Modules

First Real Module

#include <cassert>

export module hello;

import std.core;

#include <libhello/export.hxx>

export namespace hello{...

}

#include <libhello/hello.ixx>

-59-

Page 75: Building C++ Modules

Module Interface Template

<header includes>

export module <name>; // Start of module purview.

<module imports>

<special header includes> // Config, export, etc.

export{<module interface>

}

<inline/template includes>

-60-

Page 76: Building C++ Modules

Module Interface Template

<header includes>

export module <name>; // Start of module purview.

<module imports>

<special header includes> // Config, export, etc.

export{<module interface>

}

<inline/template includes>

-60-

Page 77: Building C++ Modules

Module Interface Template

<header includes>

export module <name>; // Start of module purview.

<module imports>

<special header includes> // Config, export, etc.

export{<module interface>

}

<inline/template includes>

-60-

Page 78: Building C++ Modules

Module Interface Template

<header includes>

export module <name>; // Start of module purview.

<module imports>

<special header includes> // Config, export, etc.

export{<module interface>

}

<inline/template includes>

-60-

Page 79: Building C++ Modules

Module Interface Template

<header includes>

export module <name>; // Start of module purview.

<module imports>

<special header includes> // Config, export, etc.

export{<module interface>

}

<inline/template includes>

-60-

Page 80: Building C++ Modules

Module Interface Template

<header includes>

export module <name>; // Start of module purview.

<module imports>

<special header includes> // Config, export, etc.

export{<module interface>

}

<inline/template includes>

-60-

Page 81: Building C++ Modules

Module Implementation Template

<header includes>

module <name>; // Start of module purview.

<extra module imports> // Only additional to interface.

<module implementation>

-61-

Page 82: Building C++ Modules

Module Implementation Template

<header includes>

module <name>; // Start of module purview.

<extra module imports> // Only additional to interface.

<module implementation>

-61-

Page 83: Building C++ Modules

Module Implementation Template

<header includes>

module <name>; // Start of module purview.

<extra module imports> // Only additional to interface.

<module implementation>

-61-

Page 84: Building C++ Modules

Module Implementation Template

<header includes>

module <name>; // Start of module purview.

<extra module imports> // Only additional to interface.

<module implementation>

-61-

Page 85: Building C++ Modules

Module Naming

• Module names in a separate “name plane”

• Do not collide with namespace/type/function names

• No prescribed hierarchical semantics

• Customary for hello.core to be a submodule of hello

-62-

Page 86: Building C++ Modules

Module Naming

• Start with the library/project namespace

• Finish with a name describing the module’s functionality

• If dedicated to a single/primary entity, use its name

-63-

Page 87: Building C++ Modules

Module Naming Examples

• Library name: libbutl

• Library namespace: butl

• Library modules:

butl.base64 butl.pathbutl.char_scanner butl.path_iobutl.const_ptr butl.path_mapbutl.diagnostics butl.processbutl.fdstream butl.sha256butl.filesystem butl.small_vectorbutl.manifest_parser butl.string_parserbutl.manifest_serializer butl.string_tablebutl.multi_index butl.target_tripletbutl.openssl butl.timestampbutl.pager butl.vector_view

-64-

Page 88: Building C++ Modules

When to Re-Export?

Let’s talk about this another day ;-)

export module hello;

export import std.core; // Good idea?

export void say_hello (const std::string&);

-65-

Page 89: Building C++ Modules

When to Re-Export?

Let’s talk about this another day ;-)

export module hello;

export import std.core; // Good idea?

export void say_hello (const std::string&);

-65-

Page 90: Building C++ Modules

Modularizing Existing Code

• Build system with proper modules support

• Well modularized (in the general sense) headers

-66-

Page 91: Building C++ Modules

Modularizing Existing Code

Bad Idea!

export module hello;

export{#include ”hello.hxx”}

-67-

Page 92: Building C++ Modules

Guerrilla Modularization

#include <string> // Pre-include out of purview.

export module hello;

export{#include ”hello.hxx”}

-68-

Page 93: Building C++ Modules

Modularizing Existing Code

No mixing of inclusion and importation

in the same translation unit

-69-

Page 94: Building C++ Modules

Modularized Standard Library

Two Plausible Strategies:

• First switch your entire codebase to modularized std

• First complete modularization of your entire codebase

-70-

Page 95: Building C++ Modules

Modularized Standard Library

#include <libhello/core.hxx> // Includes <iostream>?

module hello.extra;

import std.io;

-71-

Page 96: Building C++ Modules

Modularizing Own Code

Modularize inter-dependent sets of headers

one set at a time

starting from low-level components

(newly modularized only depends on already modularized)

-72-

Page 97: Building C++ Modules

Modularizing Existing Code

Modularizing one component at a time?

#include <libhello/impl.hxx> // Imports hello.extra?

module hello.extra;

-73-

Page 98: Building C++ Modules

Backwards Compatibility

• modules-only

• modules-or-headers

• modules-and-headers

-74-

Page 99: Building C++ Modules

Modules-Only

• Follow the template and guidelines discussed above

• Seriously consider only supporting modularized std

-75-

Page 100: Building C++ Modules

Modules-or-Headers

• Expect consumers to be adjusted

• Module interface files used as headers

• FTM: __cpp_modules __cpp_lib_modules

-76-

Page 101: Building C++ Modules

Modules-or-Headers Interface

#ifndef __cpp_modules#pragma once#endif

// C includes, if any.

#ifndef __cpp_lib_modules<std includes>#endif

// Other includes, if any.

#ifdef __cpp_modulesexport module <name>;#ifdef __cpp_lib_modules<std imports>#endif#endif

-77-

Page 102: Building C++ Modules

Modules-or-Headers Interface

#ifndef __cpp_modules#pragma once#endif

// C includes, if any.

#ifndef __cpp_lib_modules<std includes>#endif

// Other includes, if any.

#ifdef __cpp_modulesexport module <name>;#ifdef __cpp_lib_modules<std imports>#endif#endif

-77-

Page 103: Building C++ Modules

Modules-or-Headers Interface

#ifndef __cpp_modules#pragma once#endif

// C includes, if any.

#ifndef __cpp_lib_modules<std includes>#endif

// Other includes, if any.

#ifdef __cpp_modulesexport module <name>;#ifdef __cpp_lib_modules<std imports>#endif#endif

-77-

Page 104: Building C++ Modules

Modules-or-Headers Interface

#ifndef __cpp_modules#pragma once#endif

// C includes, if any.

#ifndef __cpp_lib_modules<std includes>#endif

// Other includes, if any.

#ifdef __cpp_modulesexport module <name>;#ifdef __cpp_lib_modules<std imports>#endif#endif

-77-

Page 105: Building C++ Modules

Modules-or-Headers Interface

#ifndef __cpp_modules#pragma once#endif

// C includes, if any.

#ifndef __cpp_lib_modules<std includes>#endif

// Other includes, if any.

#ifdef __cpp_modulesexport module <name>;#ifdef __cpp_lib_modules<std imports>#endif#endif

-77-

Page 106: Building C++ Modules

Modules-or-Headers Interface

#ifndef __cpp_modules#pragma once#endif

// C includes, if any.

#ifndef __cpp_lib_modules<std includes>#endif

// Other includes, if any.

#ifdef __cpp_modulesexport module <name>;#ifdef __cpp_lib_modules<std imports>#endif#endif

-77-

Page 107: Building C++ Modules

Modules-or-Headers Interface

#ifndef __cpp_modules#pragma once#endif

// C includes, if any.

#ifndef __cpp_lib_modules<std includes>#endif

// Other includes, if any.

#ifdef __cpp_modulesexport module <name>;#ifdef __cpp_lib_modules<std imports>#endif#endif

-77-

Page 108: Building C++ Modules

Modules-or-Headers Implementation

#ifndef __cpp_modules#include <module interface file>#endif

// C includes, if any.

#ifndef __cpp_lib_modules<std includes><extra std includes>#endif

// Other includes, if any

#ifdef __cpp_modulesmodule <name>;#ifdef __cpp_lib_modules<extra std imports> // Only additional to interface.#endif#endif -78-

Page 109: Building C++ Modules

Modules-or-Headers Implementation

#ifndef __cpp_modules#include <module interface file>#endif

// C includes, if any.

#ifndef __cpp_lib_modules<std includes><extra std includes>#endif

// Other includes, if any

#ifdef __cpp_modulesmodule <name>;#ifdef __cpp_lib_modules<extra std imports> // Only additional to interface.#endif#endif -78-

Page 110: Building C++ Modules

Modules-or-Headers Implementation

#ifndef __cpp_modules#include <module interface file>#endif

// C includes, if any.

#ifndef __cpp_lib_modules<std includes><extra std includes>#endif

// Other includes, if any

#ifdef __cpp_modulesmodule <name>;#ifdef __cpp_lib_modules<extra std imports> // Only additional to interface.#endif#endif -78-

Page 111: Building C++ Modules

Modules-or-Headers Implementation

#ifndef __cpp_modules#include <module interface file>#endif

// C includes, if any.

#ifndef __cpp_lib_modules<std includes><extra std includes>#endif

// Other includes, if any

#ifdef __cpp_modulesmodule <name>;#ifdef __cpp_lib_modules<extra std imports> // Only additional to interface.#endif#endif -78-

Page 112: Building C++ Modules

Modules-or-Headers Implementation

#ifndef __cpp_modules#include <module interface file>#endif

// C includes, if any.

#ifndef __cpp_lib_modules<std includes><extra std includes>#endif

// Other includes, if any

#ifdef __cpp_modulesmodule <name>;#ifdef __cpp_lib_modules<extra std imports> // Only additional to interface.#endif#endif -78-

Page 113: Building C++ Modules

Modules-or-Headers Implementation

#ifndef __cpp_modules#include <module interface file>#endif

// C includes, if any.

#ifndef __cpp_lib_modules<std includes><extra std includes>#endif

// Other includes, if any

#ifdef __cpp_modulesmodule <name>;#ifdef __cpp_lib_modules<extra std imports> // Only additional to interface.#endif#endif -78-

Page 114: Building C++ Modules

Modules-or-Headers Implementation

#ifndef __cpp_modules#include <module interface file>#endif

// C includes, if any.

#ifndef __cpp_lib_modules<std includes><extra std includes>#endif

// Other includes, if any

#ifdef __cpp_modulesmodule <name>;#ifdef __cpp_lib_modules<extra std imports> // Only additional to interface.#endif#endif -78-

Page 115: Building C++ Modules

Modules-or-Headers Consumer

#ifdef __cpp_modulesimport hello;#else#include <libhello/hello.mxx>#endif

-79-

Page 116: Building C++ Modules

Modules-and-Headers

• Old consumers must work unmodified

• Keep module interface and header files

• Slight complication over modules-and-headers

-80-

Page 117: Building C++ Modules

Questions?

build2.orgBuild System Manual→ C++ Modules Support

Acknowledgements

Andrew Pardoe (VC/Microsoft)David Blaikie (Clang/Google)

Gabriel Dos Reis (VC/Microsoft)Nathan Sidwell (GCC/Facebook)Richard Smith (Clang/Google)

-81-