Skip to content

Commit 0cf5c42

Browse files
TylerMSFTTylerMSFT
authored andcommitted
acrolinx and link cleanup
1 parent 3f4d09f commit 0cf5c42

5 files changed

Lines changed: 30 additions & 30 deletions

File tree

‎docs/build/reference/headerunit.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Given a project that references two header files and their header units, listed
5454
| *`C:\utils\util.h`* | *`C:\util.h.ifc`* |
5555
| *`C:\app\app.h`* | *`C:\app\app.h.ifc`* |
5656

57-
The compiler options to reference the header units for these particular header files would look similar to this:
57+
The compiler options to reference the header units for these particular header files would look similar to:
5858

5959
```CMD
6060
cl ... /std:c++latest /headerUnit C:\utils\util.h=C:\util.h.ifc /headerUnit:quote app.h=app.h.ifc

‎docs/build/reference/translateinclude.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ Instructs the compiler to treat `#include` as `import` for those headers that ha
1919

2020
The **`/translateInclude`** compiler option requires you enable the [/std:c++20](std-specify-language-standard-version.md) or later option (such as **`/std:c++latest`**). `/translateInclude` is available starting in Visual Studio 2019 version 16.10.
2121

22-
This switch only applies to `#include` statements, and only to those that are specified in a `header-unit.json` file that lists which header files can be compiled into header units. The `header-unit.json` file must be in the same directory as the included file. You can see an example of a `header-units.json` file under the installation directory for Visual Studio (`%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.30.30705\include\header-units.json`). That `header-units.json` file is used by the build system to determine whether a Standard Template Library header can be compiled as a header unit. If the #include file isn't listed, it is treated as a normal #include. Otherwise, the included header file will be compiled into a header unit and treated as an `import`.
23-
This doesn't require scan dependencies to be turned on. You do not need the IDE project setting **Scan Sources for Module Dependencies** enabled for this because the build system performs a scan automatically when `/translateInclude` is specified.
22+
This switch only applies to `#include` statements, and only to those that are specified in a `header-unit.json` file that lists which header files can be compiled into header units. The `header-unit.json` file must be in the same directory as the included file. You can see an example of a `header-units.json` file under the installation directory for Visual Studio (`%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.30.30705\include\header-units.json`). That `header-units.json` file is used by the build system to determine whether a Standard Template Library header can be compiled as a header unit. If the #include file isn't listed, it's treated as a normal #include. Otherwise, the included header file will be compiled into a header unit and treated as an `import`.
23+
This doesn't require scan dependencies to be turned on. You don't need the IDE project setting **Scan Sources for Module Dependencies** enabled for this because the build system does a scan automatically when `/translateInclude` is specified.
2424

2525
The **`/translateInclude`** option effectively makes the following transformation, where the example `<vector>` has been prebuilt into an importable header unit:
2626

‎docs/build/walkthrough-header-units.md‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ To use header units, you need Visual Studio 2019 16.10 or later.
2222

2323
A header unit is a binary representation of a header file. A header unit ends with an *`.ifc`* extension. This format is also used for named modules.
2424

25-
An important difference between a header unit and a header file is that header units aren't affected by macro definitions outside of the header unit. That is, you can't `#define` a symbol that causes the header unit to behave differently when you import it because by the time you import the header unit, the header unit has already been compiled. This is different than how an `#include` file is treated because the included file can be affected by a macro definition outside of the header unit. This is because it is not already compiled and will be run through the preprocessor when it is included.
25+
An important difference between a header unit and a header file is that header units aren't affected by macro definitions outside of the header unit. That is, you can't `#define` a symbol that causes the header unit to behave differently when you import it because by the time you import the header unit, the header unit has already been compiled. This is different than how an `#include` file is treated because the included file can be affected by a macro definition outside of the header unit. This is because it isn't already compiled and will be run through the preprocessor when it's included.
2626

27-
A related benefit of header units is that they can be imported in any order without affecting each other. This is not true of header files brought in with `#include` because macro definitions defined in one header file may affect a subsequent header file.
27+
A related benefit of header units is that they can be imported in any order without affecting each other. This isn't true of header files brought in with `#include` because macro definitions defined in one header file may affect a subsequent header file.
2828

2929
Everything visible from a header file is also visible from a header unit, including macros defined within the header unit.
3030

@@ -38,15 +38,15 @@ Another advantage of header units over PCH is that there's more flexibility for
3838

3939
Finally, header units are more flexible than a PCH. With a PCH you can't choose to select to bring in only one of the headers in the PCH; the compiler must bring them all in. 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.
4040

