Build flags in Visual Studio

March 11th 2022 Visual Studio .NET

The project properties window has been redesigned in Visual Studio 2022. But not only the appearance has changed. For at least some options, the effect of the changes in the project properties window has also changed. Let us take a look at how the behavior of the Allow unsafe code build option has changed.

In Visual Studio 2019, the flag was available on the Build tab of the project properties window:

Build flags for active configuration in Visual Studio 2019

Notice the Configuration drop-down menu at the top left. By default, it is set to active configuration. This means that any changes you make will only apply to this configuration. You can check this yourself by enabling the _Allow unsafe code _flag and then looking at the project file. You will find the following:

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
  <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

The Condition attribute indicates that the AllowUnsafeBlocks property applies only to the Debug configuration that was active when I enabled the flag in the properties window.

If you want to enable the flag for all configurations (which makes sense for Allow unsafe code), you need to change the value in the Configuration drop-down menu. You can choose between all defined configurations or select All Configurations to apply the change to all configurations:

Build flags for all configurations in Visual Studio 2019

But even if you do that, Visual Studio 2019 sets the flag for each existing configuration individually:

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
  <Optimize>true</Optimize>
  <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
  <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

The property is now also set for the Release configuration (the Optimize property is set only for the Release configuration by default).

This may be fine, but there are scenarios where this can cause problems. For example, let us say we have the following solution and project configurations:

Test solution configuration in Visual Studio 2019

I have created a new solution configuration named Test and a project configuration with the same name for the BuildFlags project. For the BuildFlagsLib project (which is referenced by BuildFlags and has the Allow unsafe code flag set as described above), I did not create a new configuration and continued to use the Release configuration.

Building this solution with the Test configuration from Visual Studio 2019 works fine. This is also true when building it from the command line. However, if you try to build the project with the Test configuration from the command line, it fails:

error CS0227: Unsafe code may only appear if compiling with /unsafe

This is because the Allow unsafe code flag is not set for the Test configuration of the BuildFlagsLib. When you build a project with a particular configuration, that configuration is implicitly used for all dependent projects as well, regardless of what the solution configuration says.

This issue could be fixed if Visual Studio 2019 had set the AllowUnsafeBlocks property at the project level instead of for each configuration individually when I enabled the flag for all configurations:

<PropertyGroup>
  <TargetFramework>netcoreapp3.1</TargetFramework>
  <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>

This could be one of the reasons for the changed behavior in Visual Studio 2022. There, the project properties window has been redesigned. In the course of this, the Configuration drop-down menu was completely removed:

Build flags in Visual Studio 2022

So if you enable the Unsafe code flag in Visual Studio 2022, the value in the project file will be set at the project level, as seen in the XML block above. For this flag, such behavior makes perfect sense. It should be enabled or disabled regardless of the configuration, because the project will fail to build if it is set incorrectly. For flags where it makes sense to configure them differently depending on the configuration (e.g. Optimize code), there is still a corresponding option, as you can see in the screenshot above

However, caution is still advised when migrating existing projects from Visual Studio 2019 to Visual Studio 2022. If the Allow unsafe code flag is already set at the configuration level in the project file, Visual Studio 2022 will not correctly display this status in the project properties window, and toggling the flag will also only affect one of the configurations. To be sure what happens, it is best to open the project file and change it by hand.

However, caution is still required when migrating existing projects from Visual Studio 2019 to Visual Studio 2022. If the Allow unsafe code flag is already set at the configuration level in the project file, Visual Studio will fail to present that state correctly in the project properties window and toggling the flag will also only affect one of the configurations. To know for sure what's happening, it's best to open the project file and modify it by hand as required.

You can check the code in my GitHub repository. The solution and the project configuration match the screenshot above. In the last commit, the flag is set at the project level, as Visual Studio 2022 does. In the previous one, the flag was set for each project configuration individually, as it is in Visual Studio 2019. Try building the project with the Test configuration in both cases and compare the results.

Visual Studio has always provided a friendly UI to hide the complexity of the project file. However, this abstraction does not allow you to configure everything to the same extent as the project file. If the behavior does not meet your expectations, it is a good idea to check how Visual Studio has stored the properties in the project file.

Get notified when a new blog post is published (usually every Friday):

If you're looking for online one-on-one mentorship on a related topic, you can find me on Codementor.
If you need a team of experienced software engineers to help you with a project, contact us at Razum.
Copyright
Creative Commons License