You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/build/reference/header-unit-json-reference.md
+4-4Lines changed: 4 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -19,7 +19,7 @@ This file must be in the same directory as the included header file. This file i
19
19
20
20
## Rationale
21
21
22
-
Some header files can't be safely translated to header units. Header files that depend on macros that aren't defined on the command line, or that aren't defined in the header files included by the header, can't be translated to header units.
22
+
Some header files can't be safely translated to header units. Header files that depend on macros that aren't defined on the command line, or that are defined outside of the aren't defined in the header files included by the header, can't be translated to header units.
23
23
24
24
If a header defines macros that affect whether other headers are included, it can't be safely translated. For example, given `a.h`, `b.h` and `macros.h`, which are all in the same directory:
25
25
@@ -45,9 +45,9 @@ The `header-units.json` in this directory can contain `a.h` and `b.h`, but not `
45
45
}
46
46
```
47
47
48
-
The reason `macros.h` can't be listed in this `header-units.json` file is that during the scan phase, the header unit (`.ifc`) might not be compiled yet for `macros.h`. In that case, `MACRO` won't be defined when `a.h` is compiled. That means `b.h` will be missing from the list of dependencies for `a.h`. Because it isn't in the list of dependencies, the build system won't build a header unit for `b.h` despite it being listed in the `header-units.json` file.
48
+
The reason `macros.h` can't be listed in this `header-units.json` file is that during the scan phase, the header unit (`.ifc`) might not be compiled yet for `macros.h`. In that case, `MACRO` won't be defined when `a.h` is compiled. That means `b.h` will be missing from the list of dependencies for `a.h`. Since it isn't in the list of dependencies, the build system won't build a header unit for `b.h` despite it being listed in the `header-units.json` file.
49
49
50
-
To avoid this problem when there's a dependency on a macro in another header file, the header file that defines the macro is excluded from the list of files that can be compiled into a header unit. This way the header file that defines the macro is treated as an`#include` and `MACRO` will be visible so that `b.h` is included and listed as one of the dependencies.
50
+
To avoid this problem, when there's a dependency on a macro in another header file, the header file that defines the macro is excluded from the list of files that can be compiled into a header unit. This way the header file that defines the macro is treated as a normal`#include` and `MACRO` will be visible so that `b.h` is included and listed as one of the dependencies.
51
51
52
52
### Preventing duplicated symbols
53
53
@@ -69,7 +69,7 @@ import "c.h";
69
69
70
70
If the compiler built header units for `a.h`, `b.h` and `c.h`, then the compiled header units `a.h.ifc`, `b.h.ifc`, and `c.h.ifc` would each contain all of the types from `b.h`. Compiling `Source.cpp`, which imports both `a.h` and `c.h`, would require the compiler to deduplicate the `b.h` types, which would impact build performance.
71
71
72
-
But if there's a `header-units.json` in the `b.h` directory, and `/translateInclude` is specified, the following happens:
72
+
But if there's a `header-units.json` in the `b.h` directory, and `/translateInclude` is specified, then the following happens:
73
73
74
74
1. The scan of `a.h` and `c.h` lists `b.h` as a header unit import in the dependency scan files generated by the compiler.
75
75
1. The build system reads the dependency scan files and determines to build `b.h.ifc` first.
Copy file name to clipboardExpand all lines: docs/build/walkthrough-header-units.md
+16-16Lines changed: 16 additions & 16 deletions
Original file line number
Diff line number
Diff line change
@@ -23,35 +23,35 @@ To use header units, you need Visual Studio 2019 16.10 or later.
23
23
24
24
A header unit is a binary representation of a header file. A header unit ends with an *`.ifc`* extension. The same format is used for named modules.
25
25
26
-
An important difference between a header unit and a header file is that a header unit isn't affected by macro definitions outside of the header unit. That is, you can't define a preprocessor symbol that causes the header unit to behave differently. By the time you import the header unit, the header unit is already compiled. It's different from how an `#include` file is treated, because an included file can be affected by a macro definition outside of the header file, because the header file isn't compiled yet. It goes through the preprocessor when you compile the source file that includes it.
26
+
An important difference between a header unit and a header file is that a header unit isn't affected by macro definitions outside of the header unit. That is, you can't define a preprocessor symbol that causes the header unit to behave differently. By the time you import the header unit, the header unit is already compiled. That's different from how an `#include` file is treated. An included file can be affected by a macro definition outside of the header file because the header file goes through the preprocessor when you compile the source file that includes it.
27
27
28
28
Header units can be imported in any order, which isn't true of header files. Header file order matters because macro definitions defined in one header file might affect a subsequent header file. Macro definitions in one header unit can't affect another header unit.
29
29
30
30
Everything visible from a header file is also visible from a header unit, including macros defined within the header unit.
31
31
32
-
A header file must be translated into a header unit before it can be imported. An advantage of header units over PCH is that they can be used in distributed builds. For example, as long as you compile the *`.ifc`* and the program that imports it with the same compiler, and target the same platform and architecture, a header unit produced on one computer can be consumed on another. Unlike a PCH, when a header unit changes, only it and what depends on it are rebuilt. Header units can be up to an order of magnitude smaller in size than a traditional`.pch`.
32
+
A header file must be translated into a header unit before it can be imported. An advantage of header units over precompiled header files (PCH) is that they can be used in distributed builds. As long as you compile the *`.ifc`* and the program that imports it with the same compiler, and target the same platform and architecture, a header unit produced on one computer can be consumed on another. Unlike a PCH, when a header unit changes, only it and what depends on it are rebuilt. Header units can be up to an order of magnitude smaller in size than a `.pch`.
33
33
34
-
Header units impose fewer constraints on the parity of compiler switches used to create the header unit and to compile the code that consumes it than a PCH does. However, some switch combinations and macro definitions might create violations of the one definition rule (ODR) between various translation units.
34
+
Header units impose fewer constraints on the required similarities of compiler switch combinations used to create the header unit and to compile the code that consumes it than a PCH does. However, some switch combinations and macro definitions might create violations of the one definition rule (ODR) between various translation units.
35
35
36
36
Finally, header units are more flexible than a PCH. With a PCH, you can't choose to bring in only one of the headers in the PCH--the compiler processes all of them. With header units, even when you compile them together into a static library, you only bring the contents of the header unit you import into your application.
37
37
38
-
Header units are a step between header files and C++ 20 modules. They provide some of the benefits of modules. They're more robust because outside macro definitions don't affect them--so you can import them in any order without affecting each other. And the compiler can process them faster than header files. But they don't have all of the advantages of modules because they expose the macros defined within them (modules don't) and unlike modules there's no way to hide private implementation. To indicate private implementation with header files, different techniques are employed like adding leading underscores to names, or putting things in an implementation namespace. A module doesn't expose private implementation in any form so you don't need to do that.
38
+
Header units are a step in between header files and C++ 20 modules. They provide some of the benefits of modules. They're more robust because outside macro definitions don't affect them--so you can import them in any order. And the compiler can process them faster than header files. But header units don't have all of the advantages of modules because header units expose the macros defined within them (modules don't). Unlike modules, there's no way to hide private implementation in a header unit. To indicate private implementation with header files, different techniques are employed like adding leading underscores to names, or putting things in an implementation namespace. A module doesn't expose private implementation in any form, so you don't need to do that.
39
39
40
-
Consider replacing your PCH implementation with header units. You get the same speed advantage, but other code hygiene and flexibility benefits as well.
40
+
Consider replacing your precompiled headers with header units. You get the same speed advantage, but with other code hygiene and flexibility benefits as well.
41
41
42
42
## Ways to compile a header unit
43
43
44
44
There are several ways to compile a file into a header unit:
45
45
46
-
-**Choose individual files to translate into header units**. This approach gives you file-by-file control over what is treated as a header unit. It's also useful when you must compile a file as a header unit that, because it doesn't have the default extension (`.ixx`, `.cppm`, `.h`, `.hpp`), wouldn't normally be compiled into a header unit. This approach is demonstrated in this walkthrough. To get started, see [Approach 1: Choose individual header units to build](#approach1).
46
+
-**Build a shared header unit project**. We recommend this approach because it provides more control over the organization and reuse of the imported header units. Create a static library project that contains the header units that you want, and then reference it to import the header units. For a walkthrough of this approach, see [Build a header unit static library project for header units](walkthrough-import-stl-header-units.md#approach2).
47
47
48
-
-**Build a shared header unit project**. We recommend this approach because it provides more control over the organization and reuse of the imported header units. Create a static library project that contains the header units that you want and then reference it to import the header units. For a walkthrough of this approach, see [Build a header unit static library project for header units](walkthrough-import-stl-header-units.md#approach2).
48
+
-**Choose individual files to translate into header units**. This approach gives you file-by-file control over what is treated as a header unit. It's also useful when you must compile a file as a header unit that, because it doesn't have the default extension (`.ixx`, `.cppm`, `.h`, `.hpp`), wouldn't normally be compiled into a header unit. This approach is demonstrated in this walkthrough. To get started, see [Approach 1: Translate a specific file into a header unit](#approach1).
49
49
50
50
-**Automatically scan for and build header units**. This approach is convenient, but is best suited to smaller projects because it doesn't guarantee optimal build throughput. For details about this approach, see [Approach 2: Automatically scan for header units](#approach2).
51
51
52
-
- As mentioned in the introduction, you can build and import STL header files as header units, and automatically treat `#include` for STL library headers as `import` without rewriting your code. To see how, visit [Walkthrough: Import STL libraries as header units](walkthrough-import-stl-header-units.md).
52
+
- As mentioned in the introduction, you can build and import STL header files as header units and automatically treat `#include` for STL library headers as `import` without rewriting your code. To see how, visit [Walkthrough: Import STL libraries as header units](walkthrough-import-stl-header-units.md).
53
53
54
-
## <aname="approach1"></a>Approach 1: Choose header units to build
54
+
## <aname="approach1"></a>Approach 1: Translate a specific file into a header unit
55
55
56
56
This section shows how to choose a specific file to translate into a header unit. Compile a header file as a header unit using the following steps in Visual Studio:
57
57
@@ -85,7 +85,7 @@ This section shows how to choose a specific file to translate into a header unit
85
85
86
86
### Set project properties
87
87
88
-
To enable header units, first set the **C++ Language Standard** to [`/std:c++20`](./reference/std-specify-language-standard-version.md) or later by using the following steps:
88
+
To enable header units, first set the **C++ Language Standard** to [`/std:c++20`](./reference/std-specify-language-standard-version.md) or later with the following steps:
89
89
90
90
1. In **Solution Explorer**, right-click the project name and choose **Properties**.
91
91
1. In the left pane of the project property pages window, select **Configuration Properties** > **General**.
@@ -98,15 +98,15 @@ Compile the header file as a header unit:
98
98
99
99
:::image type="content" source="media/change-item-type.png" alt-text="Screenshot that shows changing the item type to C/C++ compiler.":::
100
100
101
-
When you build this project later in this walkthrough, `Pythagorean.h` will be translated into a header unit. It's translated because the item type for this header file is set to **C/C++ compiler**, and because the default action for `.h` and `.hpp` files set this way is to translate the file into a header unit.
101
+
When you build this project later in this walkthrough, `Pythagorean.h` will be translated into a header unit. It's translated into a header unit because the item type for this header file is set to **C/C++ compiler**, and because the default action for `.h` and `.hpp` files set this way is to translate the file into a header unit.
102
102
103
103
> [!NOTE]
104
104
> This isn't required for this walkthrough, but is provided for your information. To compile a file as a header unit that doesn't have a default header unit file extension, like `.cpp` for example, set **Configuration properties** > **C/C++** > **Advanced** > **Compile As** to **Compile as C++ Header Unit (/exportHeader)**:
105
105
> :::image type="content" source="media/change-compile-as.png" alt-text="Screenshot that shows changing Configuration properties > C/C++ > Advanced > Compile As to Compile as C++ Header Unit (/exportHeader).":::
106
106
107
-
### Change your code to import a header unit
107
+
### Change your code to import the header unit
108
108
109
-
1. In the source file for the example project, change `#include "Pythagorean.h"` to `import "Pythagorean.h";` Don't forget the trailing semicolon that's required for `import` statements. Because it's a header file in a directory local to the project, we used quotes with the `import` statement: `import "file";`. In your own projects, to compile a header unit from a system header, use angle brackets: `import <file>;`
109
+
1. In the source file for the example project, change `#include "Pythagorean.h"` to `import "Pythagorean.h";` Don't forget the trailing semicolon. It's required for `import` statements. Because it's a header file in a directory local to the project, we used quotes with the `import` statement: `import "file";`. In your own projects, to compile a header unit from a system header, use angle brackets: `import <file>;`
110
110
111
111
1. Build the solution by selecting **Build** > **Build Solution** on the main menu. Run it to see that it produces the expected output: `Pythagorean triple a:2 b:3 c:13`
112
112
@@ -118,12 +118,12 @@ If you're interested in specifically importing STL library headers as header uni
118
118
119
119
## <aname="approach2"></a>Approach 2: Automatically scan for and build header units
120
120
121
-
Because it takes time to first scan all of your source files for header units, and then build them, this approach is best suited for smaller projects. It doesn't guarantee optimal build throughput.
121
+
Because it takes time to scan all of your source files for header units, and time to build them, the following approach is best suited for smaller projects. It doesn't guarantee optimal build throughput.
122
122
123
123
This approach combines two Visual Studio project settings:
124
124
125
-
-**Scan Sources for Module Dependencies** causes the build system to call the compiler to ensure that all imported modules and header units are built before compiling the files that depend on them. When combined with **Translate Includes to Imports**, any header files included in your source that are also specified in a [`header-units.json`](./reference/header-unit-json-reference.md) file in the same directory as the header file, are compiled into header units.
126
-
-**Translate Includes to Imports** treats a header file as an `import` if the `#include` refers to a header file that can be compiled as a header unit (as specified in a `header-units.json` file), and a compiled header unit is available for the header file. Otherwise, the header file is treated as a normal `#include`. The [`header-units.json`](./reference/header-unit-json-reference.md) file is used to automatically build header units for each `#include` without symbol duplication.
125
+
-**Scan Sources for Module Dependencies** causes the build system to call the compiler to ensure that all imported modules and header units are built before compiling the files that depend on them. When combined with **Translate Includes to Imports**, any header files included in your source that are also specified in a [`header-units.json`](./reference/header-unit-json-reference.md) file located in the same directory as the header file, are compiled into header units.
126
+
-**Translate Includes to Imports** treats a header file as an `import` if the `#include` refers to a header file that can be compiled as a header unit (as specified in a `header-units.json` file), and a compiled header unit is available for the header file. Otherwise, the header file is treated as a normal `#include`. The [`header-units.json`](./reference/header-unit-json-reference.md) file is used to automatically build header units for each `#include`, without symbol duplication.
127
127
128
128
You can turn on these settings in the properties for your project. To do so, right-click the project in the **Solution Explorer** and choose **Properties**. Then choose **Configuration Properties** > **C/C++** > **General**.
Copy file name to clipboardExpand all lines: docs/build/walkthrough-import-stl-header-units.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -14,7 +14,7 @@ This walkthrough shows how to import C++ Standard Template Library (STL) librari
14
14
15
15
Importing an STL header as a header unit is simpler than using [precompiled header files](creating-precompiled-header-files.md). Header units are easier to set up and use, are substantially smaller on disk, provide similar performance benefits, and are more flexible than a [shared PCH](https://devblogs.microsoft.com/cppblog/shared-pch-usage-sample-in-visual-studio).
16
16
17
-
For more detailed information about what header units are and the benefits they provide, see [What is a header unit?](walkthrough-header-units.md#what-is-a-header-unit).
17
+
For more detailed information about what header units are and the benefits they provide, see [What is a header unit?](walkthrough-header-units.md#what-is-a-header-unit)
0 commit comments