diff --git a/docs/build/cmake-presets-json-reference.md b/docs/build/cmake-presets-json-reference.md new file mode 100644 index 00000000000..a96f9a174bd --- /dev/null +++ b/docs/build/cmake-presets-json-reference.md @@ -0,0 +1,118 @@ +--- +description: "Schema reference for `CMakePresets.json` and `CMakeUserPresets.json` Microsoft vendor maps" +title: "CMakeUserPresets.json" +ms.date: "4/13/2021" +helpviewer_keywords: ["CMake in Visual C++"] +--- +# `CMakePresets.json` and `CMakeUserPresets.json` Microsoft vendor maps + +CMake supports two files, `CMakePresets.json` and `CMakeUserPresets.json`, that allow users to specify common configure, build, and test options and share them with others. + +`CMakePresets.json` and `CMakeUserPresets.json` can be used to drive CMake in Visual Studio, in Visual Studio Code, in a Continuous Integration (CI) pipeline, and from the command line. + +`CMakePresets.json` is intended to save project-wide builds, and `CMakeUserPresets.json` is intended for developers to save their own local builds. The schema for both files is identical. + +`CMakePresets.json` and `CMakeUserPresets.json` support vendor maps to store vendor-specific information. Microsoft maintains two vendor maps with options specific to Visual Studio and Visual Studio Code. Here we document two Microsoft vendor maps and vendor macros. For documentation about the rest of the schema, including Configure Presets, Build Presets, and Test Presets, see the official [CMake documentation](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html). + +For more information about how to use `CMakePresets.json` in Visual Studio, see [Configure and build with CMake Presets in Visual Studio](cmake-presets-vs.md) + +For more information about how to use `CMakePresets.json` in Visual Studio Code, see [Configure and build with CMake Presets in VS Code](https://github.com/microsoft/vscode-cmake-tools/blob/develop/docs/cmake-presets.md) + +## Visual Studio Settings vendor map + +One vendor map with the vendor URI `microsoft.com/VisualStudioSettings/CMake/` is allowed per Configure Preset and contains options specific to CMake integration in Visual Studio and Visual Studio Code. All options in the vendor map apply to Visual Studio. Options that apply to both Visual Studio and Visual Studio Code have been explicitly marked. + +All settings in the Visual Studio Settings vendor map are optional and inherited from Configure Presets specified by the `inherits` key. Only options that have been modified are written to the file. The Visual Studio Settings vendor map is supported by both `CMakePresets.json` and `CMakeUserPresets.json`. + +None of the options in the Visual Studio Settings vendor map impact the construction of the CMake or CTest command line. This ensures that the same `CMakePresets.json` file can be used to drive CMake with Visual Studio, Visual Studio Code, and from the command line. The exceptions to this are the `cacheRoot` and `cmakeGenerateCommand` options. These options are specific to the [Open Existing Cache](https://devblogs.microsoft.com/cppblog/open-existing-cmake-caches-in-visual-studio/) scenario in Visual Studio and cannot be reproduced from the command line. + +| Setting | Description | +|--|--| +| `hostOS` | An array of supported operating systems (OS). Accepted values are `Windows`, `Linux`, and `macOS`.

The value of `hostOS` is used by Visual Studio and Visual Studio Code to hide Configure Presets that don't apply to the OS of the target system and provide a better user experience.

If `hostOS` is unspecified, then Visual Studio and Visual Studio Code will always show all Configure Presets for selection. This field can also be a string, which is equivalent to an array containing one string

This option is supported by both Visual Studio and Visual Studio Code. | +| `intelliSenseMode` | Specifies the mode used for computing IntelliSense information in Visual Studio with the format `--`.

Accepted values:

`android-clang-arm`
`android-clang-arm64`
`android-clang-x6`
`android-clang-x86`
`ios-clang-ar`
`ios-clang-arm64`
`ios-clang-x6`
`ios-clang-x86`
`linux-gcc-arm`
`linux-gcc-x64`
`linux-gcc-x86`
`windows-clang-arm`
`windows-clang-arm64`
`windows-clang-x64`
`windows-clang-x86`
`windows-msvc-arm`
`windows-msvc-arm64`
`windows-msvc-x64`
`windows-msvc-x86`

If `intelliSenseMode` is unspecified, then Visual Studio will use the IntelliSense mode that matches your specified compilers and target architecture. `intelliSenseMode` is usually used to provide accurate IntelliSense for cross-compilation.

In Visual Studio 2019, you must explicitly specify a clang IntelliSense mode when building with clang or clang-cl. | +| `intelliSenseOptions` | A map of additional IntelliSense configuration options.

`useCompilerDefaults`: A `bool` that specifies whether to use the compilers’ default defines and include paths for IntelliSense. Should only be `false` if the compilers in use don't support gcc-style arguments. Defaults to `true`.