41-
Header units are a transition step between header files and C++ 20 modules. They provide some of the benefits of modules in terms of being more robust by not being affected by outside macro definitions, you can import them in any order without affecting each other, the compiler can process them faster than header files, and so on. But they don't have all of the advantages as they expose the macros defined within them (modules don't) and unlike modules there is no way to hide private implementation. With header files, for private implementation we do things like create names with leading underscores or put things in an implementation namespace that is meant to indicate that it is private implementation code. A module doesn't expose private implementation available in any form.
41+
Header units are a transition step between header files and C++ 20 modules. They provide some of the benefits of modules in terms of being more robust by not being affected by outside macro definitions, you can import them in any order without affecting each other, the compiler can process them faster than header files, and so on. But they don't have all of the advantages as they expose the macros defined within them (modules don't) and unlike modules there's no way to hide private implementation. With header files, for private implementation we do things like create names with leading underscores or put things in an implementation namespace that is meant to indicate it's private implementation code. A module doesn't expose private implementation available in any form.
4242

4343
Consider replacing your PCH implementation with header units. You'll get the same speed advantage, but other code hygiene and flexibility benefits as well.
4444

4545
## Ways to compile a header unit
4646

4747
There are several ways to compile a file into a header unit:
4848

49-
- **Choose individual header units to build**. This approach gives you file-by-file control over what is treated as a header unit. It is also useful when you need to compile a file as a header unit that, because of its extension, wouldn't normally be picked up as a header unit. This approach is demonstrated in this walkthrough. See [Choose individual header units to build](#approach1) for details.
49+
- **Choose individual header units to build**. This approach gives you file-by-file control over what is treated as a header unit. It's also useful when you need to compile a file as a header unit that, because of its extension, wouldn't normally be picked up as a header unit. This approach is demonstrated in this walkthrough. See [Choose individual header units to build](#approach1) for details.
5050

5151
- **Build a shared header unit project**. This is the recommended approach and provides more control over the organization 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 information about this approach, see [Build a header unit static library project for header units](walkthrough-import-stl-header-units.md#approach2).
5252

@@ -120,17 +120,17 @@ If you want to convert only a few header files to header units, this approach is
120120
This approach is best suited to smaller projects because it can't guarantee optimal build throughput. That's because it scans all of your source files to find and build header imports from `#include` files in your source.
121121

122122
This approach combines two Visual Studio project settings:
123-
- **Scan Sources for Module Dependencies** scans your project for any files, and their dependencies, that may be treated as header units but might normally be identified as header units. For those files that can be treated as header units, they are compiled as header units and imported.
124-
- **Translate Includes to Imports** so that you don't have to change your code from `#include` to `import` for files that can be treated as header units. If an `#include` refers to a header unit that exists (there is an `.IFC` for it), or to a known header unit that can be built from an `#include` file (as specified in a `header-units.json` file) then the `#include` will be treated as `import`. Otherwise, it acts as a normal `#include`.
123+
- **Scan Sources for Module Dependencies** scans your project for any files, and their dependencies, that may be treated as header units but might normally be identified as header units. For those files that can be treated as header units, they're compiled as header units and imported.
124+
- **Translate Includes to Imports** so that you don't have to change your code from `#include` to `import` for files that can be treated as header units. If an `#include` refers to a header unit that exists (there's an `.IFC` for it), or to a known header unit that can be built from an `#include` file (as specified in a `header-units.json` file) then the `#include` will be treated as `import`. Otherwise, it acts as a normal `#include`.
125125

126126
You can turn on these settings in the properties for the project (right-click the project in the **Solution Explorer** and choose **Properties**):
127127

128128
:::image type="content" source="media/vs2019-scan-module-dependencies.png" alt-text="Screenshot that shows the project properties screen with Configuration highlighted and All Configurations selected. Under C/C++ > General, Scan Sources for Module Dependencies is highlighted and set to yes, and Translate Includes to Imports is highlighted and set to Yes (/translateInclude)":::
129129

130130
There are conditions under which these settings work to automatically build and import header units. They are:
131131

132-
- **Scan Sources for Module Dependencies** scans your sources for `#import "header";` and `import <header>;` statements. If a `.cpp` file has `import <someFile.h>;`, but `someFile.h` is not part of this or a referenced project, or isn't marked to be built as a header unit (as described in this walkthrough above), then the build system will scan the `.cpp` file, identify that `someFile.h` should be imported, and attempt to build `someFile.h`into a header unit and import it. It makes the build scan all C++ sources, not just module interface and header unit sources, for module and header units dependencies. It saves you the step of specifying in the IDE that a file be compiled as a header unit for those that wouldn't compile as a header unit by default due to its file extension not matching what the build system is normally looking for. This settings only affects `import` statements. You can combine this setting with **Translate Includes to Imports** so that `#include` directives are also be treated as import statements. But whether the `#include` directives are treated as header units or not is subject to the conditions described in the next paragraph.
133-
- **Translate Includes to Imports** requires a list of which header files can be compiled into header units. This list is in the form of a [`header-units.json`](header-unit-json-reference.md) file that must be in the same directory as the included file. You can see an example of a `header-units.json` file under the installation directory for Visual Studio. For example, `%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.30.30705\include\header-units.json` is used by the build system when determining whether a Standard Template Library header can be compiled as a header unit. This functionality exists to serve as a bridge between using header units with legacy code to get some benefits of modules in the process. You don't need **Scan for dependencies** enabled for `/translateInclude` to work. The build system will perform a scan for `#include` statements when `/translateInclude` is specified. It's just that **Scan for dependencies** ensures that all the header units that can be found will be found, as described above.
132+
- **Scan Sources for Module Dependencies** scans your sources for `#import "header";` and `import <header>;` statements. If a `.cpp` file has `import <someFile.h>;`, but `someFile.h` isn't part of this or a referenced project, or isn't marked to be built as a header unit (as described in this walkthrough above), then the build system will scan the `.cpp` file, identify that `someFile.h` should be imported, and attempt to build `someFile.h`into a header unit and import it. It makes the build scan all C++ sources, not just module interface and header unit sources, for module and header units dependencies. It saves you the step of specifying in the IDE that a file be compiled as a header unit for those that wouldn't compile as a header unit by default because its file extension doesn't match what the build system is normally looking for. This setting only affects `import` statements. You can combine this setting with **Translate Includes to Imports** so that `#include` directives are treated as `import` statements if possible. Whether the `#include` directives are treated as header units or not is subject to the conditions described in the next paragraph.
133+
- **Translate Includes to Imports** requires a list of which header files can be compiled into header units. This list is in the form of a [`header-units.json`](./reference/header-unit-json-reference.md) file that must be in the same directory as the included file. You can see an example of a `header-units.json` file under the installation directory for Visual Studio. For example, `%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.30.30705\include\header-units.json` is used by the build system when determining whether a Standard Template Library header can be compiled as a header unit. This functionality exists to serve as a bridge between using header units with legacy code to get some benefits of modules in the process. You don't need **Scan for dependencies** enabled for `/translateInclude` to work. The build system does a scan for `#include` statements when `/translateInclude` is specified. It's just that **Scan for dependencies** ensures that all the header units that can be found will be found, as described above.
134134

135135
These switches and the `header-unit.json` provide some of the benefits of header units. The convenience comes at the cost of build throughput. This approach might not be the best for larger projects because it doesn't guarantee optimal build times. The same header files may be encountered and reprocessed repeatedly, which will increase build time. However, the convenience may be worth it to you depending on your project.
136136

‎docs/build/walkthrough-import-stl-header-units.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ This walkthrough shows how to import C++ Standard Template Library (STL) librari
1313

1414
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 than a shared precompiled header file (PCH), but provide similar performance benefits.
1515

16-
For more detailed information about what header units are and the benefits they provide, see [What is a header unit?](walkthrough-import-stl-header-units.md#what-is-a-header-unit)
16+
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)
1717

1818
## Prerequisites
1919

@@ -165,11 +165,11 @@ To access this setting:
165165
166166
At the beginning of this topic, another approach to importing STL libraries as header units was mentioned. That's to have Visual Studio scan for the STL headers you `#include` in your project and compile them into header units. The compiler will then import rather than include those headers.
167167
168-
This option is convenient when your project includes many STL header files across many files, or when build throughput isn't critical. This option doesn't guarantee that a header unit for a particular header will be built only once. But it is useful if you have a large codebase because you don't have to change your source code to take advantage of the benefits of header units for most of the STL libraries you use.
168+
This option is convenient when your project includes many STL header files across many files, or when build throughput isn't critical. This option doesn't guarantee that a header unit for a particular header will be built only once. But it's useful if you have a large codebase because you don't have to change your source code to take advantage of the benefits of header units for most of the STL libraries you use.
169169
170170
This approach is less flexible than the static library approach because it doesn't lend itself towards reusing the built header units in other projects. This approach might not be appropriate for larger projects because it doesn't guarantee an optimal build time since all of the sources need to be scanned for `#include` statements.
171171
172-
Not all header files can be automatically converted to header units. For example, headers that depend on conditional compilation via `#define` won't as header units. There's an allowlist for the STL headers that the build system uses when `/translateInclude` is specified to determine which STL headers can be compiled into header units. The `header-units.json` file is under the installation directory for Visual Studio. For example, `%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.30.30705\include\header-units.json` It's consulted before the build system attempts to create a header unit for an STL header file, and also when dependencies are resolved for an STL header file. If the STL header file isn't on the list, it's treated as a normal `#include` instead of importing it as a header unit.
172+
Not all header files can be automatically converted to header units. For example, headers that depend on conditional compilation via `#define` won't be converted to header units. There's an allowlist for the STL headers that the build system uses when `/translateInclude` is specified to determine which STL headers can be compiled into header units. The `header-units.json` file is under the installation directory for Visual Studio. For example, `%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.30.30705\include\header-units.json` It's consulted before the build system attempts to create a header unit for an STL header file, and also when dependencies are resolved for an STL header file. If the STL header file isn't on the list, it's treated as a normal `#include` instead of importing it as a header unit.
173173
174174
To demonstrate this approach, we'll create a project that includes two STL libraries and then change the project properties so that it imports the libraries as header units instead of including them. We'll do it without changing the code.
175175

0 commit comments

Comments
 (0)