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
- Specify which header files can be translated into header units when [`/translateInclude`](translateinclude.md) is specified.
15
+
- Minimize duplicated symbols to increase build throughput.
16
+
17
+
This file must be in the same directory as the included header file. This file is only used when [`/translateInclude`](translateinclude.md) is specified along with either `/scanDependencies` or [`/sourceDependencies:directives`](sourcedependencies-directives.md).
18
+
19
+
## Rationale
20
+
21
+
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
+
23
+
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:
24
+
25
+
```cpp
26
+
// a.h
27
+
28
+
#include"macros.h"// #defines MACRO=1
29
+
#ifdef MACRO
30
+
#include "b.h"
31
+
#endif
32
+
```
33
+
34
+
The `header-units.json` in this directory can contain `a.h` and `b.h`, but not `macros.h`. The `header-units.json` for this example would be similar to this:
35
+
36
+
```json
37
+
{
38
+
"Version": "1.0",
39
+
"BuildAsHeaderUnits": [
40
+
// macros.h should not be listed
41
+
"a.h",
42
+
"b.h"
43
+
]
44
+
}
45
+
```
46
+
47
+
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
+
49
+
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
+
51
+
### Preventing duplicated symbols
52
+
53
+
The `header-units.json` file is also important because it allows for automatic header unit creation without duplicated symbols. It does this by creating "atomic" header units for the files listed in `header-units.json`. The imported header units don't contain duplicated symbols from the various `#include` directives that were processed while translating the header file.
54
+
55
+
For example, consider two header files that both include a common header file. Both header files are included by the same source file:
56
+
57
+
```cpp
58
+
// a.h
59
+
#include"b.h"
60
+
61
+
// c.h
62
+
#include"b.h"
63
+
64
+
// Source.cpp
65
+
import"a.h";
66
+
import"c.h";
67
+
```
68
+
69
+
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.
70
+
71
+
But if there's a `header-units.json` in the `b.h` directory, and `/translateInclude` is specified, the following happens:
72
+
73
+
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.
74
+
1. The build system reads the dependency scan files and determines to build `b.h.ifc` first.
75
+
1. Then the build system adds `/headerUnit` for `b.h.ifc` to the command lines for compiling `a.h` and `c.h`. It calls the compiler to build the header units `a.h.ifc` and `c.h.ifc`. Because `/translateInclude` is specified, and `/headerUnit for b.h.ifc` is also specified, `a.h.ifc` and `c.h.ifc` won't contain `b.h` types, so there won't be any duplication in the produced header units.
76
+
77
+
## Schema
78
+
79
+
There's a `headerunits.json` file for the Standard Template Library (STL) headers. The build system uses it to determine whether to create a header unit for an STL header file, and for its dependencies. 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.
80
+
81
+
You can see the `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`
82
+
83
+
The `header-units.json` file starts with the schema version, followed by an array of filenames for headers that can be built into header units.
84
+
85
+
The schema also supports comments, as shown here:
86
+
87
+
```json
88
+
{
89
+
"Version": "1.0",
90
+
"BuildAsHeaderUnits": [
91
+
// "__msvc_all_public_headers.hpp", // for testing, not production
92
+
"__msvc_system_error_abi.hpp",
93
+
"__msvc_tzdb.hpp",
94
+
"__msvc_xlocinfo_types.hpp",
95
+
"algorithm",
96
+
"any",
97
+
"array",
98
+
"atomic",
99
+
"barrier",
100
+
"bit",
101
+
"bitset",
102
+
// "cassert", // design is permanently incompatible with header units
103
+
...
104
+
}
105
+
```
106
+
107
+
## Search rules
108
+
109
+
The compiler looks for this file in the same directory as the header file being processed. If your library is organized into subdirectories, each subdirectory needs its own `header-units.json` file.
110
+
111
+
## See also
112
+
113
+
[Walkthrough: Import STL libraries as header units](..\walkthrough-import-stl-header-units.md#approach1)\
114
+
[Walkthrough: Build and import header units in your Visual C++ projects](..\walkthrough-header-units.md)
description: "Use the /headerUnit compiler option to associate a header file with the header unit to import in its place."
4
-
ms.date: 04/13/2021
4
+
ms.date: 02/01/2022
5
5
f1_keywords: ["/headerUnit"]
6
6
helpviewer_keywords: ["/headerUnit", "Use header unit IFC"]
7
7
author: "tylermsft"
8
8
ms.author: "twhitney"
9
9
---
10
10
# `/headerUnit` (Use header unit IFC)
11
11
12
-
Used to import a header unit. Tells the compiler where to find the *`.ifc`* file (the binary representation of the header unit) for the specified header.
12
+
Imports a header unit. Tells the compiler where to find the *`.ifc`* file (the binary representation of the header unit) for the specified header.
13
13
14
14
## Syntax
15
15
@@ -27,45 +27,46 @@ The name of a file that contains compiled header unit information. To import mor
27
27
28
28
## Remarks
29
29
30
-
The **`/headerUnit`** compiler option requires the [`/std:c++20`](std-specify-language-standard-version.md) or later compiler option (such as **`/std:c++latest`**).
30
+
The **`/headerUnit`** compiler option requires [`/std:c++20`](std-specify-language-standard-version.md) or later.
31
31
32
-
The **`/headerUnit`** compiler option is available starting in Visual Studio 2019 version 16.10.
32
+
The **`/headerUnit`** compiler option is available in Visual Studio 2019 version 16.10 or later.
33
33
34
-
When the compiler comes across `import "file";` or `import <file>;`, this compiler option helps the compiler find the compiled header unit (*`.ifc`*) for the specified header file. The path to this file can be expressed in three ways:
34
+
When the compiler comes across `import "file";` or `import <file>;` this compiler option helps the compiler find the compiled header unit (*`.ifc`*) for the specified header file. The path to this file can be expressed in these ways:
35
35
36
-
**`/headerUnit`** looks up the compiled header unit in the current directory, or at the location specified in*`ifc-filename`*.
36
+
-**`/headerUnit`** looks up the compiled header unit in the current directory, or at the location specified by*`ifc-filename`*.
37
37
38
-
**`/headerUnit:quote`** looks up the compiled header unit file using the same rules as `#include "file"`.
38
+
-**`/headerUnit:quote`** looks up the compiled header unit file using the same rules as `#include "file"`.
39
39
40
-
**`/headerUnit:angle`** looks up the compiled header unit file using the same rules as `#include <file>`.
40
+
-**`/headerUnit:angle`** looks up the compiled header unit file using the same rules as `#include <file>`.
41
41
42
-
The compiler can't map a single *`header-name`* to multiple *`.ifc`* files. While mapping multiple *`header-name`* arguments to a single *`.ifc`* is possible, we don't recommend it. The contents of the *`.ifc`*get imported as if it was only the header specified by *`header-name`*.
42
+
The compiler can't map a single *`header-name`* to multiple *`.ifc`* files. Mapping multiple *`header-name`* arguments to a single *`.ifc`* is possible, but it isn't recommended. The contents of the *`.ifc`*are imported as if it was only the header specified by *`header-name`*.
43
43
44
-
The compiler implicitly enables the new preprocessor when this option is used. That is, [`/Zc:preprocessor`](zc-preprocessor.md) is added to the command line by the compiler if any form of `/headerUnit` is specified on the command line. To opt out of the implicit `/Zc:preprocessor`, specify: `/Zc:preprocessor-`
44
+
The compiler implicitly enables the new preprocessor when this option is used. If any form of `/headerUnit` is specified on the command line, then [`/Zc:preprocessor`](zc-preprocessor.md) is added to the command line by the compiler. To opt out of the implicit `/Zc:preprocessor`, specify: `/Zc:preprocessor-`
45
45
46
46
If you disable the new preprocessor, but a file you compile imports a header unit, the compiler will report an error.
47
47
48
48
### Examples
49
49
50
-
Given a project that references two header files and their header units, listed in this table:
50
+
Given a project that references two header files and their header units as listed in this table:
51
51
52
52
| Header file | IFC file |
53
53
|--|--|
54
54
|*`C:\utils\util.h`*|*`C:\util.h.ifc`*|
55
55
|*`C:\app\app.h`*|*`C:\app\app.h.ifc`*|
56
56
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 like this:
# `/sourceDependencies:directives` (List module and header unit dependencies)
11
11
12
-
This command-line option generates a JSON file that lists module and header-unit dependencies.
12
+
This command-line option scans source files and their `#include` statements to generate a JSON file that lists module export and imports. This information can be used by a build system to determine the build order of modules and header units.
13
13
14
-
It identifies which modules and header units need to be compiled before the project that uses them is compiled. For instance, it will list `import <library>;` or `import "library";` as a header unit dependency, and `import name;` as a module dependency.
14
+
This option differs from [`/sourceDependencies`](sourcedependencies.md) in the following ways:
15
15
16
-
This command-line option is similar to [`/sourceDependencies`](sourcedependencies.md), but differs in the following ways:
17
-
18
-
- The compiler doesn't produce compiled output. Instead, the files are scanned for module directives. No compiled code, modules, or header units are produced.
16
+
- The compiler doesn't produce compiled output. No compiled code, modules, or header units are produced. Instead, the files are scanned for module directives.
17
+
- The JSON format is different from what `/sourceDependencies` produces. The `/sourceDependencies` option is intended to be used with other build tools, such as CMake.
19
18
- The output JSON file doesn't list imported modules and imported header units (*`.ifc`* files) because this option does a scan of the project files, not a compilation. So there are no built modules or header units to list.
20
19
- Only directly imported modules or header units are listed. It doesn't list the dependencies of the imported modules or header units themselves.
21
-
- Header file dependencies are not listed. That is, `#include <file>` or `#include "file"` dependencies are not listed.
20
+
- Header file dependencies aren't listed. That is, `#include <file>` or `#include "file"` dependencies aren't listed.
22
21
-`/sourceDependencies:directives` is meant to be used before *`.ifc`* files are built.
22
+
-`/sourceDependencies` causes the compiler to report all of the files, such as `#includes`, `.pch` files, `.ifc` files, and so on, that were used for a particular translation unit, whereas `/sourceDependencies:directives [file1]` scans the specified source file and reports all `import` and `export` statements. `/sourceDependencies` can be used with `/sourceDependencies:directives`.
23
23
24
24
## Syntax
25
25
@@ -40,14 +40,16 @@ If the argument is a directory, the compiler generates source dependency files i
40
40
41
41
## Remarks
42
42
43
-
**`/sourceDependencies:directives`** is available starting in Visual Studio 2019 version 16.10. It's not enabled by default.
43
+
**`/sourceDependencies:directives`** is available starting in Visual Studio 2019 version 16.10.
44
44
45
-
When you specify the **`/MP`**compiler option, we recommend you use **`/sourceDependencies`** with a directory argument. If you provide a single filename argument, two instances of the compiler may attempt to open the output file simultaneously and cause an error. For more information on **`/MP`**, see [`/MP` (Build with multiple processes)](mp-build-with-multiple-processes.md).
45
+
When you specify the [`/MP` (Build with multiple processes)](mp-build-with-multiple-processes.md)compiler option, specify the output file location for **`/sourceDependencies:directives`** with a directory argument. The compiler will produce `[directory]\[source file name with extension].module.json` for each source file.
46
46
47
47
When a non-fatal compiler error occurs, the dependency information still gets written to the output file.
48
48
49
49
All file paths appear as absolute paths in the output.
50
50
51
+
This switch can be used with [`/translateInclude`](translateinclude.md).
This command line produces a JSON file *`output.json`*with content like:
75
+
produces a JSON file *`output.json`*similar to:
72
76
73
77
```JSON
74
78
{
@@ -88,17 +92,19 @@ This command line produces a JSON file *`output.json`* with content like:
88
92
}
89
93
```
90
94
91
-
We've used `...` to abbreviate the reported paths. The report will contain the absolute paths. The paths reported depend on where the compiler finds the dependencies. If the results are unexpected, you may want to check your project's include path settings.
95
+
For brevity, the previous example uses `...` to abbreviate the reported paths. The report contains the absolute paths. The paths reported depend on where the compiler finds the dependencies. If the results are unexpected, you might want to check your project's include path settings.
92
96
93
97
`ProvidedModule` lists exported module or module partition names.
94
98
95
-
No *`.ifc`* files are listed in the output because they weren't built. Unlike `/sourceDependencies`, the compiler doesn't produce compiled output when `/sourceDependencies:directives` is specified, so no compiled modules or header units are produced to import.
99
+
No *`.ifc`* files are listed in the output because they weren't built. Unlike `/sourceDependencies`, the compiler doesn't produce compiled output when `/sourceDependencies:directives` is specified, so no compiled modules or header units are produced.
96
100
97
101
## To set this compiler option in Visual Studio
98
102
99
-
You normally shouldn't set this yourself in the Visual Studio development environment. It is set by the build system.
103
+
You normally shouldn't set this yourself in the Visual Studio development environment. It's set by the build system.
0 commit comments