`additionalCompilerArgs`: An array of additional options to control IntelliSense in Visual Studio. This option supports macro expansion. | +| `enableMicrosoftCodeAnalysis` | A `bool` that enables Microsoft code analysis in Visual Studio when building with `cl` or `clang-cl`. Defaults to `false`. | +| `codeAnalysisRulset` | Specifies the ruleset to use when running Microsoft code analysis in Visual Studio. This can be a path to a ruleset file, or the name of a ruleset file installed with Visual Studio. This option supports macro expansion. | +| `disableExternalAnalysis` | A `bool` that specifies whether code analysis should run on external headers in Visual Studio. | +| `codeAnalysisExternalRuleset` | Specifies the ruleset to use when running Microsoft code analysis on external header in Visual Studio. This can be a path to a ruleset file, or the name of a ruleset file installed with Visual Studio. This option supports macro expansion. | +| `enableClangTidyCodeAnalysis` | A bool that enables clang-tidy code analysis in Visual Studio when building with `clang-cl`. Defaults to `false`. | +| `clangTidyChecks` | A comma-separated list of warnings passed to clang-tidy when running clang-tidy code analysis in Visual Studio. Wildcards are allowed, and the `–` prefix will remove checks. | +| `cacheRoot` | Specifies the path to a CMake cache. This directory should contain an existing `CMakeCache.txt` file. This key is only supported by the Open Existing Cache scenario in Visual Studio. This option supports macro expansion. | +| `cmakeGenerateCommand` | A command-line tool (specified as a command-line program + arguments, for example, "gencache.bat debug") to generate the CMake cache. This command will run from the shell in the preset’s specified environment when CMake configure is invoked. This key is only supported by the [Open Existing Cache](https://devblogs.microsoft.com/cppblog/open-existing-cmake-caches-in-visual-studio/) scenario in Visual Studio. This option supports macro expansion | + +## Visual Studio Remote Settings vendor map + +One vendor map with the vendor URI ` microsoft.com/VisualStudioRemoteSettings/CMake/` is allowed per Configure Preset and contains options specific to remote development in Visual Studio. Remote development means you're invoking CMake on a remote SSH connection or WSL. None of the options in the Visual Studio Remote Settings vendor map apply to Visual Studio Code. + +All settings in the Visual Studio Remote Settings vendor map are optional and inherited from Configure Presets specified by the `inherits` key. Only options that have been modified are written to the file. The Visual Studio Remote Settings vendor map is supported by both `CMakePresets.json` and `CMakeUserPresets.json`. + +None of the options in the Visual Studio Settings vendor map impact the construction of the CMake or CTest command line. This ensures that the same `CMakePresets.json` file can be used to drive CMake with Visual Studio, Visual Studio Code, and from the command line. + +Many of the options in the Visual Studio Remote Settings vendor map are ignored when targeting WSL1. This is because the WSL1 toolset executes all commands locally and relies on Windows drives mounted under the `/mnt` folder to access local source files from WSL1. No source file copy is required. Options that are ignored when targeting WSL1 have been explicitly marked. + +| Setting | Description | +|--|--| +|`sourceDir` | Path to the directory on the remote system where the project will be copied. Defaults to `$env{HOME}/.vs/$ms{projectDirName}`. This option supports macro expansion.

In remote copy scenarios, the macro` ${sourceDir}` evaluates to the project source directory on the remote system and not the project source directory on the Windows machine. Remote copy scenarios include targeting a remote SSH connection. In these cases, the project source directory on the remote system will be determined by the value of sourceDir in the Visual Studio Remote Settings vendor map. This option is ignored when targeting WSL1. | +|`copySources` | If `true`, Visual Studio will copy sources from Windows to the remote system. Set to `false` if you manage file synchronization yourself. Defaults to true. This option is ignored when targeting WSL1. | +|`copySourcesOptions` | An object of options related to the source copy from Windows to the remote system. This object is ignored when targeting WSL1.

`copySourcesOptions.exclusionList`: A list of paths to be excluded when copying source files to the remote system. A path can be the name of a file or directory, or a path relative to the root of the copy. Defaults to `[ ".vs", ".git", "out" ]`. This option supports macro expansion.

`copySourcesOptions.method`: The method used to copy source files to the remote system. Accepted values are `rsync` and `sftp`. Defaults to `rsync`.

`copySourcesOptions.concurrentCopies`: The number of concurrent copies used during the synchronization of sources to the remote system. Defaults to `5`.

`copySourcesOptions.outputVerbosity`: The verbosity level of source copy operations to the remote system. Accepted levels are `Normal`, `Verbose`, and `Diagnostic`. Defaults to `Normal`.| +|`rsyncCommandArgs` | A list of additional command-line arguments passed to `rsync`. Defaults to `[ "-t", "--delete", "--delete-excluded" ]`. This option supports macro expansion and is ignored when targeting WSL1. | +|`copyBuildOutput` | Specifies whether to copy build output from the remote system back to Windows. Defaults to `false`. This option is ignored when targeting WSL1. | +|`copyOptimizations` | An object of options related to source copy optimizations. These options are ignored when targeting WSL1.

`copyOptimizations.maxSmallChange`: The maximum number of files to copy using sftp instead of rsync. Defaults to 10.

`copyOptimizations.useOptimizations`: Specifies the copy optimizations in use. Accepted values are no copy optimizations (`None`), rsync only optimizations (`RsyncOnly`), or rsync and sftp optimizations (`RsyncAndSftp`). Defaults to `RsyncAndSftp`.

`copyOptimizations.rsyncSingleDirectoryCommandArgs`: A list of additional command-line arguments passed to rsync when copying the contents of a single directory to the remote system. Defaults to `[ "-t", "-d" ]`. This option supports macro expansion. | +|`copyAdditionalIncludeDirectoriesList` | A list of paths to remote header directories to be copied locally for IntelliSense. This option supports macro expansion. | +|`copyExcludeDirectoriesList` | A list of paths to remote header directories to not be copied locally for IntelliSense. This option supports macro expansion. | +|`forceWSL1Toolset` | If `true`, Visual Studio will always use the WSL1 toolset when targeting WSL from Visual Studio. The WSL1 toolset executes all commands locally and relies on Windows drives mounted under the `/mnt` folder to access local source files from WSL. These options may be slower with WSL2. Defaults to `false`.

The WSL1 toolset will always be used in Visual Studio 2019 version 16.10. This option will be relevant once native support for WSL2 is available. | + +## Remote pre-build and post-build events + +Options for a `remotePrebuildEvent` and `remotePostbuildEvent` have been deprecated with the adoption of `CMakePresets.json`. + + Encode pre-build, pre-link, and post-build events in your CMakeLists.txt using [add_custom_command](https://cmake.org/cmake/help/latest/command/add_custom_command.html#build-events). This will ensure the same behavior when building with Visual Studio and from the command line. + +If you need behavior that is specific to Visual Studio, you can add a custom remote task in` tasks.vs.json`. To get started, right-click on your root `CMakeLists.txt` in the **Solution Explorer** from **Folder View** and select **Configure Tasks**. You can then [add a new remote task](https://docs.microsoft.com/cpp/build/tasks-vs-json-schema-reference-cpp#remote-properties) to your `tasks.vs.json` file. + +The following remote task creates a directory called test on the remote Linux system: + +```json +{ + "taskLabel": "mkdir", + "appliesTo": "CMakeLists.txt", + "type": "remote", + "command": "mkdir test", + "remoteMachineName": "localhost" + } +``` + +Right-click on any `CMakeLists.txt` and select the **mkdir** option to execute this task. + +The value of `remoteMachineName` must match the Host Name of a connection in the **Connection Manager**. + +## Microsoft vendor macros + +The two Microsoft vendor maps, `Visual Studio Settings` and `Visual Studio Remote Settings`, support all the macros defined by CMake. Our vendor maps support all the macros defined by CMake. See [cmake-presets Macro Expansion](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html#macro-expansion) for more information. All macros and environment variables are expanded before being passed to `cmake.exe`. + +Visual Studio supports vendor macros with the prefix `ms`. Microsoft vendor macros can only be used in Microsoft vendor maps. CMake can't use presets that have vendor macros outside of a vendor map. + +|Macro |Description | +|---------|---------| +|`$ms{projectDirName}`| Evaluates to the name of the open folder in Visual Studio. This macro is used to set the default value of `sourceDir` in remote copy scenarios. This macro is not supported by Visual Studio Code. Use `${sourceDirName}` instead. | + +## Environment variables + +|Macro |Description | +|---------|---------| +| `$env{}`
`$penv{}`| Reference environment variables using this syntax supported by CMake. See [cmake-presets Macro Expansion](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html#macro-expansion) for more information. | + +## Deprecated macros + +A few macros that were supported by CMakeSettings.json have been deprecated with the adoption of `CMakePresets.json`. + +Use the macros supported by CMake to construct your file paths. This will ensure that the same `CMakePresets.json` file works inside Visual Studio and from the command line. + +| Deprecated macro | Recommendation | +|---------|---------| +|`${projectFile} ` | `${sourceDir}/CMakeLists.txt` | +| `${thisFile}` | ` ${sourceDir}/CMakePresets.json` | + +## Accepted shell syntax + +Use the `$env{HOME}` syntax to reference `$HOME` when constructing Linux paths in the Microsoft vendor maps. \ No newline at end of file diff --git a/docs/build/cmake-presets-vs.md b/docs/build/cmake-presets-vs.md new file mode 100644 index 00000000000..8edfe28df59 --- /dev/null +++ b/docs/build/cmake-presets-vs.md @@ -0,0 +1,435 @@ +--- +title: Configure and build with CMake Presets +description: "Reference for using CMake Presets to configure and build CMake projects." +ms.topic: reference +ms.date: "04/13/2020" +--- + +# Configure and build with CMake Presets in Visual Studio + +CMake supports two files, `CMakePresets.json` and `CMakeUserPresets.json`, that allow users to specify common configure, build, and test options and share them with others. + +Use `CMakePresets.json` and `CMakeUserPresets.json` to drive CMake in Visual Studio and Visual Studio Code, in a Continuous Integration (CI) pipReline, and from the command line. `CMakePresets.json` is intended to save project-wide builds, and `CMakeUserPresets.json` is intended for developers to save their own local builds. `CMakePresets.json` is supported in Visual Studio 2019 version 16.10 or later. + +This article contains information about `CMakePresets.json` integration Visual Studio. +- For more information about the format of `CMakePresets.json`, see the official [CMake documentation](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html#id1). +- For more information about the Microsoft vendor maps and macro expansion, see [`CMakePresets.json` and `CMakeUserPresets.json` Microsoft vendor maps](cmake-presets-json-reference.md). +- For more information about how to use `CMakePresets.json` in Visual Studio Code, see [Configure and build with CMake Presets](https://github.com/microsoft/vscode-cmake-tools/tree/develop/docs/cmake-presets.md). + + `CMakePresets.json` is a recommended alternative to `CMakeSettings.json`. Visual Studio will never read from both `CMakePresets.json` and `CMakeSettings.json` at the same time. See [Enable `CMakePresets.json` in Visual Studio 2019](#enable-cmakepresetsjson-integration-in-visual-studio-2019) to enable or disable `CMakePresets.json` integration in Visual Studio. + +## Supported CMake and `CMakePresets.json` versions + +Visual Studio supports `CMakePresets.json` and `CMakeUserPresets.json` files version 2 or higher. You can update your file version by incrementing the version field in the root object. For an example and more information, see [`CMakePresets.json` format](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html#format). + +CMake version 3.20 or higher is required when invoking CMake with `CMakePresets.json` (version 2 or higher) from the command line. However, Visual Studio reads and evaluates `CMakePresets.json` and `CMakeUserPresets.json` itself and doesn't invoke CMake directly with the `--preset` option. This means CMake version 3.20 or higher isn't strictly required when building with `CMakePresets.json` inside Visual Studio. We recommend using at least CMake version 3.14 or higher. + +## Enable `CMakePresets.json` integration in Visual Studio 2019 + +`CMakePresets.json` integration isn't enabled by default in Visual Studio 2019. You can enable it for all CMake projects in **Tools** > **Options** > **CMake** > **General**: + +![Enable `CMakePresets.json` in CMake options > General](./media/enable-cmakepresets.png) + +> [!Important] +> Close and reopen the folder in Visual Studio to activate the integration. + +If you don't want to enable `CMakePresets.json` integration for all CMake projects, then you can enable `CMakePresets.json` integration for a single CMake project by adding a `CMakePresets.json` file to the root of the open folder. You must close and reopen the folder in Visual Studio to activate the integration. + +The following table indicates when `CMakePresets.json` is used instead of `CMakeSettings.json` to drive CMake configuration and build. If no configuration file is present, then default Configure Presets are used. + +Key: **Tools** > **Options** enabled means **Use CMakePresets.json to drive CMake configure, build, and test** is selected in **Tools** > **Options** > **CMake** > **General**. + +| Configuration files | Tools > Options disabled | Tools > Options enabled | +|--|--|--| +| No configuration file present | `CMakeSettings.json` | `CMakePresets.json` | +| `CMakeSettings.json` present | `CMakeSettings.json` | `CMakePresets.json` | +| `CMakePresets.json` present | `CMakePresets.json` | `CMakePresets.json` | +| Both configuration files present | `CMakePresets.json` | `CMakePresets.json` | + +## Auto configuration and cache notifications + +By default, Visual Studio automatically invokes configure each time the active Target System or Configure Preset changes. You can modify this behavior by selecting **Never run configure step automatically** in **Tools** > **Options** > **CMake** > **General**. You can also disable all CMake cache notifications (gold bars) by deselecting **Show CMake cache notifications**. + +## Default Configure Presets + +If no `CMakePresets.json` or `CMakeUserPresets.json` file exists, or if `CMakePresets.json` or `CMakeUserPresets.json` are invalid, then Visual Studio will fall back on the following default Configure Presets: + +**Windows example** + +```json +{ + "name": "windows-default", + "displayName": "Windows x64 Debug", + "description": "Sets Ninja generator, compilers, x64 architecture, build and install directory, debug build type", + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "architecture": { + "value": "x64", + "strategy": "external" + }, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}" + }, + "vendor": { + "microsoft.com/VisualStudioSettings/CMake/1.0": { + "hostOS": [ "Windows" ] + } + } +}, +``` + +**Linux example** + +```json +{ + "name": "linux-default", + "displayName": "Linux Debug", + "description": "Sets Ninja generator, compilers, build and install directory, debug build type", + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}" + }, + "vendor": { + "microsoft.com/VisualStudioSettings/CMake/1.0": { + "hostOS": [ "Linux" ] + }, + "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": { + "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}" + } + } +} +``` + +A `CMakePresets.json` file with the default Configure Presets is automatically created by Visual Studio at the root of your project if you attempt to open or modify a `CMakePresets.json` file that doesn't exist. + +## Configure and build + +Visual Studio provides three dropdowns when `CMakePresets.json` integration is enabled: + +![Target system dropdown](./media/target-system-dropdown.png) + +### Select a target system + +The dropdown on the left indicates the active **Target System**. This is the system on which CMake will be invoked to configure and build the project. This dropdown lists your local machine, all SSH connections in the **Connection Manager** by host name, and all Windows Subsystem for Linux (WSL) installations that Visual Studio can find: + +![Target system dropdown selection examples for local machine, a SSH connection, and WSL ubuntu and WSL debian](./media/target-system-selections.png) + +In the example above: +- **192.168.0.5** is a remote Linux system that was added to the **Connection Manager**. +- **ubuntu2004** and **debian** are WSL installations. + +Select **Manage Connections…** to open the **Connection Manager**. + +### Select a Configure Preset + +The dropdown in the middle indicates the active **Configure Preset**. This is the `configurePreset` that will be used when CMake is invoked to generate the project build system. This dropdown lists the union of non-hidden Configure Presets defined in `CMakePresets.json` and `CMakeUserPresets.json`. + +Visual Studio will use the value of `hostOS` in the Microsoft Visual Studio Settings vendor map to hide Configure Presets that don't apply to the active Target System. See the entry for `hostOS` in the table under [Visual Studio Settings vendor map](cmake-presets-json-reference.md#visual-studio-settings-vendor-map) for more information. + +Select **Manage Configurations…** to open the `CMakePresets.json` file located at the root of the project. `CMakePresets.json` is created if it doesn't already exist. + +### Select a Build Preset + +The dropdown on the right indicates the active **Build Preset**. This is the `buildPreset` that will be used when CMake is invoked to build the project. This dropdown lists the union of non-hidden Build Presets defined in `CMakePresets.json` and `CMakeUserPresets.json`. + +All Build Presets are required to specify an associated `configurePreset`. Visual Studio hides Build Presets that don't apply to the active Configure Preset. For more information, see [Build Presets](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html#build-preset). If there are no Build Presets associated with the active Configure Preset, then Visual Studio will list the Default Build Preset. The Default Build Preset is equivalent to passing `cmake --build` with no other arguments from the command line. + +### Configure + +Visual Studio automatically tries to configure the project when it detects that the CMake cache is out of date. To manually invoke configure, select **Project** > **Configure ** from the main menu. This is the same as running `cmake --preset ` from the command line, where `` is the name of the active Configure Preset. To disable automatic cache generation, see [Auto configuration and cache notifications](#auto-configuration-and-cache-notifications). + +### Build + +To build the entire project, select **Build** > **Build All** from the main menu. This is the same as running `cmake --build --preset ` from the command line, where `` is the name of the active Build Preset. + +To build a single target, switch to **CMake Targets View** in the **Solution Explorer**. Then right-click any target and select **Build** from the context menu. + +> [!NOTE] +> Visual Studio 2019 doesn't support the `buildPresets.targets` option to build a subset of targets specified in `CMakePresets.json`. + +## Run CTest + +There are two menu options supported by `CMakePresets.json` in Visual Studio 2019. + +- **Test** > **Run CTests** for invokes CTest and runs all tests associated with the active Configure Preset and Build Preset, with no additional arguments passed to CTest. +- **Test** > **Run Test Preset** for will expand to show all Test Presets associated with the active Configure Preset. Selecting a single Test Preset is the same as running `ctest --preset ` from the command line, where `` is the name of the selected Test Preset. This option will be grayed out if no Test Presets are defined for the active Configure Preset. + +In Visual Studio 2019, the Test Explorer isn't integrated with `CMakePresets.json`. + +## Add new presets + +In Visual Studio 2019, all commands and preset templates modify `CMakePresets.json`. You can add new user-level presets by directly editing `CMakeUserPresets.json` + +Use a forward slash (`/`) for paths in `CMakePresets.json` and `CMakeUserPresets.json`. + +### Add new Configure Presets + +To add a new Configure Preset to `CMakePresets.json`, from **Solution Explorer** right-click `CMakePresets.json` from **Folder View** and select **Add Configure Preset…** from the context menu. The dialog to select a Configure Preset template appears: + +![Add configure preset to `CMakePresets.json` dialog](./media/add-configure-preset-to-cmakepresets.png) + +Choose the **Windows x64 Debug** template to configure on Windows systems. Choose the **Linux Debug** template to configure on WSL and remote Linux systems. See [Edit presets](#edit-presets) for more information about editing `CMakePresets.json`. + +The selected template will be added to `CMakePresets.json` if it exists. Otherwise, the template will be copied into a new `CMakePresets.json`. + +### Add new Build Presets and Test Presets + +Visual Studio 2019 doesn't offer templates for new Build Presets and Test Presets. Build Presets and Test Presets can be added by directly editing `CMakePresets.json`. See [Build Presets](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html#build-preset), [Test Presets](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html#test-preset), or [Example `CMakePresets.json` file](#example-cmakepresetsjson-file) for more information. + +## Edit presets + +The official [CMake documentation](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html#id1) is the best resource for editing Configure Presets, Build Presets, and Test Presets. The following information is a subset of the CMake documentation that is especially relevant to Visual Studio developers. + +### Select your compilers + +C and C++ compilers can be set with `cacheVariables.CMAKE_C_COMPILER` and `cacheVariables.CMAKE_CXX_COMPILER` in a Configure Preset. This is equivalent to passing `-D CMAKE_C_COMPILER= and -D CMAKE_CXX_COMPILER=` to CMake from the command line. For more information, see [CMAKE__COMPILER](https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER.html#cmake-lang-compiler). + +Use the following examples to build with `cl.exe` and `clang-cl.exe` from Visual Studio. The C++ Clang tools for Windows component must be installed to build with `clang-cl`. + +**Build with `cl.exe`** +```json +"cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}", + "CMAKE_C_COMPILER": "cl", + "CMAKE_CXX_COMPILER": "cl" +}, +``` + +**Build with `clang`** +```json +"cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}", + "CMAKE_C_COMPILER": "clang-cl", + "CMAKE_CXX_COMPILER": "clang-cl" +}, + +"vendor": { + "microsoft.com/VisualStudioSettings/CMake/1.0": { + "intelliSenseMode": "windows-clang-x64" + } +} +``` + +> [!IMPORTANT] +> In Visual Studio 2019, you must explicitly specify a Clang IntelliSense mode when building with `clang` or `clang-cl`. + +See [Run CMake from the command line or a continuous integration (CI) pipeline](#run-cmake-from-the-command-line-or-a-continuous-integration-ci-pipeline) to reproduce these builds outside of Visual Studio. + +To build on Linux or without the Visual C++ toolset, specify the name of a compiler on your `PATH`, or an environment variable that evaluates to the full path of a compiler. Full paths are discouraged so that the file can remain shareable. A preset that builds with GCC version 8 might look like this: + +**GCC** +```json +"cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}", + "CMAKE_C_COMPILER": "gcc-8", + "CMAKE_CXX_COMPILER": "g++-8" +}, +``` + +You can also set compilers with a CMake toolchain file. Toolchain files can be set with `cacheVariables.CMAKE_TOOLCHAIN_FILE`, which is equivalent to passing` -D CMAKE_TOOLCHAIN_FILE=` to CMake from the command line. A CMake toolchain file is most often used for cross-compilation. See [CMake toolchains](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html) for more information about authoring CMake toolchain files. + +### Select your generator + +The Windows and Linux Configure Preset templates both specify Ninja as the default generator. Other common generators are the [Visual Studio Generators](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html?highlight=visual%20studio%20generators#visual-studio-generators) on Windows and Unix Makefiles on Linux and macOS. You can specify a new generator with the `generator` option in a Configure Preset. This is equivalent to passing `-G` to CMake from the command line. + +Set `architecture.strategy` and `toolset.strategy` to `set` when building with a Visual Studio Generator. See [CMake generators](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#:~:text=A%20CMake%20Generator%20is%20responsible%20for%20writing%20the,what%20native%20build%20system%20is%20to%20be%20used) for more information. + +Set `architecture.strategy` and `toolset.strategy` to `set` when building with a Visual Studio Generator. + +### Select your configuration type + +The configuration type (**Debug/Release**) for single configuration generators can be set with `cacheVariables.CMAKE_BUILD_TYPE`. This is equivalent to passing `-D CMAKE_BUILD_TYPE=` to CMake from the command line. See[ CMAKE_BUILD_TYPE](https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html) for more information. + +### Select your target and host architecture when building with the Visual C++ toolset. + +The target architecture (x64, Win32, ARM64, or ARM) can be set with `architecture.value`. This is equivalent to passing` -A` to CMake from the command line. See [Platform Selection](https://cmake.org/cmake/help/latest/generator/Visual%20Studio%2016%202019.html#platform-selection) for more information. + +> [!NOTE] +> Currently Visual Studio Generators expect the Win32 syntax and command-line generators (like Ninja) expect the x86 syntax when building for x86. + +The host architecture (x64 or x86) and toolset can be set with `toolset.value`. This is equivalent to passing `-T` to CMake from the command line. See [Toolset Selection](https://cmake.org/cmake/help/latest/generator/Visual%20Studio%2016%202019.html#toolset-selection) for more information. + +`architecture.strategy` and `toolset.strategy` tell CMake how to handle the architecture and toolset fields. `set` means CMake will set the respective value, and `external` means CMake won't set the respective value. + + `set` should be used with IDE generators like the Visual Studio Generator. `external` should be used with command-line generators like Ninja. This allows vendors like Visual Studio to source the required environment before CMake is invoked. See [Configure Presets](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html#configure-preset) for more information about the architecture and toolset fields. + +For a full list of IDE generators that support the architecture field, see [CMAKE_GENERATOR_PLATFORM](https://cmake.org/cmake/help/latest/variable/CMAKE_GENERATOR_PLATFORM.html). For a full list of IDE generators that support the toolset field, see [CMAKE_GENERATOR_TOOLSET](https://cmake.org/cmake/help/latest/variable/CMAKE_GENERATOR_TOOLSET.html). + +Use the examples below to target ARM64 with the Ninja generator, or Win32 (x86) with the Visual Studio 16 2019 generator: + +```json +"generator": "Ninja", +"architecture": { + "strategy": "external", + "value": "arm64" +}, + +"generator": "Visual Studio 16 2019", +"architecture": { + "strategy": "set", + "value": "Win32" +}, +``` + +### Set and reference environment variables + +You can set environment variables using the environment map. Environment variables are inherited through the `inherits` field, but you can override them as desired. A preset’s environment will be the union of its own environment and the environment from all its parents. If multiple `inherits` presets provide conflicting values for the same variable, the earlier preset in the `inherits` list will be preferred. You can unset a variable inherited from another preset by setting it to `null`. Environment variables set in a Configure Preset also automatically flow through to associated Build Presets and Test Presets unless `inheritConfigureEnvironment` is set to `false`. See [Configure Presets](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html#configure-preset) for more information. + +You can reference environment variables using the `$env{}` and `$penv{}` syntax. See [Macro Expansion](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html#macro-expansion) for more information. + +### Configure IntelliSense for a cross-compiler + +By default, Visual Studio will use the IntelliSense mode that matches your specified toolset and target architecture. If you're cross-compiling, then you may need to manually specify the correct IntelliSense mode with the `intelliSenseMode` option in the Visual Studio Settings vendor map. See the entry for `intelliSenseMode` in the table under [Visual Studio Settings vendor map](cmake-presets-json-reference.md#visual-studio-settings-vendor-map) for more information. + +## Configure and build on a remote system or the Windows Subsystem for Linux (WSL) + +With `CMakePresets.json` support in Visual Studio, you can easily configure and build your project on Windows, WSL, and remote systems. The steps to [Configure and build](#configure-and-build) your project on Windows, a remote system, or WSL are the same. However, there are a few behaviors that are specific to remote development. + +### `${sourceDir}` behavior in remote copy scenarios + +In local scenarios (including WSL1), `${sourceDir}` evaluates to the path to the project source directory that is open in Visual Studio. In remote copy scenarios, `${sourceDir}` evaluates to the path to the project source directory on the target system and not the project source directory on the local machine. The project source directory on the target system is determined by the value of `sourceDir` in the Visual Studio Remote Settings vendor map (defaults to `$env{HOME}/.vs/$ms{projectDirName}`). See the entry for `sourceDir` in the table under [Visual Studio Settings vendor map](cmake-presets-json-reference.md#visual-studio-settings-vendor-map) for more information. + +### Local folder for remote output + +Remote copy scenarios require a local directory to copy some remote files like CMake File-API response files or build files if `copyBuildOutput` in the Visual Studio Remote Settings vendor map is set to `true`. These files are automatically copied to `/out//build/${presetName}`. + +### Invoke the same Configure Preset on Windows and WSL1 + +You'll see an error if you try to use the same Configure Preset on Windows and WSL1. Windows and WSL1 both use the Windows file system, so CMake will try to use the same output directory (`binaryDir`) for both the Windows and WSL1 build tree. If you want to use the same Configure Preset with both Windows and the WSL1 toolset, create a second Configure Preset that inherits from the original preset and specifies a new `binaryDir`. In the following example, `windows-preset` can be used on Windows and `base-preset` can be used on WSL1: + +```json +{ + "name": "windows-preset", + "inherits": "base-preset", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "vendor": { + "microsoft.com/VisualStudioSettings/CMake/1.0": { + "hostOS": "Windows" + } + } +} +``` + +> [!NOTE] +> In Visual Studio 2019, only the WSL1 toolset is supported. You'll see this behavior anytime you invoke configure on both Windows and WSL. + +## Vcpkg integration + +Vcpkg helps you manage C and C++ libraries on Windows, Linux, and macOS. A vcpkg toolchain file (`vcpkg.cmake`) must be passed to CMake to enable vcpkg integration. See the [vcpkg documentation](https://github.com/microsoft/vcpkg#vcpkg-overview) for more information. + +Visual Studio no longer passes your vcpkg toolchain file to CMake automatically when `CMakePresets.json` integration is enabled. This eliminates Visual Studio specific behavior and ensures that your build can be reproduced from the command line. + +Instead, set the path to `vcpkg.cmake` with the `VCPKG_ROOT` environment variable in `CMakePresets.json`: + +```json +"cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": { + "value": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake", + "type": "FILEPATH" + } + }, +``` + +`VCPKG_ROOT` should be set to the root of your vcpkg installation. See [vcpkg environment variables](https://github.com/microsoft/vcpkg/blob/master/docs/users/config-environment.md) for more information. + +If you're already using a CMake toolchain file and want to enable vcpkg integration, then see [Using multiple toolchain files](https://github.com/microsoft/vcpkg/blob/master/docs/users/integration.md#using-multiple-toolchain-files) and follow those instructions to use an external toolchain file with a project using vcpkg. + +## Variable substitution in `launch.vs.json` and `tasks.vs.json` + +`CMakePresets.json` supports variable substitution in `launch.vs.json` and `tasks.vs.json`. + +* Environment variables set in the active Configure Preset automatically flow through to `launch.vs.json` and `tasks.vs.json` configurations. You can unset individual environment variables in `launch.vs.json` and `tasks.vs.json` by setting them to `null`. The following example sets the variable `DEBUG_LOGGING_LEVEL` to `null` in `launch.vs.json`: `"env": { "DEBUG_LOGGING_LEVEL": null }` + +* Key-values set in the active Configure Preset are available for consumption in `launch.vs.json` and `tasks.vs.json` with the syntax `${cmake.}`. For example, use ` ${cmake.binaryDir}` to reference the output directory of the active Configure Preset. +* Individual environment variables set in the environment map of the active Configure Preset are available for consumption in `launch.vs.json` and `tasks.vs.json` using the syntax `${env.}`. + +Update your `launch.vs.json` and `task.vs.json` files to reference `CMakePresets.json` syntax instead of `CMakeSettings.json` syntax. Macros that reference the old `CMakeSettings.json` syntax when `CMakePresets.json` is the active configuration file will be deprecated in a future release. For example, reference the output directory of the active Configure Preset with `${cmake.binaryDir}` instead of `${cmake.buildRoot}`, because `CMakePresets.json` uses the `binaryDir` syntax. + +## Troubleshooting + +If things aren’t working as expected, there are a few troubleshooting steps that you can take. + +If either `CMakePrests.json` or `CMakeUserPresets.json` is invalid, then Visual Studio will fall back on its default behavior and show only the default Configure Presets. Visual Studio IntelliSense can help you catch many of these JSON errors, but it won’t know if you're referencing a preset with `inherits` or `configurePreset` by the wrong name. To check if your preset files are valid, run `cmake --list-presets` from the command line at the root of your project directory (CMake 3.20 or higher is required). If either file is invalid, then you'll see the following error: + +```DOS +CMake Error: Could not read presets from +C:/Users//source/repos/: JSON parse error +``` + +Other troubleshooting steps include: +* Delete the cache and reconfigure the project (**CMake: Delete Cache** and **Project** > **Configure **) +* Close and reopen the folder in Visual Studio (**File** > **Close Folder**) +* Delete the `.vs` folder at the root your project + +If you've identified a problem, the best way to report it is by clicking the **Send Feedback** button in the top right-hand corner of Visual Studio. + +## Logging for remote connections + +You can enable logging for remote connections if you're having trouble connecting or copying files to a remote system. See [logging for remote connections](https://docs.microsoft.com/cpp/linux/connect-to-your-remote-linux-computer#logging-for-remote-connections) for more information. + +## Enable AddressSanitizer for Windows and Linux + +AddressSanitizer (`ASan`) is a runtime memory error detector for C and C++ that is supported in Visual Studio for both Windows and Linux development. AddressSanitizer was enabled with an option (`addressSanitizerEnabled`) in `CMakeSettings.json`. This behavior isn't supported by `CMakePresets.json`. + +Instead, enable and disable AddressSanitizer by setting the required compiler and linker flags yourself. This removes Visual Studio specific behavior and ensures that the same `CMakePresets.json` file can reproduce your build from the command line. The following sample can be added to a `CMakeLists.txt` to enable or disable AddressSanitizer for a target. + +``` +option(ASAN_ENABLED "Build this target with AddressSanitizer" ON) + +if(ASAN_ENABLED) + if(MSVC) + target_compile_options( PUBLIC /fsanitize=address) + else() + target_compile_options( PUBLIC -fsanitize=address ) + target_link_options( PUBLIC -fsanitize=address) + endif() +endif() +``` + +`` are other compilation flags like `"-fno-omit-frame-pointer"`. See [Using AddressSanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizer#using-addresssanitizer) for more information about `ASan` for Linux, and see [Use the AddressSanitizer from a Developer Command Prompt](https://docs.microsoft.com/cpp/sanitizers/asan#command-prompt) for more information about `ASan` with MSVC. + +Pass additional runtime flags to AddressSanitizer with the `ASAN_OPTIONS` field in `launch.vs.json`. `ASAN_OPTIONS` defaults to `detect_leaks=0` when no other runtime options are specified because LeakSanitizer isn't supported in Visual Studio. + +## Run CMake from the command line or a continuous integration (CI) pipeline + +You can use the same `CMakePresets.json` and `CMakeUserPresets.json` files to invoke CMake in Visual Studio and from the command line. The [CMake](https://cmake.org/cmake/help/latest/manual/cmake.1.html) and [CTest](https://cmake.org/cmake/help/latest/manual/ctest.1.html) documentation are the best resources for invoking CMake and CTest with `--preset`. CMake version 3.20 or higher is required. + +### Sourcing the environment when building with command-line generators on Windows + +It’s up to the user to configure the environment before CMake is invoked when building with a command-line generator. If you’re building with Ninja and the Visual C++ toolset on Windows, then you'll need to source the environment before CMake is called to generate the build system. You can do this by calling `vcvarsall.bat` with the `architecture` argument. `architecture` specifies the host and target architecture to use. See [vcvarsall syntax](https://docs.microsoft.com/cpp/build/building-on-the-command-line#vcvarsall-syntax) for more information. If you build on Linux or on Windows with a Visual Studio Generator, then you don't need to take this step. + +This is the same step that Visual Studio takes for you when CMake is invoked by the IDE. Visual Studio parses the active Configure Preset for the host and target architecture specified by `toolset` and `architecture` and then sources the specified environment from `vcvarsall.bat`. When you build from the Windows command line with Ninja, you'll need to take this step yourself. + +`vcvarsall.bat` is installed with the Build Tools for Visual Studio. By default, `vcvarsall.bat` is installed in `C:\Program Files (x86)\Microsoft Visual Studio\2019\\VC\Auxiliary\Build`. You can add `vcvarsall.bat` to your `PATH` if you use the command-line workflow frequently. + +### Example command-line workflow + +The following commands can be used to configure and build a CMake project that uses Ninja to target arm64 with x64 build tools. CMake version 3.20 or higher is required. Run these commands from the directory where your `CMakePresets.json` is located: + +```DOS +/path/to/vcvarsall.bat x64_arm64 +cmake --list-presets=all . +cmake --preset +cmake --build --preset +``` + +## Example `CMakePresets.json` file + +The `CMakePresets.json` file in [box2d-lite](https://github.com/esweet431/box2d-lite/blob/main/CMakePresets.json) contains examples of Configure Presets, Build Presets, and Test Presets. + +## Next steps + +Learn more about configuring and debugging CMake projects in Visual Studio: + +> [!div class="nextstepaction"] +> [CMake Projects in Visual Studio](cmake-projects-in-visual-studio.md)

+> [Customize CMake build settings](customize-cmake-settings.md)

+> [Configure CMake debugging sessions](configure-cmake-debugging-sessions.md)

+> [CMake predefined configuration reference](cmake-predefined-configuration-reference.md) +> \ No newline at end of file diff --git a/docs/build/media/add-configure-preset-to-cmakepresets.png b/docs/build/media/add-configure-preset-to-cmakepresets.png new file mode 100644 index 00000000000..343e8a85ed6 Binary files /dev/null and b/docs/build/media/add-configure-preset-to-cmakepresets.png differ diff --git a/docs/build/media/add-reference-to-walkthrough.png b/docs/build/media/add-reference-to-walkthrough.png new file mode 100644 index 00000000000..e158d40b485 Binary files /dev/null and b/docs/build/media/add-reference-to-walkthrough.png differ diff --git a/docs/build/media/additional-header-unit-dependencies-setting.png b/docs/build/media/additional-header-unit-dependencies-setting.png new file mode 100644 index 00000000000..d2834ce2fa6 Binary files /dev/null and b/docs/build/media/additional-header-unit-dependencies-setting.png differ diff --git a/docs/build/media/change-compile-as.png b/docs/build/media/change-compile-as.png new file mode 100644 index 00000000000..8d92a9d7d0b Binary files /dev/null and b/docs/build/media/change-compile-as.png differ diff --git a/docs/build/media/change-item-type.png b/docs/build/media/change-item-type.png new file mode 100644 index 00000000000..3255f44d4ec Binary files /dev/null and b/docs/build/media/change-item-type.png differ diff --git a/docs/build/media/empty-project-option.png b/docs/build/media/empty-project-option.png new file mode 100644 index 00000000000..42326545402 Binary files /dev/null and b/docs/build/media/empty-project-option.png differ diff --git a/docs/build/media/enable-cmakepresets.png b/docs/build/media/enable-cmakepresets.png new file mode 100644 index 00000000000..f2b46318ff0 Binary files /dev/null and b/docs/build/media/enable-cmakepresets.png differ diff --git a/docs/build/media/public-include-module-directories-setting.png b/docs/build/media/public-include-module-directories-setting.png new file mode 100644 index 00000000000..a6539264b44 Binary files /dev/null and b/docs/build/media/public-include-module-directories-setting.png differ diff --git a/docs/build/media/set-cpp-language-latest.png b/docs/build/media/set-cpp-language-latest.png new file mode 100644 index 00000000000..ea67b165be1 Binary files /dev/null and b/docs/build/media/set-cpp-language-latest.png differ diff --git a/docs/build/media/set-header-unit-library-settings.png b/docs/build/media/set-header-unit-library-settings.png new file mode 100644 index 00000000000..2a2c423fcdd Binary files /dev/null and b/docs/build/media/set-header-unit-library-settings.png differ diff --git a/docs/build/media/target-system-dropdown.png b/docs/build/media/target-system-dropdown.png new file mode 100644 index 00000000000..a09eead210a Binary files /dev/null and b/docs/build/media/target-system-dropdown.png differ diff --git a/docs/build/media/target-system-selections.png b/docs/build/media/target-system-selections.png new file mode 100644 index 00000000000..6947285cddc Binary files /dev/null and b/docs/build/media/target-system-selections.png differ diff --git a/docs/build/media/vs2019-additional-module-dependencies.png b/docs/build/media/vs2019-additional-module-dependencies.png new file mode 100644 index 00000000000..73dff3c604d Binary files /dev/null and b/docs/build/media/vs2019-additional-module-dependencies.png differ diff --git a/docs/build/media/vs2019-scan-module-dependencies.png b/docs/build/media/vs2019-scan-module-dependencies.png new file mode 100644 index 00000000000..5b207ea85cd Binary files /dev/null and b/docs/build/media/vs2019-scan-module-dependencies.png differ diff --git a/docs/build/media/vs2019-translate-includes-option.png b/docs/build/media/vs2019-translate-includes-option.png new file mode 100644 index 00000000000..782975cd089 Binary files /dev/null and b/docs/build/media/vs2019-translate-includes-option.png differ diff --git a/docs/build/reference/compiler-options-listed-alphabetically.md b/docs/build/reference/compiler-options-listed-alphabetically.md index 60c27b941f1..ed2cb7d3e8d 100644 --- a/docs/build/reference/compiler-options-listed-alphabetically.md +++ b/docs/build/reference/compiler-options-listed-alphabetically.md @@ -1,7 +1,7 @@ --- title: "Compiler options listed alphabetically" description: "Reference listing in alphabetical order of the Microsoft C/C++ compiler command-line options." -ms.date: 07/29/2020 +ms.date: 04/13/2021 helpviewer_keywords: ["compiler options, C++"] --- # Compiler options listed alphabetically @@ -34,6 +34,7 @@ This table contains an alphabetical list of compiler options. For a list of comp | [`/execution-charset`](execution-charset-set-execution-character-set.md) | Set the execution character set. | | [`/experimental:module`](experimental-module.md) | Enables experimental module support. | | [`/experimental:preprocessor`](experimental-preprocessor.md) | Deprecated. Enables experimental conforming preprocessor support. Use [`/Zc:preprocessor`](zc-preprocessor.md) | +| [`/exportHeader`](module-exportheader.md) | Create the header units (*`.ifc`*) files specified by the input arguments. | | [`/F`](f-set-stack-size.md) | Sets stack size. | | [`/favor`](favor-optimize-for-architecture-specifics.md) | Produces code optimized for a specific x64 architecture. Or, for the specific micro-architectures in both the AMD64 and EM64T architectures. | | [`/FA`](fa-fa-listing-file.md) | Creates a listing file. | @@ -74,6 +75,8 @@ This table contains an alphabetical list of compiler options. For a list of comp | [`/GZ`](gz-enable-stack-frame-run-time-error-checking.md) | Deprecated. Same as [`/RTC1`](rtc-run-time-error-checks.md). | | [`/Gz`](gd-gr-gv-gz-calling-convention.md) | Uses the **`__stdcall`** calling convention (x86 only). | | [`/H`](h-restrict-length-of-external-names.md) | Deprecated. Restricts the length of external (public) names. | +| [`/headerName`](headername.md) | Build a header unit from the specified header. | +| [`/headerUnit`](headerunit.md) | Specify where to find the header unit file (`.ifc`) for the specified header. | | [`/HELP`](help-compiler-command-line-help.md) | Lists the compiler options. | | [`/homeparams`](homeparams-copy-register-parameters-to-stack.md) | Forces parameters passed in registers to be written to their locations on the stack upon function entry. This compiler option is only for the x64 compilers (native and cross compile). | | [`/hotpatch`](hotpatch-create-hotpatchable-image.md) | Creates a hot-patchable image. | @@ -114,16 +117,19 @@ This table contains an alphabetical list of compiler options. For a list of comp | [`/Qspectre-load`](qspectre-load.md) | Specifies compiler generation of serializing instructions to mitigate Spectre security vulnerabilities based on load instructions. | | [`/Qspectre-load-cf`](qspectre-load-cf.md) | Specifies compiler generation of serializing instructions to mitigate Spectre security vulnerabilities based on control flow instructions that load memory. | | [`/Qvec-report` (Auto-vectorizer reporting level)](qvec-report-auto-vectorizer-reporting-level.md) | Enables reporting levels for automatic vectorization. | +| [`/reference`](module-reference.md) | Use named module IFC. | | [`/RTC`](rtc-run-time-error-checks.md) | Enables run-time error checking. | | [`/sdl`](sdl-enable-additional-security-checks.md) | Enables additional security features and warnings. | | [`/showIncludes`](showincludes-list-include-files.md) | Displays a list of include files during compilation. | | [`/source-charset`](source-charset-set-source-character-set.md) | Set source character set. | -| [`/sourceDependencies`](sourcedependencies.md) | List headers, modules, and other source dependencies. | +| [`/sourceDependencies`](sourcedependencies.md) | List all source-level dependencies. | +| [`/sourceDependencies:directives`](sourcedependencies-directives.md) |List module and header unit dependencies. | | [`/std`](std-specify-language-standard-version.md) | C++ standard version compatibility selector. | | [`/Tc`](tc-tp-tc-tp-specify-source-file-type.md) | Specifies a C source file. | | [`/TC`](tc-tp-tc-tp-specify-source-file-type.md) | Specifies all source files are C. | | [`/Tp`](tc-tp-tc-tp-specify-source-file-type.md) | Specifies a C++ source file. | | [`/TP`](tc-tp-tc-tp-specify-source-file-type.md) | Specifies all source files are C++. | +| [`/translateInclude`](translateinclude.md) | Treat `#include` as `import`. | | [`/U`](u-u-undefine-symbols.md) | Removes a predefined macro. | | [`/u`](u-u-undefine-symbols.md) | Removes all predefined macros. | | [`/utf-8`](utf-8-set-source-and-executable-character-sets-to-utf-8.md) | Set source and execution character sets to UTF-8. | diff --git a/docs/build/reference/compiler-options-listed-by-category.md b/docs/build/reference/compiler-options-listed-by-category.md index fccd2139f6c..20c8dc9428c 100644 --- a/docs/build/reference/compiler-options-listed-by-category.md +++ b/docs/build/reference/compiler-options-listed-by-category.md @@ -103,6 +103,18 @@ This article contains a categorical list of compiler options. For an alphabetica | [`/u`](u-u-undefine-symbols.md) | Removes all predefined macros. | | [`/X`](x-ignore-standard-include-paths.md) | Ignores the standard include directory. | +## Header units + +| Option | Purpose | +|--|--| +| [`/exportHeader`](module-exportheader.md) | Create the header units files (*`.ifc`*) specified by the input arguments. | +| [`/headerUnit`](headerunit.md) | Specify where to find the header unit file (`.ifc`) for the specified header. | +| [`/headerName`](headername.md) | Build a header unit from the specified header. | +| [`/reference`](module-reference.md) | Use named module IFC. | +| [`/sourceDependencies`](sourcedependencies.md) | List all source-level dependencies. | +| [`/sourceDependencies:directives`](sourcedependencies-directives.md) | List module and header unit dependencies. | +| [`/translateInclude`](translateinclude.md) | Treat `#include` as `import`. | + ## Language | Option | Purpose | @@ -165,7 +177,6 @@ This article contains a categorical list of compiler options. For an alphabetica | [`/nologo`](nologo-suppress-startup-banner-c-cpp.md) | Suppresses display of sign-on banner. | | [`/sdl`](sdl-enable-additional-security-checks.md) | Enables additional security features and warnings. | | [`/showIncludes`](showincludes-list-include-files.md) | Displays a list of all include files during compilation. | -| [`/sourceDependencies`](sourcedependencies.md) | List headers, modules, and other source dependencies. | | [`/Tc`](tc-tp-tc-tp-specify-source-file-type.md) | Specifies a C source file. | | [`/TC`](tc-tp-tc-tp-specify-source-file-type.md) | Specifies all source files are C. | | [`/Tp`](tc-tp-tc-tp-specify-source-file-type.md) | Specifies a C++ source file. | diff --git a/docs/build/reference/experimental-module.md b/docs/build/reference/experimental-module.md index 937b2ceedb5..1b5765fa529 100644 --- a/docs/build/reference/experimental-module.md +++ b/docs/build/reference/experimental-module.md @@ -1,13 +1,13 @@ --- title: "/experimental:module (Enable module support)" -description: "Use the /experimental:module compiler option to enable experimental compiler support for modules." -ms.date: "09/03/2019" +description: "Use the /experimental:module compiler option to enable experimental compiler support for named modules." +ms.date: "04/13/2021" f1_keywords: ["module", "/experimental:module"] helpviewer_keywords: ["module", "/experimental:module", "Enable module support"] --- # /experimental:module (Enable module support) -Enables experimental compiler support for modules, as specified by the draft C++20 standard. +Enables experimental compiler support for Standard Template Library named modules. ## Syntax @@ -15,18 +15,12 @@ Enables experimental compiler support for modules, as specified by the draft C++ ## Remarks -You can enable experimental modules support by use of the **/experimental:module** compiler option along with the [/std:c++latest](std-specify-language-standard-version.md) option. You can use **/experimental:module-** to disable module support explicitly. +You can enable experimental modules support by use of the **`/experimental:module`** compiler option along with the [/std:c++latest](std-specify-language-standard-version.md) option. Use **`/experimental:module-`** to disable module support explicitly. -This option is available starting in Visual Studio 2015 Update 1. As of Visual Studio 2019 version 16.2, Draft C++20 Standard modules are not fully implemented in the Microsoft C++ compiler. You can use the modules feature to create single-partition modules and to import the Standard Library modules provided by Microsoft. A module and the code that consumes it must be compiled with the same compiler options. +This option is available starting in Visual Studio 2015 Update 1. As of Visual Studio 2019 version 16.2, Draft C++20 Standard modules aren't fully implemented in the Microsoft C++ compiler. You can use the modules feature to create single-partition modules and to import the Standard Library modules provided by Microsoft. A module and the code that consumes it must be compiled with the same compiler options. For more information on modules and how to use and create them, see [Overview of modules in C++](../../cpp/modules-cpp.md). -Here's an example of the compiler command-line options used to create an export module from source file *ModuleName.ixx*: - -```cmd -cl /EHsc /MD /experimental:module /module:export /module:name ModuleName /module:wrapper C:\Output\path\ModuleName.h /module:output C:\Output\path\ModuleName.ifc -c ModuleName.ixx -``` - ### To set this compiler option in the Visual Studio development environment 1. Open the project's **Property Pages** dialog box. For details, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md). @@ -40,7 +34,7 @@ cl /EHsc /MD /experimental:module /module:export /module:name ModuleName /module ## See also [`/headerUnit` (Use header unit IFC)](headerunit.md)\ -[`/module:exportHeader` (Create header units)](module-exportheader.md)\ -[`/module:reference` (Use named module IFC)](module-reference.md)\ +[`/exportHeader` (Create header units)](module-exportheader.md)\ +[`/reference` (Use named module IFC)](module-reference.md)\ [`/translateInclude` (Translate include directives into import directives)](translateinclude.md)\ -[/Zc (Conformance)](zc-conformance.md) +[`/Zc` (Conformance)](zc-conformance.md) diff --git a/docs/build/reference/headername.md b/docs/build/reference/headername.md new file mode 100644 index 00000000000..f02520a15f0 --- /dev/null +++ b/docs/build/reference/headername.md @@ -0,0 +1,73 @@ +--- +title: "/headerName (Build a header unit from the specified header)" +description: "Use the /headerName compiler option to establish a mapping between a header file and the header unit to build." +ms.date: 04/13/2021 +author: "tylermsft" +ms.author: "twhitney" +f1_keywords: ["/headerName"] +helpviewer_keywords: ["/headerName", "Use header unit IFC"] +--- +# `/headerName` (Build a header unit from the specified header) + +Build the specified header file into a header unit (*`.ifc`* file). + +## Syntax + +> **`/headerName:quote`** `header-filename`\ +> **`/headerName:angle`** `header-filename` + +### Arguments + +*`header-filename`*\ +The name of a header file that the compiler should compile into a header unit (*`.ifc`* file). + +## Remarks + +The **`/headerName`** compiler option is available starting in Visual Studio 2019 version 16.10 preview 2. + +The **`/headerName`** compiler option, in all its forms, requires the [/std:c++latest](std-specify-language-standard-version.md) option.\ +If you specify **`/headerName:{quote,angle}`**, you must also specify [`/exportHeader`](module-exportheader.md). + +**`/headerName:quote`** looks up *`header-filename`* using the same rules as `#include "header-name"` and builds it as a header unit (*`.ifc`* file).\ +**`/headerName:angle`** looks up *`header-filename`* using the same rules as `#include ` and builds it as a header unit (*`.ifc`* file). + +### Examples + +Given a project that references a header file it defines called `m.h`, the compiler option to compile it into a header unit looks similar to this: + +```Bash +$ cl /std:c++latest /exportHeader /headerName:quote m.h /Fom.h.obj +``` + +The `/headerName:{quote,angle}`switch acts like a flag and does not explicitly need an argument. The following examples are valid: + +```Bash +$ cl /std:c++latest /exportHeader /headerName:angle /MP /Fo.\ vector iostream algorithm +$ cl /std:c++latest /exportHeader /headerName:quote /MP /Fo.\ my-utilities.h a/b/my-core.h +``` + +You can specify multiple `/headerName` switches on the same command line, and every argument after that switch will be processed with the specified *`header-filename`* lookup rules. The following example processes all the headers as the previous two command line examples in the same way. It looks up the headers using the lookup rules applied as if they had been specified as: `#include `, `#include "my-utilties.h"`, and `#include "a/b/my-core.h"`: + +```bash +$ cl /std:c++latest /exportHeader /headerName:angle /MP /Fo.\ vector iostream algorithm /headerName:quote my-utilities.h a/b/my-core.h +``` + +### To set this compiler option in the Visual Studio development environment + +> [!NOTE] +> Users don't typically set this command line switch. It is set by the build system. + +1. Open the project's **Property Pages** dialog box. For details, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md). + +1. Set the **Configuration** drop-down to **All Configurations**. + +1. Select the **Configuration Properties** > **C/C++** > **Command Line** property page. + +1. Modify the **Additional Options** property to add the *`/headerName`* options and arguments. Then, choose **OK** or **Apply** to save your changes. + +## See also + +[`/exportHeader` (Create header units)](module-exportheader.md)\ +[`/headerUnit` (Create header units)](headerunit.md)\ +[`/reference` (Use named module IFC)](module-reference.md)\ +[`/translateInclude` (Translate include directives into import directives)](translateinclude.md) diff --git a/docs/build/reference/headerunit.md b/docs/build/reference/headerunit.md index 73a599f5f11..5957c4afcd7 100644 --- a/docs/build/reference/headerunit.md +++ b/docs/build/reference/headerunit.md @@ -1,31 +1,49 @@ --- title: "/headerUnit (Use header unit IFC)" -description: "Use the /headerUnit compiler option to specify an existing IFC header unit to import in the current compilation." -ms.date: 09/13/2020 +description: "Use the /headerUnit compiler option to associate a header file with the header unit to import in its place." +ms.date: 04/13/2021 f1_keywords: ["/headerUnit"] helpviewer_keywords: ["/headerUnit", "Use header unit IFC"] +author: "tylermsft" +ms.author: "twhitney" --- # `/headerUnit` (Use header unit IFC) -Tells the compiler to translate `#include` directives for an importable header-name into an `import header-name;` directive, rather than use textual inclusion. +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. ## Syntax -> **`/headerUnit`** *`header-filename`*=*`ifc-filename`* +> **`/headerUnit`** *`header-filename`*=*`ifc-filename`*\ +> **`/headerUnit:quote`** \[*`header-filename`*=*`ifc-filename`*\]\ +> **`/headerUnit:angle`** \[*`header-filename`*=*`ifc-filename`*\] ### Arguments *`header-filename`*\ -The name of a file that the compiler resolves a `header-name` to. During `import header-name ;` the compiler resolves `header-name` to some file on disk. Use *`header-filename`* to specify that file. Once matched, the compiler opens the corresponding IFC named by *`ifc-filename`* for import. +During `import header-name;` the compiler resolves `header-name` to a file on disk. Use *`header-filename`* to specify that file. Once matched, the compiler opens the corresponding IFC named by *`ifc-filename`* for import. *`ifc-filename`*\ -The name of a file that contains *IFC data*, prebuilt module information. To import more than one header unit, include a separate **`/headerUnit`** option for each file. +The name of a file that contains compiled header unit information. To import more than one header unit, add a separate **`/headerUnit`** option for each file. ## Remarks -The **`/headerUnit`** compiler option requires you enable experimental modules support by use of the [`/experimental:module`](experimental-module.md) compiler option, along with the [/std:c++latest](std-specify-language-standard-version.md) option. This option is available starting in Visual Studio 2019 version 16.8. +The **`/headerUnit`** compiler option requires the [/std:c++latest](std-specify-language-standard-version.md) option. -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`*. +The **`/headerUnit`** compiler option is available starting in Visual Studio 2019 version 16.10 preview 2. + +When the compiler comes across `import "file";` or `import ;`, this compiler switch 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: + +**`/headerUnit`** looks up the compiled header unit in the current directory, or at the location specified in *`ifc-filename`*. + +**`/headerUnit:quote`** looks up the compiled header unit file using the same rules as `#include "file"`. + +**`/headerUnit:angle`** looks up the compiled header unit file using the same rules as `#include `. + +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`*. + +The compiler implicitly enables the new preprocessor when this switch 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-` + +If you disable the new preprocessor, but a file you compile imports a header unit, the compiler will report an error. ### Examples @@ -34,27 +52,20 @@ Given a project that references two header files and their header units, listed | Header file | IFC file | |--|--| | *`C:\utils\util.h`* | *`C:\util.h.ifc`* | -| *`C:\app\app.h`* | *`C:\app.h.ifc`* | +| *`C:\app\app.h`* | *`C:\app\app.h.ifc`* | -The compiler options to reference the header units for these particular header files might look like this example: +The compiler options to reference the header units for these particular header files would look similar to this: ```CMD -cl ... /experimental:module /translateInclude /headerUnit C:\utils\util.h=C:\util.h.ifc /headerUnit C:\app\app.h=C:\app.h.ifc +cl ... /std:c++latest /headerUnit C:\utils\util.h=C:\util.h.ifc /headerUnit:quote app.h=app.h.ifc ``` ### To set this compiler option in the Visual Studio development environment -1. Open the project's **Property Pages** dialog box. For details, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md). - -1. Set the **Configuration** drop-down to **All Configurations**. - -1. Select the **Configuration Properties** > **C/C++** > **Command Line** property page. - -1. Modify the **Additional Options** property to add the *`/headerUnit`* options and arguments. Then, choose **OK** or **Apply** to save your changes. +You normally shouldn't set this in the Visual Studio development environment. It is set by the build system. ## See also -[`/experimental:module` (Enable module support)](experimental-module.md)\ -[`/module:exportHeader` (Create header units)](module-exportheader.md)\ -[`/module:reference` (Use named module IFC)](module-reference.md)\ -[`/translateInclude` (Translate include directives into import directives)](translateinclude.md)\ +[`/exportHeader` (Create header units)](module-exportheader.md)\ +[`/headerName` (Create a header unit from the specified header)](headername.md)\ +[`/reference` (Use named module IFC)](module-reference.md) diff --git a/docs/build/reference/module-exportheader.md b/docs/build/reference/module-exportheader.md index 3f94795279f..a89cf612b17 100644 --- a/docs/build/reference/module-exportheader.md +++ b/docs/build/reference/module-exportheader.md @@ -1,82 +1,62 @@ --- -title: "/module:exportHeader (Create header units)" -description: "Use the /module:exportHeader compiler option to create module header units for the header-name or include files specified." -ms.date: 09/13/2020 -f1_keywords: ["/module:exportHeader"] -helpviewer_keywords: ["/module:exportHeader", "Create header units"] +title: "/exportHeader (Create header units)" +description: "Use the /exportHeader compiler option to create module header units for the header-name or include files specified." +ms.date: 04/13/2020 +author: "tylermsft" +ms.author: "twhitney" +f1_keywords: ["/exportHeader"] +helpviewer_keywords: ["/exportHeader", "Create header units"] --- -# `/module:exportHeader` (Create header units) +# `/exportHeader` (Create header units) -Tells the compiler to create the header units specified by the input arguments. The compiler generates output in IFC (*`.ifc`*) files. +Tells the compiler to create the header units specified by the input arguments. The compiler generates header units as IFC (*`.ifc`*) files. ## Syntax -> **`/module:exportHeader`** *`header-name`* \[...]\ -> **`/module:exportHeader`** *`filename`* \[...] +> **`/exportHeader /headerName:angle`** *`header-name`* +> **`/exportHeader /headerName:quote`** *`header-name`* +> **`/exportHeader`** *`full path to header file`* ### Arguments -*`header-name`*\ -The header file to export. The *`header-name`* argument must take the same form as an argument to an `#include` directive. - -*`filename`*\ -The relative or absolute path to the header file to create a header unit from. +The argument to `/exportHeader` is a `/headerName` command-line option that specifies the name, *`header-name`*, of the header file to export. ## Remarks -The **`/module:exportHeader`** compiler option requires you enable experimental modules support by use of the [`/experimental:module`](experimental-module.md) compiler option, along with the [/std:c++latest](std-specify-language-standard-version.md) option. This option is available starting in Visual Studio 2019 version 16.8. - -One **`/module:exportHeader`** compiler option can specify as many header-name arguments as your build requires. You don't need to specify them separately. - -By default, the compiler doesn't produce an object file when a header unit is compiled. To produce an object file, specify the **`/Fo`** compiler option. For more information, see [`/Fo` (Object File Name)](fo-object-file-name.md). - -The compiler resolves a *`header-name`* based on the include directory search order, including any you specify. For more information, see [`/I` (Additional include directories)](i-additional-include-directories.md). - -The argument *`header-name`* must be specified the same way it would appear in source. The argument is sensitive to quoting rules and to `<` and `>` operators on the command line. The properly escaped command to build a header unit such as `` using the VS2019 command prompt might look like: +**`/exportHeader`** is available starting in Visual Studio 2019 version 16.10 Preview 2. -```cmd -cl ... /experimental:module /module:exportHeader "" -``` +The **`/exportHeader`** compiler option requires you enable the [/std:c++latest](std-specify-language-standard-version.md) option. -Building a local project header such as `"utils/util.h"` might look like: +One **`/exportHeader`** compiler option can specify as many header-name arguments as your build requires. You don't need to specify them separately. -```cmd -cl ... /experimental:module /module:exportHeader """util/util.h""" -``` +The compiler implicitly enables the new preprocessor when this switch is used. That is, [`/Zc:preprocessor`](zc-preprocessor.md) is added to the command line by the compiler if any form of `/exportHeader` is used on the command line. To opt out of the implicit `/Zc:preprocessor`, use: `/Zc:preprocessor-` -The quoting rules in other command-line processors may differ. +By default, the compiler doesn't produce an object file when a header unit is compiled. To produce an object file, specify the **`/Fo`** compiler option. For more information, see [`/Fo` (Object File Name)](fo-object-file-name.md). -When using the *`header-name`* form of **`/module:exportHeader`**, you may find it's helpful to use the complementary option **`/module:showResolvedHeader`**. The **`/module:showResolvedHeader`** option prints an absolute path to the file the *`header-name`* argument resolves to. +You may find it helpful to use the complementary option **`/showResolvedHeader`**. The **`/showResolvedHeader`** option prints an absolute path to the file the *`header-name`* argument resolves to. -**`/module:exportHeader`** can handle multiple inputs at once even under **`/MP`**. We recommended you use **`/module:output `** to create a separate IFC file for each compilation. +**`/exportHeader`** can handle multiple inputs at once, even under **`/MP`**. We recommended you use **`/ifcOutput `** to create a separate *`.ifc`* file for each compilation. ### Examples -Given headers `"C:\util\util.h"` and `"C:\app\app.h"`, you can export them as *`header-name`* arguments by using this command: +To build a header unit such as `` might look like: ```cmd -cl /IC:\ /experimental:module /module:exportHeader """util/util.h""" """app/app.h""" /FoC:\obj +cl … /std:c++latest /exportHeader /headerName:angle vector ``` -You can export them as *`filename`* arguments by using this command: +Building a local project header such as `"utils/util.h"` might look like: ```cmd -cl /IC:\ /experimental:module /module:exportHeader C:\util\util.h C:\app\app.h /FoC:\obj +cl … /std:c++latest /exportHeader /headerName:quote util/util.h ``` ### To set this compiler option in the Visual Studio development environment -1. Open the project's **Property Pages** dialog box. For details, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md). - -1. Set the **Configuration** drop-down to **All Configurations**. - -1. Select the **Configuration Properties** > **C/C++** > **Command Line** property page. - -1. Modify the **Additional Options** property to add the *`/module:exportHeader`* option and any arguments. Then, choose **OK** or **Apply** to save your changes. +You normally shouldn't set this in the Visual Studio development environment. It is set by the build system. ## See also -[`/experimental:module` (Enable module support)](experimental-module.md)\ [`/headerUnit` (Use header unit IFC)](headerunit.md)\ -[`/module:reference` (Use named module IFC)](module-reference.md)\ +[`/reference` (Use named module IFC)](module-reference.md)\ [`/translateInclude` (Translate include directives into import directives)](translateinclude.md) diff --git a/docs/build/reference/module-reference.md b/docs/build/reference/module-reference.md index 347c85d52d0..fafe887f2f2 100644 --- a/docs/build/reference/module-reference.md +++ b/docs/build/reference/module-reference.md @@ -1,32 +1,34 @@ --- -title: "/module:reference (Use named module IFC)" -description: "Use the /module:reference compiler option to create module header units for the header-name or include files specified." -ms.date: 09/13/2020 -f1_keywords: ["/module:reference"] -helpviewer_keywords: ["/module:reference", "Use named module IFC"] +title: "/reference (Use named module IFC)" +description: "Use the /reference compiler option to create module header units for the header-name or include files specified." +ms.date: 04/13/2020 +f1_keywords: ["/reference"] +helpviewer_keywords: ["/reference", "Use named module IFC"] --- -# `/module:reference` (Use named module IFC) +# `/reference` (Use named module IFC) Tells the compiler to use an existing IFC (*`.ifc`*) for the current compilation. ## Syntax -> **`/module:reference`** *`module-name=filename`*\ -> **`/module:reference`** *`filename`* +> **`/reference`** *`module-name=filename`*\ +> **`/reference`** *`filename`* ### Arguments *`filename`*\ -The name of a file that contains *IFC data*, prebuilt module information. To import more than one module, include a separate **`/module:reference`** option for each file. +The name of a file that contains *IFC data*, which is prebuilt module information. To import more than one module, include a separate **`/reference`** option for each file. *`module-name`*\ A valid name of an exported primary module interface unit name or full module partition name. ## Remarks -The **`/module:reference`** compiler option requires you enable experimental modules support by use of the [`/experimental:module`](experimental-module.md) compiler option, along with the [/std:c++latest](std-specify-language-standard-version.md) option. This option is available starting in Visual Studio 2019 version 16.8. +In most cases you won't need to specify this switch because the project system discovers module dependencies within a solution automatically. -If the **`/module:reference`** argument is a *`filename`* without a *`module-name`*, the file gets opened at runtime to verify the *`filename`* argument names a specific import. It can result in slower runtime performance in scenarios that have many **`/module:reference`** arguments. +The **`/reference`** compiler option requires you enable the [/std:c++latest](std-specify-language-standard-version.md) option. The **`/reference`** option is available starting in Visual Studio 2019 version 16.10 Preview 2. + +If the **`/reference`** argument is a *`filename`* without a *`module-name`*, the file gets opened at runtime to verify the *`filename`* argument names a specific import. It can result in slower runtime performance in scenarios that have many **`/reference`** arguments. The *`module-name`* must be a valid primary module interface unit name or full module partition name. Examples of primary module interface names include: @@ -45,7 +47,7 @@ Examples of full module partition names include: If a module reference is created using a *`module-name`*, other modules on the command line don't get searched if the compiler encounters an import of that name. For example, given this command line: ```cmd -cl ... /experimental:module /module:reference m.ifc /module:reference m=n.ifc +cl ... /std:c++latest /reference m.ifc /reference m=n.ifc ``` In the case above, if the compiler sees `import m;` then *`m.ifc`* doesn't get searched. @@ -60,31 +62,20 @@ Given three modules as listed in this table: | *`M:Part1`* | *`m-part1.ifc`* | | *`Core.Networking`* | *`Networking.ifc`* | -The reference options using a *`filename`* argument could look like: +The reference options using a *`filename`* argument would be like this: ```cmd -cl ... /experimental:module /module:reference m.ifc /module:reference m-part.ifc /module:reference Networking.ifc +cl ... /std:c++latest /reference m.ifc /reference m-part.ifc /reference Networking.ifc ``` -The reference options using *`module-name=filename`* could look like: +The reference options using *`module-name=filename`* would be like this: ```cmd -cl ... /experimental:module /module:reference m=m.ifc /module:reference M:Part1=m-part.ifc /module:reference Core.Networking=Networking.ifc +cl ... /std:c++latest /reference m=m.ifc /reference M:Part1=m-part.ifc /reference Core.Networking=Networking.ifc ``` -### To set this compiler option in the Visual Studio development environment - -1. Open the project's **Property Pages** dialog box. For details, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md). - -1. Set the **Configuration** drop-down to **All Configurations**. - -1. Select the **Configuration Properties** > **C/C++** > **Command Line** property page. - -1. Modify the **Additional Options** property to add the *`/module:reference`* option and its arguments. Then, choose **OK** or **Apply** to save your changes. - ## See also -[`/experimental:module` (Enable module support)](experimental-module.md)\ +[`/sourceDependencies:directives` (List module and header unit dependencies)](sourcedependencies-directives.md)\ [`/headerUnit` (Use header unit IFC)](headerunit.md)\ -[`/module:exportHeader` (Create header units)](module-exportheader.md)\ -[`/translateInclude` (Translate include directives into import directives)](translateinclude.md) +[`/exportHeader` (Create header units)](module-exportheader.md) diff --git a/docs/build/reference/sourcedependencies-directives.md b/docs/build/reference/sourcedependencies-directives.md new file mode 100644 index 00000000000..99ad668327c --- /dev/null +++ b/docs/build/reference/sourcedependencies-directives.md @@ -0,0 +1,104 @@ +--- +title: "/sourceDependencies:directives (List module and header unit dependencies)" +description: "Reference guide to the /sourceDependencies:directives compiler option in Microsoft C++." +ms.date: 04/13/2020 +author: "tylermsft" +ms.author: "twhitney" +f1_keywords: ["/sourceDependencies:directives"] +helpviewer_keywords: ["/sourceDependencies:directives compiler option", "/sourceDependencies:directives"] +--- +# `/sourceDependencies:directives` (List module and header unit dependencies) + +This command-line switch generates a JSON file that lists module and header-unit dependencies. + +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 ;` or `import "library";` as a header unit dependency, and `import name;` as a module dependency. + +This command-line option is similar to [`/sourceDependencies`](sourcedependencies.md), but differs in the following ways: + +- The compiler doesn't produce compiled output. Instead, the files are scanned for module directives. No compiled code, modules, or header units are produced. +- The output JSON file doesn't list imported modules and imported header units (*`.ifc`* files) because this switch does a scan of the project files, not a compilation. So there are no built modules or header units to list. +- Only directly imported modules or header units are listed. It doesn't list the dependencies of the imported modules or header units themselves. +- Header file dependencies are not listed. That is, `#include ` or `#include "file"` dependencies are not listed. +- `/sourceDependencies:directives`is meant to be used before *`.ifc`* files are built. + +## Syntax + +> **`/sourceDependencies:directives`** -\ +> **`/sourceDependencies:directives`** *filename*\ +> **`/sourceDependencies:directives`** *directory*\ + +## Arguments + +*`-`*\ +If the single dash is provided, then the compiler will emit the source dependencies JSON to `stdout`, or to where compiler output is redirected to. + +*`filename`*\ +The compiler writes the source dependency output to the specified filename, which may include a relative or absolute path. + +*`directory`*\ +If the argument is a directory, the compiler generates source dependency files in the specified directory. The output file name is based on the full name of the input file, with an appended *`.json`* extension. For example, if the file provided to the compiler is *`main.cpp`*, the generated output filename is *`main.cpp.json`*. + +## Remarks + +**`/sourceDependencies:directives`** is available starting in Visual Studio 2019 version 16.10 Preview 2. It's not enabled by default. + +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). + +When a non-fatal compiler error occurs, the dependency information still gets written to the output file. + +All file paths appear as absolute paths in the output. + +### Examples + +Given the following sample code: + +```cpp +//main.cpp: +#include + +import m; +import std.core; + +import ; + +import "t.h"; + +int main() {} +``` + +> `cl /std:c++latest /sourceDependencies:directives output.json main.cpp` + +This command line produces a JSON file *`output.json`* with content like: + +```JSON +{ + "Version":"1.1", + "Data":{ + "Source":"C:\\a\\b\\main.cpp", + "ProvidedModule":"", + "ImportedModules":[ + "m", + "std.core" + ], + "ImportedHeaderUnits":[ + "C:\\...\\utility", + "C:\\a\\b\\t.h" + ] + } +} +``` + +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. + +`ProvidedModule` lists exported module or module partition names. + +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. + +## To set this compiler option in Visual Studio + +You normally shouldn't set this yourself in the Visual Studio development environment. It is set by the build system. + +## See also + +[MSVC compiler options](compiler-options.md)\ +[MSVC compiler command-line syntax](compiler-command-line-syntax.md) \ No newline at end of file diff --git a/docs/build/reference/sourcedependencies.md b/docs/build/reference/sourcedependencies.md index 071ee81dcab..d5405349d64 100644 --- a/docs/build/reference/sourcedependencies.md +++ b/docs/build/reference/sourcedependencies.md @@ -1,31 +1,38 @@ --- title: "/sourceDependencies (Report source-level dependencies)" -description: "Reference guide to the /sourceDependencies compiler option in Microsoft C++." -ms.date: 07/29/2020 +description: "Describes the /sourceDependencies compiler option in Microsoft C++." +ms.date: 04/13/2020 +author: "tylermsft" +ms.author: "twhitney" f1_keywords: ["/sourceDependencies"] helpviewer_keywords: ["/sourceDependencies compiler option", "/sourceDependencies"] --- -# `/sourceDependencies` (Report source-level dependencies) +# `/sourceDependencies` (List all source-level dependencies) -Instructs the compiler to generate a JSON file that details the source-level dependencies consumed during compilation. +This command-line switch generates a JSON file that details the source-level dependencies consumed during compilation. The JSON file contains a list of the source dependencies, which include: -The JSON file contains a list of the source dependencies, which include: - -- Header files (both transitive and directly included headers). +- Header files. Both directly included and the list of headers included by those headers. - The PCH used (if **`/Yu`** is specified). -- Imported modules and imported header units (both transitive and directly imported modules/header units). +- Names of imported modules +- File paths and names of imported header units. Both directly imported and those imported by those modules and headers units. + +This provides information necessary to build modules and header units in the proper dependency order. ## Syntax +> **`/sourceDependencies`** -\ > **`/sourceDependencies`** *filename*\ > **`/sourceDependencies`** *directory* ## Arguments -*filename*\ +*`-`*\ +If the single dash is provided, then the compiler will emit the source dependencies JSON to `stdout`, or to where compiler output is redirected to. + +*`filename`*\ The compiler writes the source dependency output to the specified filename, which may include a relative or absolute path. -*directory*\ +*`directory`*\ If the argument is a directory, the compiler generates source dependency files in the specified directory. The output file name is based on the full name of the input file, with an appended *`.json`* extension. For example, if the file provided to the compiler is *`main.cpp`*, the generated output filename is *`main.cpp.json`*. ## Remarks @@ -43,50 +50,61 @@ All file paths appear as absolute paths in the output. Given the following sample code: ```cpp -// main.cpp -#include "header.h" -import m; -import "other.h"; - -int main() { } +// ModuleE.ixx: +export module ModuleE; +import ModuleC; +import ModuleD; +import ; ``` -You can use **`/sourceDependencies`** along with the rest of your compiler options: +You can use **`/sourceDependencies`** with the rest of your compiler options: > `cl ... /sourceDependencies output.json ... main.cpp` -where `...` represents your other compiler options. This command line produces a JSON file *`output.json`* with content something like: +where `...` represents your other compiler options. This command line produces a JSON file *`output.json`* with content like: ```JSON { - "Version": "1.0", + "Version": "1.1", "Data": { - "Source": "C:\\...\\main.cpp", - "PCH": "C:\\...\\pch.pch", - "Includes": [ - "C:\\...\\header.h" + "Source": "F:\\Sample\\myproject\\modulee.ixx", + "ProvidedModule": "ModuleE", + "Includes": [], + "ImportedModules": [ + { + "Name": "ModuleC", + "BMI": "F:\\Sample\\Outputs\\Intermediate\\MyProject\\x64\\Debug\\ModuleC.ixx.ifc" + }, + { + "Name": "ModuleB", + "BMI": "F:\\Sample\\Outputs\\Intermediate\\ModuleB\\x64\\Debug\\ModuleB.ixx.ifc" + }, + { + "Name": "ModuleD", + "BMI": "F:\\Sample\\Outputs\\Intermediate\\MyProject\\x64\\Debug\\ModuleD.cppm.ifc" + } ], - "Modules": [ - "C:\\...\\m.ifc", - "C:\\...\\other.h.ifc" + "ImportedHeaderUnits": [ + { + "Header": "f:\\visual studio 16 main\\vc\\tools\\msvc\\14.29.30030\\include\\iostream", + "BMI": "F:\\Sample\\Outputs\\Intermediate\\HeaderUnits\\x64\\Debug\\iostream_W4L4JYGFJ3GL8OG9.ifc" + }, + { + "Header": "f:\\visual studio 16 main\\vc\\tools\\msvc\\14.29.30030\\include\\yvals_core.h", + "BMI": "F:\\Sample\\Outputs\\Intermediate\\HeaderUnits\\x64\\Debug\\yvals_core.h.ifc" + } ] } } ``` -We've used `...` 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 may want to check your project's include path settings. - -### To set the /sourceDependencies compiler option in Visual Studio - -1. Open the **Property Pages** dialog box for the project. For more information, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md). - -1. Select the **Configuration Properties** > **C/C++** > **Command Line** property page. +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. -1. In the **Additional options** box, add *`/sourceDependencies: `* and then choose **OK** or **Apply** to save your changes. +`ProvidedModule` lists exported module or module partition names. -### To set this compiler option programmatically +### To set this compiler option in the Visual Studio development environment -- This option doesn't have a programmatic equivalent. +You normally shouldn't set this yourself in the Visual Studio development environment. It is set by the build system. ## See also diff --git a/docs/build/reference/translateinclude.md b/docs/build/reference/translateinclude.md index 2b187744ec9..f8cf53733d6 100644 --- a/docs/build/reference/translateinclude.md +++ b/docs/build/reference/translateinclude.md @@ -1,13 +1,15 @@ --- title: "/translateInclude (Translate include directives into import directives)" -description: "Use the /translateInclude compiler option to translate #include directives for an importable header-name into an import header-name directive." -ms.date: 09/13/2020 +description: "Use the /translateInclude compiler option to treat #include directives as import statements when an importable header unit is available." +ms.date: 4/13/2021 +author: "tylermsft" +ms.author: "twhitney" f1_keywords: ["/translateInclude"] helpviewer_keywords: ["/translateInclude", "Translate include directives into import directives"] --- # `/translateInclude` (Translate include directives into import directives) -Tells the compiler to translate `#include` directives for an importable header-name into an `import header-name;` directive, rather than use textual inclusion. +Instructs the compiler to treat `#include` as `import` for those headers that have been prebuilt into a header unit (`.ifc`) file. ## Syntax @@ -15,9 +17,9 @@ Tells the compiler to translate `#include` directives for an importable header-n ## Remarks -The **`/translateInclude`** compiler option requires you enable experimental modules support by use of the [`/experimental:module`](experimental-module.md) compiler option, along with the [/std:c++latest](std-specify-language-standard-version.md) option. This option is available starting in Visual Studio 2019 version 16.8. +The **`/translateInclude`** compiler option requires you enable the [/std:c++latest](std-specify-language-standard-version.md) option. `/translateInclude` is available starting in Visual Studio 2019 version 16.10 Preview 2. -The **`/translateInclude`** option effectively makes the following transformation, where the example `` is an importable header unit: +The **`/translateInclude`** option effectively makes the following transformation, where the example `` has been prebuilt into an importable header unit: ```cpp #include @@ -26,10 +28,10 @@ The **`/translateInclude`** option effectively makes the following transformatio The compiler replaces this directive with: ```cpp -import ; +import ; ``` -In MSVC an importable header unit is one named by a **`/headerUnit`** reference. For more information, see [`/headerUnit` (Use header unit IFC)](headerunit.md). +In MSVC, available header units are made available by the **`/headerUnit`** option, which maps a header file to its corresponding prebuilt importable header unit. For more information, see [`/headerUnit` (Specify where to find the header unit file (`.ifc`) for the specified header)](headerunit.md). ### Examples @@ -49,25 +51,27 @@ And a source *`.cpp`* file that includes the headers, int main() { } ``` -The **`/translateInclude`** option allows the compiler to import the header units instead of compile the headers again. Here's an example command line that translates the include directives for *`util.h`* and *`app.h`* into imports of the header units instead: +The **`/translateInclude`** option allows the compiler to treat an `#include` as an `import` for header files that have a corresponding compiled header unit file (*`.ifc`*) and that have been specified on the command line via the `/headerUnit` switch. + +If an `#include` is encountered that doesn't have a corresponding header unit specified via the `/headerUnit` switch, it is processed by the preprocessor as a normal `#include` directive. + + Here's an example command line that translates the include directives for *`util.h`* and *`app.h`* into imports of the header units instead: ```CMD -cl /IC:\ /experimental:module /translateInclude /headerUnit C:\utils\util.h=C:\util.h.ifc /headerUnit C:\app\app.h=C:\app.h.ifc +cl /IC:\ /translateInclude /headerUnit C:\utils\util.h=C:\util.h.ifc /headerUnit C:\app\app.h=C:\app.h.ifc ``` -### To set this compiler option in the Visual Studio development environment - -1. Open the project's **Property Pages** dialog box. For details, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md). +## To set this compiler option in Visual Studio -1. Set the **Configuration** drop-down to **All Configurations**. +To enable `/translateInclude`, set the **Translate Includes to Imports** option in project properties: -1. Select the **Configuration Properties** > **C/C++** > **Command Line** property page. +1. In the left-hand pane of the project property pages, select **Configuration Properties** > **C/C++** > **General** +1. Change the **Translate Includes to Imports** dropdown to **Yes** +![Project properties dialog set Translate Includes to Imports](../media/vs2019-translate-includes-option.png) -1. Modify the **Additional Options** property to add the *`/translateInclude`* option. Then, choose **OK** or **Apply** to save your changes. ## See also -[`/experimental:module` (Enable module support)](experimental-module.md)\ [`/headerUnit` (Use header unit IFC)](headerunit.md).\ -[`/module:exportHeader` (Create header units)](module-exportheader.md)\ -[`/module:reference` (Use named module IFC)](module-reference.md) +[`/exportHeader` (Create header units)](module-exportheader.md)\ +[`/reference` (Use named module IFC)](module-reference.md) diff --git a/docs/build/reference/y-precompiled-headers.md b/docs/build/reference/y-precompiled-headers.md index f218371a2a1..1dd5938fb80 100644 --- a/docs/build/reference/y-precompiled-headers.md +++ b/docs/build/reference/y-precompiled-headers.md @@ -1,28 +1,27 @@ --- -description: "Learn more about: /Y (Precompiled Headers)" -title: "/Y (Precompiled Headers)" +description: "Learn more about: /Y (precompiled headers)" +title: "/Y (precompiled headers)" ms.date: "11/04/2016" f1_keywords: ["/Y"] helpviewer_keywords: ["/Y compiler options [C++]"] -ms.assetid: 1df5726a-8ebe-42c3-b618-d2f5e1ce8673 --- -# /Y (Precompiled Headers) +# /Y (precompiled headers) The following compiler options affect the generation and use of precompiled headers: -- [/Y- (Ignore Precompiled Header Options)](y-ignore-precompiled-header-options.md) +- [/Y- (Ignore precompiled header options)](y-ignore-precompiled-header-options.md) -- [/Yc (Create Precompiled Header File)](yc-create-precompiled-header-file.md) +- [/Yc (Create precompiled header file)](yc-create-precompiled-header-file.md) -- [/Yd (Place Debug Information in Object File)](yd-place-debug-information-in-object-file.md) +- [/Yd (Place Debug Information in Object file)](yd-place-debug-information-in-object-file.md) -- [/Yl (Inject PCH Reference for Debug Library)](yl-inject-pch-reference-for-debug-library.md) +- [/Yl (Inject PCH reference for debug library)](yl-inject-pch-reference-for-debug-library.md) -- [/Yu (Use Precompiled Header File)](yu-use-precompiled-header-file.md) +- [/Yu (Use precompiled header file)](yu-use-precompiled-header-file.md) -For details on working with precompiled headers, see [Precompiled Header Files](../creating-precompiled-header-files.md). +For details on working with precompiled headers, see [precompiled header files](../creating-precompiled-header-files.md). ## See also -[MSVC Compiler Options](compiler-options.md)
-[MSVC Compiler Command-Line Syntax](compiler-command-line-syntax.md) +[MSVC compiler options](compiler-options.md)\ +[MSVC compiler command-line syntax](compiler-command-line-syntax.md) diff --git a/docs/build/toc.yml b/docs/build/toc.yml index 1f730724a73..a695cad0a15 100644 --- a/docs/build/toc.yml +++ b/docs/build/toc.yml @@ -61,6 +61,10 @@ href: ../build/clang-support-cmake.md - name: Configure a Linux CMake project href: ../build/../linux/cmake-linux-project.md + - name: Configure and build with CMake Presets + href: ../build/cmake-presets-vs.md + - name: CMakePresets.json reference + href: ../build/cmake-presets-json-reference.md - name: Customize CMake build settings href: ../build/customize-cmake-settings.md - name: Configure CMake debugging sessions @@ -84,6 +88,13 @@ href: ../build/vcpkg-command-line-reference.md - name: "C++ Build Insights" href: ../build-insights/get-started-with-cpp-build-insights.md +- name: "Build and import header units" + expanded: false + items: + - name: "Walkthrough: Build and import header units in Visual C++ projects" + href: ../build/walkthrough-header-units.md + - name: "Walkthrough: Import STL libraries as header units" + href: ../build/walkthrough-import-stl-header-units.md - name: Precompiled header files href: ../build/creating-precompiled-header-files.md - name: C++ release builds @@ -602,6 +613,8 @@ href: ../build/reference/gz-enable-stack-frame-run-time-error-checking.md - name: /H (Restrict length of external names) href: ../build/reference/h-restrict-length-of-external-names.md + - name: /headerName (Build a header unit from the specified header) + href: ../build/reference/headername.md - name: /headerUnit (Use header unit IFC) href: ../build/reference/headerunit.md - name: /HELP (Compiler command-line help) @@ -624,9 +637,9 @@ href: ../build/reference/ln-create-msil-module.md - name: /MD, /MT, /LD (Use Run-time library) href: ../build/reference/md-mt-ld-use-run-time-library.md - - name: /module:exportHeader (Create header units) + - name: /exportHeader (Create header units) href: ../build/reference/module-exportheader.md - - name: /module:reference (Use named module IFC) + - name: /reference (Use named module IFC) href: ../build/reference/module-reference.md - name: /MP (Build with multiple processes) href: ../build/reference/mp-build-with-multiple-processes.md @@ -694,8 +707,10 @@ href: ../build/reference/showincludes-list-include-files.md - name: /source-charset (Set source character set) href: ../build/reference/source-charset-set-source-character-set.md - - name: /sourceDependencies (Report source-level dependencies) + - name: /sourceDependencies (List all source-level dependencies) href: ../build/reference/sourcedependencies.md + - name: /sourceDependencies:directives (List module and header unit dependencies) + href: ../build/reference/sourcedependencies-directives.md - name: /std (Specify language standard version) href: ../build/reference/std-specify-language-standard-version.md - name: /Tc, /Tp, /TC, /TP (Specify source file type) diff --git a/docs/build/walkthrough-header-units.md b/docs/build/walkthrough-header-units.md new file mode 100644 index 00000000000..e81fe406b27 --- /dev/null +++ b/docs/build/walkthrough-header-units.md @@ -0,0 +1,110 @@ +--- +description: "Learn more about C++ header units by converting a header file to a header unit" +title: "Walkthrough: Build and import header units in Microsoft Visual C++ projects" +ms.date: "4/13/2021" +ms.custom: "conceptual" +author: "tylermsft" +ms.author: "twhitney" +helpviewer_keywords: ["import", "header unit", "ifc"] +--- + +# Walkthrough: Build and import header units in Microsoft Visual C++ + +This article is about building and importing header units using Visual Studio 2019. See [Walkthrough: Import STL libraries using header units](walkthrough-import-stl-header-units.md) to learn specifically how to import Standard Template Library headers as header units. + +Header units are the recommended alternative to [precompiled header files](creating-precompiled-header-files.md) (PCH). They're easier to set up and easier to use than a [shared PCH](https://devblogs.microsoft.com/cppblog/shared-pch-usage-sample-in-visual-studio), while providing similar performance benefits. Unlike a PCH, when a header unit changes, only it and its dependencies are rebuilt. + +## Prerequisites + +Support for header units requires at least Visual Studio 2019 16.10.0 Preview 2. + +## What is a header unit + +Header units are a binary representation of a header file, and end with an *`.ifc`* extension. This is also the format used for named modules. + +An important difference between a header unit and a header file is that header units aren't affected by macro definitions. You can't `#define` a symbol that causes the header unit to behave differently when you import it, the way that you can with a header file. + +A similarity is that everything visible from a header file is also visible from a header unit. + +Before you can import a header unit, a header file must be compiled into a header unit. An advantage of header units over a PCH is that it can be used in distributed builds. For example, as long as you're using the same compiler to compile the *`.ifc`* and the program that imports it, and are targeting the same platform and architecture, a header unit produced on one machine can be used on another. + +Another advantage of header units over PCHs is that there's more flexibility when it comes to the compiler flags used to compile the header unit and the program that imports it. With a PCH, more compiler flags must be the same. But with header units, the primary flags that should be the same include: + +- Exception handling switches such as `/EHsc` +- `/MD[d]` or `MT[d]` +- `/D` You can define additional macros when building the program that imports the header unit, but those used to build the header unit should also be present and defined the same way when building the program that imports the header unit. + +## Ways to compile a header unit + +There are several ways to compile a file into a header unit: + +- **Automatically scan for header units**: This approach is best suited to smaller projects that include many different header files. See [Walkthrough: Import STL libraries as header units](walkthrough-import-stl-header-units.md#approach1) for a demonstration of this approach. The reason it's better suited to smaller projects is because it can't guarantee optimal build throughput since it scans all of the files to find what should be built into header units. + +- **Build a shared header unit project**: This approach is best suited for larger projects, and for when you want more control over the organization of the imported header units. You create a static library project (or projects) that contain the header units that you want. Then reference the library project (or projects) from the project that then imports the header units it needs. See [Walkthrough: Import STL libraries as header units](walkthrough-import-stl-header-units.md#approach2) for a demonstration of this approach. + +- **Choose individual header units to build**: This approach gives you file by file control over which header files are treated as header units. It's also a good way to quickly and selectively try out header units in your project. This approach is demonstrated in this walkthrough. + +## Convert a project to use header units + +In this example, you'll compile a header file as a header unit. Begin by creating the following project in Visual Studio: + +1. Create a new C++ console app project. +1. Replace the source file contents as follows: + ```cpp + #include "Pythagorean.h" + + int main() + { + PrintPythogoreanTriple(2,3); + return 0; + } + ``` +1. Add a header file called `Pythagorean.h`, and replace its contents with the following: + ```cpp + #pragma once + #include + + void PrintPythogoreanTriple(int a, int b) + { + std::cout << "Pythagorean triple a:" << a << " b:" << b << " c:" << a*a + b*b << std::endl; + } + ``` + +To enable header units, first set the **C++ Language Standard** to [`/std:c++latest`](./reference/std-specify-language-standard-version.md): + +1. From the Visual Studio main menu, choose **Project** > **Properties**. +1. In the left-hand pane of the project property pages window, select **Configuration Properties** > **General**. +1. Change the **C++ Language Standard** dropdown to **Preview-Features from the Latest C++ Working Draft (/std:c++latest)**. +:::image type="content" source="media/set-cpp-language-latest.png" alt-text="Screenshot showing setting the language standard to preview version."::: + +### Compile a header file as a header unit + +In the **Solution Explorer**, select the file you want to compile as a header unit. Right-click that file, and select **Properties**. Then do one of the following, depending on the file type: + +**For header files**: + +Set the **Item Type** property to **C/C++ compiler**. By default, header files have an **Item Type** of **C/C++ header**. Setting this property also sets **C/C++** > **Advanced** > **Compile As** to **Compile as C++ Header Unit (/exportHeader)** for you. +:::image type="content" source="media/change-item-type.png" alt-text="Screenshot showing changing the item type to c/c++ compiler."::: + +**For source files** (or header files that don't have a `.h` or `.hpp` extension): + +Set the **Compile As** property to **Compile as C++ Header Unit (/exportHeader)**. +:::image type="content" source="media/change-compile-as.png" alt-text="Screenshot showing changing Compile As to Compile as C++ Header Unit."::: + +### Change your code to import a header unit + +In the source file for the example project, that is, the file that contains `main()`, change `#include "Pythagorean.h"` to `import "Pythagorean.h";` (don't forget the trailing semicolon that is required for `import` statements). When you're compiling a header unit from a system header, use angle brackets (`import ;`). If it's a project header, use `import "file";` + +Build the solution (**Build** > **Build Solution** from the main menu) and run it to see that it produces the expected output: `Pythagorean triple a:2 b:3 c:13` + +In your own projects, repeat this process to compile the header files you want to import as header units. + +If you only want to convert a few header files to header units, this is a good approach. But if you have many header files that you want to compile, and the convenience of having the build system automatically handle it outweighs the potential impact on build performance, you can have the build system scan for, and build, header units for you. See [Walkthrough: Import STL libraries as header units](walkthrough-import-stl-header-units.md#approach1) to learn how. + +## See also + +[Walkthrough: Import STL libraries as header units](walkthrough-import-stl-header-units.md#approach1)\ +[Overview of modules in C++](../cpp/modules-cpp.md) \ +[`/translateInclude`](./reference/translateinclude.md) \ +[`/exportHeader`](./reference/module-exportheader.md) \ +[`/headerUnit`](./reference/headerunit.md) \ No newline at end of file diff --git a/docs/build/walkthrough-import-stl-header-units.md b/docs/build/walkthrough-import-stl-header-units.md new file mode 100644 index 00000000000..a4884eb1cc1 --- /dev/null +++ b/docs/build/walkthrough-import-stl-header-units.md @@ -0,0 +1,237 @@ +--- +description: "Learn to use header units to import C++ Standard Template Library (STL) libraries." +title: "Walkthrough: Import Standard Template Library (STL) libraries as header units" +ms.date: "4/13/2021" +ms.custom: "conceptual" +author: "tylermsft" +ms.author: "twhitney" +helpviewer_keywords: ["import", "header unit", "ifc", "stl"] +--- +# Walkthrough: Import STL libraries as header units + +This walkthrough shows two different ways to import C++ Standard Template Library (STL) libraries as header units in Visual Studio. + +The [first way](#approach1) has the build system automatically scan for, and build, header units based on what STL headers you import in your project. + +The [second way](#approach2) demonstrates how to build a static library project containing header units for the STL headers you want to use, and then reference that project to import the header units. + +Importing a STL header as a header unit is a simpler alternative to [precompiled header files](creating-precompiled-header-files.md). Header units are easier to set up and easier to use than a shared precompiled header file (PCH), while providing similar performance benefits. Unlike a PCH, when a header unit changes, only it and its dependencies are rebuilt. + +Before you can import an STL header, it must be compiled into a header unit. Header units are a binary representation of a header file, and end with an *`.ifc`* extension. + +An important difference between a header unit and a header file is that header units aren't affected by macro definitions. You can't `#define` a symbol that causes the header unit to behave differently when you import it, the way that you can with a header file. + +A similarity is that everything visible from a header file is also visible from a header unit. + +## Prerequisites + +Support for header units requires at least Visual Studio 2019 16.10.0 Preview 2. + +## Two different approaches + +Before an STL header can be imported, it must be compiled into a header unit. There are two main approaches, demonstrated below. + +**Scan for module dependencies** + +At a high level, this works by scanning your sources for `import "header";` and `import
;` statements, and tries to compile those header files and their dependencies into header units. It then imports the compiled header unit files (*`.ifc`*) instead of running the header file through the preprocessor. + +It may not be the optimal approach for larger projects because it doesn't guarantee optimal build times as it needs to scan through the files to find the headers to build into header units. It may result in reprocessing the same header files repeatedly, increasing build time. Also, not all header files can be automatically converted to header units. For example, headers that depend on conditional compilation via `#define` symbols may not work as header units. If a header file can't be compiled into a header unit, it is treated as a normal `#include` file. + +See [Approach 1: Scan for headers](#approach1), in this article, to walkthrough this approach. + +**Create a static library project** + +The recommended approach, particularly for larger projects, or in cases where you want to share a common set of header units across multiple projects, is to create a static library project containing the header units you want to share. This library project is then referenced by projects that import those header units. It's like using [shared precompiled headers](https://devblogs.microsoft.com/cppblog/shared-pch-usage-sample-in-visual-studio/), but easier. + +See [Approach 2: Build a static library project](#approach2), in this article, for a walkthrough of this approach. + +## Approach 1: Scan for imports + +We'll begin with the easiest way to import STL libraries as header units. This approach may not be appropriate for larger projects because it doesn't guarantee the most optimal build time due to scanning the sources for `import` statements. + +This option is convenient for codebases that use many different headers, and where build throughput isn't critical. This option doesn't guarantee a header unit for a particular header will be built only once, whereas header units that are part of referenced static libraries projects are reused. + +You can import your STL libraries as header units without modifying your code by setting the Visual C++ project **Scan Sources for Module Dependencies** option. + +This setting causes the build system to scan your source code for `import` directives and tries to compile the imported header file into a header unit. There are other ways to indicate that a header file should be treated as a header unit besides scanning your entire project. That is covered in [Walkthrough: Build and import header units in Visual C++ projects](walkthrough-header-units.md). + +Not all headers can be converted to a header unit. One issue is header files that rely on `#define` symbols to cause the header file to compile differently. If a header file relies on this mechanism, it won't be converted to a header unit. Instead, it is treated as an ordinary `#include`. + +To demonstrate this approach, we'll create a project that imports two STL libraries, and then change the project properties so that it treats the libraries as header units. + +### Create a C++ console app project + +This step creates a project that includes two libraries: `` and ``. You'll modify the project settings so that the project is scanned for potential header files that can be compiled into header units. + +1. With Visual Studio, create a new C++ console app project. +1. Modify the source file as follows: + ```cpp + import ; + import ; + + int main() + { + std::vector numbers = {0, 1, 2}; + std::cout << numbers[1]; + } + ``` + +### Set project options and run the project + +Follow these steps to set the options that cause the build system to scan for imported headers that can be compiled into header units: + +1. From the main menu, choose **Project** > **Properties**. The project properties window appears: +:::image type="content" source="media/vs2019-scan-module-dependencies.png" alt-text="Screenshot showing the scan module dependencies property setting in the project properties window."::: +1. You may want to set the **Configuration** dropdown to **All Configurations** and **Platform** dropdown to **All Platforms**. This propagates the settings you change to apply whether you are building for debug or release, and so on. +1. In the left-hand pane of the project property page, select **C/C++** > **General**. +1. Set **Scan Sources for Module Dependencies** to **Yes**. Because we're setting the project property, all sources in this project will be scanned. + +Change the C++ language standard for the compiler. The [`/std:c++latest`](./reference/std-specify-language-standard-version.md) switch is required to use header units: + +1. In the left-hand pane of the project property pages, select **Configuration Properties** > **General**. +1. Change the **C++ Language Standard** dropdown to **Preview-Features from the Latest C++ Working Draft (/std:c++latest)**. +:::image type="content" source="media/set-cpp-language-latest.png" alt-text="Screenshot showing where to set the language standard."::: +1. Click **OK** to close the project properties pages, and then build the solution with **Build** > **Build Solution** from the main menu. + +You can run the solution to verify that it produces the expected output: `1` + +The primary consideration of this approach is the balance between convenience and the build cost of scanning all of your files to determine which header files to build as header units. + +You can fine-tune this balance by not scanning for import dependencies, and instead explicitly marking which files should be built as header units. That approach is shown in [Walkthrough: Build and import header units in your Visual C++ projects](walkthrough-header-units.md) + +## Approach 2: Build a static library project + +The more flexible way to consume STL headers is to create one or more static library projects that build the header units from the STL headers that you want to reuse. Then reference the library project, or library projects, from the projects that need those STL headers. Modules and header units built in a static library project are automatically available to referencing projects. The project system automatically adds the appropriate [`/headerUnit](./reference/headerunit.md) switches to the command line so that the header units can be imported by the referencing projects. + +This option ensures that header units for a particular header will be built only once. It's similar to using a shared precompiled header file, but is much easier. + +In this example, you'll create a project that imports `` and ``. Once built, you'll reference this shared header unit project from another C++ project. Then, in the referencing project, everywhere `import ;` or `import ;` is found, it will import the built header unit for that library instead of running the contents of the library header through the preprocessor. In projects that include the same library header in multiple files, this will improve build performance similarly to how PCH files do because the header won't have to be processed over and over by the files that include it. Instead, the already processed compiled header unit will be imported. + +### Create the shared header unit project + +Begin by creating the project for the shared header unit as follows: + +1. Create an Empty C++ project. Call it, for the sake of this example, **SharedPrj**.\ + Select **Empty C++ project** from the project types available on the **Create a new project** window: +:::image type="content" source="media/empty-project-option.png" alt-text="Screenshot showing creating a new empty C++ project."::: +1. Add a new (empty) C++ file to the project. Change the file's contents to the following: + + ```cpp + import ; + import ; + ``` + +### Set project properties + +Set project properties to share the header units from this project: + +1. From the Visual Studio main menu, choose **Project** > **Properties**. The project properties window appears: +:::image type="content" source="media/set-header-unit-library-settings.png" alt-text="Screenshot showing settings for Configuration type and C++ language standard."::: +1. You may want to set the **Configuration** dropdown to **All Configurations** and **Platform** dropdown to **All Platforms**. This propagates the settings you change so that they apply whether you are building for debug or retail, and so on. +1. In the left-hand pane of the project property page, select **General** +1. Change the **Configuration Type** option to **Static library (.lib)** +1. Change **C++ Language Standard** to **Preview-Features from the Latest C++ Working Draft (/std:c++latest)** +1. In the left-hand pane of the project property page, select **C/C++** > **General** +:::image type="content" source="media/vs2019-scan-module-dependencies.png" alt-text="Screenshot showing the scan module dependencies property setting."::: +1. Set the **Scan Sources for Module Dependencies** dropdown to **Yes** +1. Click **OK** to close the project properties pages and then build the solution by selecting **Build** > **Build Solution** from the main menu. + +## Reference the shared header unit project + +Next, create a project that will use the built `` and `` shared header project: + +1. With the current solution still open, from the Visual Studio menu select **File** > **Add** > **New Project**. +1. Add a C++ Console app project. Call it **Walkthrough**, for this example. +1. Change the contents of its source file as follows: + + ```cpp + import ; + import ; + + int main() + { + std::vector numbers = {0, 1, 2}; + std::cout << numbers[1]; + } + ``` + +Change the **C++ Language Standard** for the compiler. The [`/std:c++latest`](./reference/std-specify-language-standard-version.md) switch is required to use header units: +1. In the **Solution Explorer**, select right-click the **Walkthrough** project and select **Properties**. The project properties window appears. +:::image type="content" source="media/set-cpp-language-latest.png" alt-text="Screenshot showing setting the language standard to preview version"::: +1. In the left-hand pane of the **Walkthrough** project property pages, select **Configuration Properties** > **General** +1. Change **C++ Language Standard** to **Preview-Features from the Latest C++ Working Draft (/std:c++latest)** +1. Click **OK** to close the project properties pages + +Add a reference from the **Walkthrough** project to the **SharedPrj** project. + +1. Under the **Walkthrough** project, click on the **References** node, and select **Add Reference**. Select **SharedPrj** from the list of projects. +:::image type="content" source="./media/add-reference-to-walkthrough.png" alt-text="Screenshot showing the add reference dialog. Used to add a reference to the Walkthrough project."::: +What this reference accomplishes is that the build system will use the header units built by **SharedPrj** whenever an `import` in the **Walkthrough** project matches one of the built header units in **SharedPrj** +1. Click **OK** to close the **Add Reference** dialog +1. Right-click the **Walkthrough** project and select **Set as Startup Project** + +Then you can build the solution (**Build** > **Build Solution** from the main menu) and run it to see that it produces the expected output: `1` + +The advantage of this approach is that you can reference the static library project from any project to reuse the header units in it. In this example, that's `` and ``. + +You can make a monolithic static library project that contains all of the commonly used STL headers that you want to import from your various projects. Or, you can produce smaller shared library projects for the different groupings of STL libraries that you want to import as header units. Then reference those shared header unit projects as needed. + +The result should be increased build throughput because importing a header unit significantly reduces the work the compiler must do. + +It's important when you do this with your own projects that you build the static library project using compiler switches that are compatible with the project that will reference it. For example, STL projects should be built with the `/EHsc` compiler switch to turn on exception handling, and so should the projects that reference the static library project. + +## `/translateInclude` + +The [`/translateInclude`](./reference/translateinclude.md) compiler switch can make it easier for you to use a referenced shared header unit project from your project. + +It is useful because you don't have to modify the `#include` directives in your project to take advantage of importing built header units from the referenced shared header unit project. + +For example, if you `#include ` in your project, and you reference a shared header unit project that contains a header unit for ``, you don't need to manually change `#include ` to `import ;` in your source code. If you specify `/translateInclude` (available in the project properties dialog under **C/C++** > **General** > **Translate Includes to Imports**) the compiler will automatically treat `#include ` as `import ;` This applies to any `#include` statement that refers to a built header unit in a referenced shared header unit project. Otherwise, it will be treated as a normal `#include`. + +## Reuse header units between projects + +Header units built by a static library project are automatically available to all directly and indirectly referencing projects. There are project settings that allow you to select which header units should be automatically available to all referencing projects. The settings are in project settings under **VC++ Directories**: +1. Select the project in the **Solution Explorer**, then right-click the project and select **Properties**. +1. In the left-hand pane of the project properties window, select **VC++ Directories** +:::image type="content" source="media/public-include-module-directories-setting.png" alt-text="Screenshot showing public project content properties such as public include directories, all header files are public, etc."::: + +The following settings control the visibility of header units to the build system: + +- **Public Include Directories**: specifies project directories for header units that should be automatically added to the include path in referencing projects. +- **Public C++ Module directories**: specifies which project directories contain header units that should be available to referencing projects. This is a way of making some header units public by providing a place where you can put header units that can be shared in a place that is made visible to other projects. If you set this, you may also want to specify **Public Include Directories** so your public headers are automatically added to the include path in referencing projects. +- **All Modules are Public** - To use header units built as a part of a DLL project, the symbols have to be exported from the DLL. To do so, set this property to **Yes**. + +## Use a prebuilt module file + +Normally, the easiest way to reuse header units between solutions is to reference the same shared header unit project from each solution. + +But if you have a need to use a built header unit that you don't have the project for, you can specify where the built *`.ifc`* file is so that you can import it in your solution. + +To access this setting: +1. From the main menu, choose **Project** > **Properties**. The project properties window appears. +1. In the left-hand pane of the project properties window, select **C/C++** > **General**. +1. Add the modules to reference in the **Additional Module Dependencies** dropdown. Here's an example of the format to use for **Additional Module Dependencies**: `ModuleName1=Path\To\ModuleName1.ifc; ModuleName2=Path\To\ModuleName2.ifc` +:::image type="content" source="media/vs2019-additional-module-dependencies.png" alt-text="Screenshot showing project properties under C/C++, General, which Additional Module Dependencies selected."::: + +## Select among multiple copies of a header unit + +If you reference two or more projects that built two or more header units with the same name, or that built two or more header units for the same header file, there will be multiple header units to choose from for the same import. You might have different versions of the header unit that were built with different compiler settings, for instance, and need to tell the compiler which one to use. + +Use the project properties **C/C++** > **Additional Header Unit Dependencies** to resolve collisions by specifying which header unit should be used. Otherwise, you can't predict which one gets picked. + +To access this setting: +1. From the main menu, choose **Project** > **Properties**. The project properties window appears. +1. In the left-hand pane of the project properties window, select **C/C++** > **General**. +1. Use **Additional Header Unit Dependencies** to resolve collisions by specifying which module or header unit should be used for this project. This is the format to use for **Additional Header Unit Dependencies**: `Path\To\Header1.h= Path\To\HeaderUnit1.ifc;Path\To\Header2.h= Path\To\ HeaderUnit2.ifc` +:::image type="content" source="media/additional-header-unit-dependencies-setting.png" alt-text="Screenshot showing the Additional Header Unit Dependencies setting in the project properties dialog."::: + +> [!IMPORTANT] +> Ensure that projects that share header units are built with compatible compilation options. The compiler will issue warnings if it detects different compilation options used for how the header unit was produced versus how it's used. + +> [!NOTE] +> To use header units built as a part of a **DLL** project, the project property setting **All Modules arePublic** should be set to **Yes**. + +## See also + +[Walkthrough: Build and import header units in your Visual C++ projects](walkthrough-header-units.md) \ +[`/translateInclude`](./reference/translateinclude.md) diff --git a/docs/standard-library/ranges.md b/docs/standard-library/ranges.md new file mode 100644 index 00000000000..0a6d5eb6823 --- /dev/null +++ b/docs/standard-library/ranges.md @@ -0,0 +1,123 @@ +--- +title: "" +description: "Overview of the Standard Template Library (STL) ranges library" +ms.date: "04/13/2021" +f1_keywords: [""] +helpviewer_keywords: ["ranges"] +--- + +# `` + +At a high level, a range is something you can iterate over. A range abstracts iterators in a way that simplifies and amplifies your ability to use the Standard Template Library (STL). + +STL algorithms usually take iterators that point to the portion of the collection they should operate on. Consider how you sort a `vector` today. To call `std::sort()`, you pass two iterators the mark the beginning and end of the `vector`. That provides flexibility, but passing the iterators to the algorithm is extra noise since most of the time you just want to sort the whole thing. + +With ranges, you can simply call `std::ranges::sort(myVector);` which is treated as if you had called `std::sort(myVector.begin(), myVector.end());` In range libraries, algorithms take ranges as parameters (although they can also take iterators, if you want). Examples of range algorithms available in `` include `copy`, `copy_n`, `copy_if`, `all_of`, `any_of`, and `none_of`, `find`, `find_if`, and `find_if_not`, `count` and `count_if`, `for_each` and `for_each_n`, `equal` and `mismatch`. + +Code that is easier to write and more readable is great, but the benefits of ranges go further than that. They also make it easier to filter and transform collections of data in part by allowing you to compose STL algorithms more easily. + +Because ranges don't own elements like a container does, they're lightweight. The time it takes to copy, move, or assign a range is constant no matter how many elements it points to. + +## A ranges example + +Before ranges, if you wanted to transform only the elements of a collection that meet a certain criteria, you'd need to introduce an intermediate step to hold the results between operations. For example, let's say you want to build a vector of squares from only the elements in another vector that are divisible by 3. You'd write something like: + +```cpp +std::vector input = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; +std::vector intermediate, output; + +std::copy_if(input.begin(), input.end(), std::back_inserter(intermediate), [](const int i) { return i%3 == 0; }); +std::transform(intermediate.begin(), intermediate.end(), std::back_inserter(output), [](const int i) {return i*i; }); +``` + +With ranges, you can accomplish the same thing without needing the `intermediate` vector: + +```cpp +// requires /std:c++latest +std::vector input = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + +auto output = input | std::views::filter([](const int n) {return n % 3 == 0; }) | std::views::transform([](const int n) {return n * n; }); +``` + +Besides being easier to read, it avoids the memory allocation required for the `intermediate` vector and its contents, while also allowing you to compose two operations. + +In the code above, each element that is divisible by three is combined with an operation to square that element. The '`|`' symbol chains the operations together, and is read left to right. + +The result, `output`, is itself a type of range called a view, which is discussed next. + +> [!NOTE] +> The ranges examples require the [`/std:c++latest`](../build/reference/std-specify-language-standard-version.md) compiler option. + +## Views + +A view is essentially a range that takes another range and transforms how its elements are accessed. How the elements appear depends on the algorithm or operation that you specify. The underlying range is unchanged. In the earlier example, one view took a range and returned a view of only the elements that were divisible by three. + +A view is lightweight. Like a range, it doesn't own the elements. The time it takes to copy, move, or assign a view is constant, no matter the number of elements it points to. + +Views are composable. In the example above, the view of vector elements that are divisible by three is combined with the view that squares those elements. + +The elements of a view are evaluated lazily. That is, the transformations you apply to yield the elements in a view aren't evaluated until you ask for an element. For example, if you run the following code in a debugger, and put a breakpoint on the lines `auto divisible_by_three = ...` and `auto square = ...`, you'll see that you hit the `divisible_by_three` lambda breakpoint as each element in `input` is tested for divisibility by three. The `square` lambda breakpoint will be hit as the elements that are divisible by three are squared. + +```cpp +// requires /std:c++latest +#include +#include +#include + +int main() +{ + std::vector input = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + auto divisible_by_three = [](const int n) {return n % 3 == 0; }; + auto square = [](const int n) {return n * n; }; + + auto x = input | std::views::filter(divisible_by_three) + | std::views::transform(square); + + for (int i : x) + { + std::cout << i << '\n'; + } + return 0; +} +``` + +## View adaptors + +A view adaptor produces a view over a range. The range being viewed remains unchanged. A view doesn't own any elements. It allows you to iterate over the underlying range using customized behavior that you specify. + +In the example above, the first view acts like an iterator that only provides the elements of `input` that are divisible by three. The other view acts like an iterator that takes the elements divisible by three, and provides the element's square. + +The `` library provides many kinds of view adaptors. Besides the filter and transform views, there are views that take or skip the first N elements of a range, reverse the order of a range, join ranges, skip elements of a range until a condition is met, transform the elements of a range, and more. + +## Range adaptors + +A range adaptor produces a new range from an existing range. The new range uses customized behavior specified by the range adaptor to provide the elements. For example, a range adaptor might take a range and produce a new one that presents the elements from the original range in reverse order. Views, discussed earlier, are a common kind of range adaptor. + +Range adaptors produce lazily evaluated ranges. That is, you don't incur the cost of transforming every element in the range--only the ones that you access, and at the time that you access them. + +Range adaptors come in many forms. For example, there are range adaptors that allow you to filter another range based on a predicate (`view::filter`), transform the elements in a range (`view::transform`), split a range (`view::split()`), and more. + +Range adaptors can be chained or composed--which is where the power and flexibility of ranges is most apparent. + +## Range algorithms + +Range algorithms have been created that take a range argument. For example, `std::ranges::sort(myVector);` + +The range algorithms are lazy, meaning that they operate on the range only when an element is accessed. They can work directly on a container, and can be easily chained together. + +## Types of ranges + +What you can do with a range depends on the underlying iterator type of the range. There are different kinds of ranges, called refinements. The different kinds of ranges are codified as C++ 20 concepts. This table lists various range concepts, along with the type of container they can be applied to: + +| Range refinement | Description | Supported containers | +|--|--|--| +| `std::ranges::input_range` | Can iterate from beginning to end at least once | +| `std::forward_list`
`std::unordered_map`
`std::unordered_multimap`
`std::unordered_set`
`std::unordered_multiset`
`basic_istream_view` | +| `std::ranges::forward_range` | Can iterate from beginning to end more than once) | `std::forward_list`
`std::unordered_map`
`std::unordered_multimap`
`std::unordered_set`
`std::unordered_multiset` | +| `std::ranges::bidirectional_range` | Can iterate forward and backward more than once | `std::list`
`std::map`
`std::multimap`
`std::multiset`
`std::set`| +| `std::ranges::random_access_range` | Can access an arbitrary element (in constant time) using the `[]` operator) | `std::deque` | +| `std::ranges::contiguous_range` | The elements are stored in memory consecutively | `std::array`
`std::string`
`std::vector` | + +## See also + +[Header Files Reference](../standard-library/cpp-standard-library-header-files.md) \ No newline at end of file diff --git a/docs/standard-library/span.md b/docs/standard-library/span.md index 56cb3153625..b88fbc00dae 100644 --- a/docs/standard-library/span.md +++ b/docs/standard-library/span.md @@ -1,12 +1,12 @@ --- -title: "<span>" +title: "" description: "API reference for the Standard Template Library (STL) span namespace, which provides a lightweight view over a contiguous sequence of objects." ms.date: "05/28/2020" f1_keywords: [""] helpviewer_keywords: ["span header"] --- -# <span> +# `` A `span` is a view over a contiguous sequence of objects. It provides fast and bounds-safe access. Unlike `vector` or `array`, it doesn't "own" the elements it provides access to. diff --git a/docs/standard-library/toc.yml b/docs/standard-library/toc.yml index 84f61cc2cf8..8170b8f123d 100644 --- a/docs/standard-library/toc.yml +++ b/docs/standard-library/toc.yml @@ -844,6 +844,11 @@ href: ../standard-library/uniform-real-distribution-class.md - name: weibull_distribution class href: ../standard-library/weibull-distribution-class.md + - name: + expanded: false + items: + - name: + href: ../standard-library/ranges.md - name: href: ../standard-library/ratio.md - name: