admin管理员组

文章数量:1025286

In my builds, I need to ensure a specific intermediate directory. Now, I have noticed that building a .vcxproj file uses a different intermediate directory than building the same project as part of an .sln file: in fact, the former has the project file name prepended as an additional level while the latter does not.

In debugging this, I found that the intermediate directories differs between .vcxproj files in the .sln's folder (which do have the project name prepended) and .vcxproj files elsewhere (which do not).

Why is that, where is this documented, and how can I configure this to stay constant?

The documentation I found says that

$(IntDir): Path to the directory specified for intermediate files. If it's a relative path, intermediate files go to this path appended to the project directory.

I assume that "the project directory" is $(ProjectDir) which does not differ between builds, so I have no explanation why the $(IntDir)s do.

Here's an MWE to reproduce the problem:

Project.vcxproj

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns=";>
  <PropertyGroup Label="Globals">
    <ProjectGuid>{00000000-0000-0000-0000-000000000001}</ProjectGuid>
  </PropertyGroup>
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Configuration">
    <PlatformToolset>v143</PlatformToolset>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>

Sub\Project.vcxproj

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns=";>
  <PropertyGroup Label="Globals">
    <ProjectGuid>{00000000-0000-0000-0000-000000000002}</ProjectGuid>
  </PropertyGroup>
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Configuration">
    <PlatformToolset>v143</PlatformToolset>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>

Solution.sln

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RootProject", "Project.vcxproj", "{00000000-0000-0000-0000-000000000001}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SubProject", "Sub\Project.vcxproj", "{00000000-0000-0000-0000-000000000002}"
EndProject
Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|x64 = Debug|x64
    EndGlobalSection
    GlobalSection(ProjectConfigurationPlatforms) = postSolution
        {00000000-0000-0000-0000-000000000001}.Debug|x64.ActiveCfg = Debug|x64
        {00000000-0000-0000-0000-000000000001}.Debug|x64.Build.0 = Debug|x64
        {00000000-0000-0000-0000-000000000002}.Debug|x64.ActiveCfg = Debug|x64
        {00000000-0000-0000-0000-000000000002}.Debug|x64.Build.0 = Debug|x64
    EndGlobalSection
EndGlobal

Build.bat

@echo off

pushd "%~dp0"
if "%VSCMD_VER%" == "" (
    call "%VS2022INSTALLDIR%\Common7\Tools\VsDevCmd.bat" -arch=amd64
)

set CMD=MSBuild.exe -v:diag -property:Configuration=Debug -property:Platform=x64
set GREP=findstr /b /c:"IntDir ="

%CMD% Solution.sln -target:RootProject | %GREP%
%CMD% Solution.sln -target:SubProject  | %GREP%
%CMD% Project.vcxproj                  | %GREP%
%CMD% Sub\Project.vcxproj              | %GREP%

Output

IntDir = Project\x64\Debug\
IntDir = x64\Debug\
IntDir = Project\x64\Debug\
IntDir = Project\x64\Debug\

dir *.lastbuildstate /s/b (expecting two files, finding three)

.\Project\x64\Debug\Project.tlog\Project.lastbuildstate
.\Sub\Project\x64\Debug\Project.tlog\Project.lastbuildstate
.\Sub\x64\Debug\Project.tlog\Project.lastbuildstate

In my builds, I need to ensure a specific intermediate directory. Now, I have noticed that building a .vcxproj file uses a different intermediate directory than building the same project as part of an .sln file: in fact, the former has the project file name prepended as an additional level while the latter does not.

In debugging this, I found that the intermediate directories differs between .vcxproj files in the .sln's folder (which do have the project name prepended) and .vcxproj files elsewhere (which do not).

Why is that, where is this documented, and how can I configure this to stay constant?

The documentation I found says that

$(IntDir): Path to the directory specified for intermediate files. If it's a relative path, intermediate files go to this path appended to the project directory.

I assume that "the project directory" is $(ProjectDir) which does not differ between builds, so I have no explanation why the $(IntDir)s do.

Here's an MWE to reproduce the problem:

Project.vcxproj

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft/developer/msbuild/2003">
  <PropertyGroup Label="Globals">
    <ProjectGuid>{00000000-0000-0000-0000-000000000001}</ProjectGuid>
  </PropertyGroup>
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Configuration">
    <PlatformToolset>v143</PlatformToolset>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>

Sub\Project.vcxproj

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft/developer/msbuild/2003">
  <PropertyGroup Label="Globals">
    <ProjectGuid>{00000000-0000-0000-0000-000000000002}</ProjectGuid>
  </PropertyGroup>
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Configuration">
    <PlatformToolset>v143</PlatformToolset>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>

Solution.sln

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RootProject", "Project.vcxproj", "{00000000-0000-0000-0000-000000000001}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SubProject", "Sub\Project.vcxproj", "{00000000-0000-0000-0000-000000000002}"
EndProject
Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|x64 = Debug|x64
    EndGlobalSection
    GlobalSection(ProjectConfigurationPlatforms) = postSolution
        {00000000-0000-0000-0000-000000000001}.Debug|x64.ActiveCfg = Debug|x64
        {00000000-0000-0000-0000-000000000001}.Debug|x64.Build.0 = Debug|x64
        {00000000-0000-0000-0000-000000000002}.Debug|x64.ActiveCfg = Debug|x64
        {00000000-0000-0000-0000-000000000002}.Debug|x64.Build.0 = Debug|x64
    EndGlobalSection
EndGlobal

Build.bat

@echo off

pushd "%~dp0"
if "%VSCMD_VER%" == "" (
    call "%VS2022INSTALLDIR%\Common7\Tools\VsDevCmd.bat" -arch=amd64
)

set CMD=MSBuild.exe -v:diag -property:Configuration=Debug -property:Platform=x64
set GREP=findstr /b /c:"IntDir ="

%CMD% Solution.sln -target:RootProject | %GREP%
%CMD% Solution.sln -target:SubProject  | %GREP%
%CMD% Project.vcxproj                  | %GREP%
%CMD% Sub\Project.vcxproj              | %GREP%

Output

IntDir = Project\x64\Debug\
IntDir = x64\Debug\
IntDir = Project\x64\Debug\
IntDir = Project\x64\Debug\

dir *.lastbuildstate /s/b (expecting two files, finding three)

.\Project\x64\Debug\Project.tlog\Project.lastbuildstate
.\Sub\Project\x64\Debug\Project.tlog\Project.lastbuildstate
.\Sub\x64\Debug\Project.tlog\Project.lastbuildstate
Share Improve this question edited Nov 18, 2024 at 19:53 bers asked Nov 18, 2024 at 12:03 bersbers 6,0132 gold badges46 silver badges87 bronze badges 5
  • You haven't provided a MWE - emphasis on working. The projects you have provided as examples, fail to build because they do not contain a Configuration/Platform. The targets RootProject and SubProject don't exist -- which would be an error if Debug/x64 existed. You are relying on the diagnostic output (which outputs "initial properties", not property values as used) instead of what a working project actually produces as an intermediate directory. When built via the solution the properties reported by -v:diag include the property values as the solurtion sees them. – Jonathan Dodds Commented Nov 18, 2024 at 17:05
  • @JonathanDodds it shouldn't really matter: the IntDir values that are output are consistent with what I observe when compiling an actual project. Also, if you are right, I can easily change my question to "why are 'initial properties' different ...?" Either way, I will update the answer with a completely MWE. – bers Commented Nov 18, 2024 at 19:43
  • The 'initial properties' can be different because the properties are changed during evaluation. If you have a variable set to 0 and then change the value to 1 before using the variable, do you complain that the initial value was 0? – Jonathan Dodds Commented Nov 19, 2024 at 2:19
  • @JonathanDodds I am not complaining about the initial property values (assuming you are right that these are different from the final ones). I am complaining about the final location where intermediate files are being stored to, and that location is inconsistent: see the dir output in the updated question. Now, it so happens that the initial location equals the final location, so my hypothesis is that the initial location needs to be fixed. If you know another way to fix the final location, by all means, please go ahead. – bers Commented Nov 19, 2024 at 6:04
  • 1 I tested with your revised MWE (except that I didn't bother with the Build.bat file) and I can see that the directories are created as you say. I think your own answer is on-point -- This is a somewhat recent change in behavior that is a somewhat poorly executed fix for an issue. – Jonathan Dodds Commented Nov 19, 2024 at 17:26
Add a comment  | 

1 Answer 1

Reset to default 1

Somewhat hypothetical/heuristical answer:

Why is that?

I think this is primarily to avoid warning MSB8028 ("The intermediate directory (shared-intermediate-path) contains files shared from another project (intermediate-path).")

If so, this somewhat poorly executed, since putting projects in subdirectories does not guarantee they do not share intermediate directories. But I understand the assumption may be that projects are put into individual subdirectories, and in that case the changed behavior does make sense to avoid one level of intermediate directories.

Where is this documented?

I am still looking for anything written. However, I noticed that the Visual Studio IDE correctly shows the default value of "Intermediate Directory" to be different for the two projects in the solution file:

Note the addition of $(ShortProjectName). So at least this is consistent.

So one should probably note that MSBuild uses $(ShortProjectName)\$(Platform)\$(Configuration)\ as a default Intermediate Directory for *.sln root projects as well as when compiling individual *.vcxproj files.

Google-searching for ShortProjectName reveals that this additional level of Intermediate Directory is intended and was introduced in VS 2022 17.9, see Issue with Intermediate Directory (new folder when building) since update to VS 2022 CE 17.9.0.

How can I configure this to stay constant?

Given the previous answer, the solution is straightforward: by overwriting the default value of Intermediate Directory, e.g., in each vcxproj file or, somewhat more elegantly, using a shared property or even a Directory.build.props file:

<?xml version = "1.0" encoding="utf-8"?>
<Project ToolsVersion = "4.0" xmlns="http://schemas.microsoft/developer/msbuild/2003">
  <PropertyGroup>
    <!-- https://stackoverflow/q/79199847/ -->
    <IntDir>$(Platform)\$(Configuration)\</IntDir>
  </PropertyGroup>
</Project>

In my builds, I need to ensure a specific intermediate directory. Now, I have noticed that building a .vcxproj file uses a different intermediate directory than building the same project as part of an .sln file: in fact, the former has the project file name prepended as an additional level while the latter does not.

In debugging this, I found that the intermediate directories differs between .vcxproj files in the .sln's folder (which do have the project name prepended) and .vcxproj files elsewhere (which do not).

Why is that, where is this documented, and how can I configure this to stay constant?

The documentation I found says that

$(IntDir): Path to the directory specified for intermediate files. If it's a relative path, intermediate files go to this path appended to the project directory.

I assume that "the project directory" is $(ProjectDir) which does not differ between builds, so I have no explanation why the $(IntDir)s do.

Here's an MWE to reproduce the problem:

Project.vcxproj

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns=";>
  <PropertyGroup Label="Globals">
    <ProjectGuid>{00000000-0000-0000-0000-000000000001}</ProjectGuid>
  </PropertyGroup>
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Configuration">
    <PlatformToolset>v143</PlatformToolset>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>

Sub\Project.vcxproj

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns=";>
  <PropertyGroup Label="Globals">
    <ProjectGuid>{00000000-0000-0000-0000-000000000002}</ProjectGuid>
  </PropertyGroup>
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Configuration">
    <PlatformToolset>v143</PlatformToolset>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>

Solution.sln

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RootProject", "Project.vcxproj", "{00000000-0000-0000-0000-000000000001}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SubProject", "Sub\Project.vcxproj", "{00000000-0000-0000-0000-000000000002}"
EndProject
Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|x64 = Debug|x64
    EndGlobalSection
    GlobalSection(ProjectConfigurationPlatforms) = postSolution
        {00000000-0000-0000-0000-000000000001}.Debug|x64.ActiveCfg = Debug|x64
        {00000000-0000-0000-0000-000000000001}.Debug|x64.Build.0 = Debug|x64
        {00000000-0000-0000-0000-000000000002}.Debug|x64.ActiveCfg = Debug|x64
        {00000000-0000-0000-0000-000000000002}.Debug|x64.Build.0 = Debug|x64
    EndGlobalSection
EndGlobal

Build.bat

@echo off

pushd "%~dp0"
if "%VSCMD_VER%" == "" (
    call "%VS2022INSTALLDIR%\Common7\Tools\VsDevCmd.bat" -arch=amd64
)

set CMD=MSBuild.exe -v:diag -property:Configuration=Debug -property:Platform=x64
set GREP=findstr /b /c:"IntDir ="

%CMD% Solution.sln -target:RootProject | %GREP%
%CMD% Solution.sln -target:SubProject  | %GREP%
%CMD% Project.vcxproj                  | %GREP%
%CMD% Sub\Project.vcxproj              | %GREP%

Output

IntDir = Project\x64\Debug\
IntDir = x64\Debug\
IntDir = Project\x64\Debug\
IntDir = Project\x64\Debug\

dir *.lastbuildstate /s/b (expecting two files, finding three)

.\Project\x64\Debug\Project.tlog\Project.lastbuildstate
.\Sub\Project\x64\Debug\Project.tlog\Project.lastbuildstate
.\Sub\x64\Debug\Project.tlog\Project.lastbuildstate

In my builds, I need to ensure a specific intermediate directory. Now, I have noticed that building a .vcxproj file uses a different intermediate directory than building the same project as part of an .sln file: in fact, the former has the project file name prepended as an additional level while the latter does not.

In debugging this, I found that the intermediate directories differs between .vcxproj files in the .sln's folder (which do have the project name prepended) and .vcxproj files elsewhere (which do not).

Why is that, where is this documented, and how can I configure this to stay constant?

The documentation I found says that

$(IntDir): Path to the directory specified for intermediate files. If it's a relative path, intermediate files go to this path appended to the project directory.

I assume that "the project directory" is $(ProjectDir) which does not differ between builds, so I have no explanation why the $(IntDir)s do.

Here's an MWE to reproduce the problem:

Project.vcxproj

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft/developer/msbuild/2003">
  <PropertyGroup Label="Globals">
    <ProjectGuid>{00000000-0000-0000-0000-000000000001}</ProjectGuid>
  </PropertyGroup>
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Configuration">
    <PlatformToolset>v143</PlatformToolset>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>

Sub\Project.vcxproj

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft/developer/msbuild/2003">
  <PropertyGroup Label="Globals">
    <ProjectGuid>{00000000-0000-0000-0000-000000000002}</ProjectGuid>
  </PropertyGroup>
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Configuration">
    <PlatformToolset>v143</PlatformToolset>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>

Solution.sln

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RootProject", "Project.vcxproj", "{00000000-0000-0000-0000-000000000001}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SubProject", "Sub\Project.vcxproj", "{00000000-0000-0000-0000-000000000002}"
EndProject
Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|x64 = Debug|x64
    EndGlobalSection
    GlobalSection(ProjectConfigurationPlatforms) = postSolution
        {00000000-0000-0000-0000-000000000001}.Debug|x64.ActiveCfg = Debug|x64
        {00000000-0000-0000-0000-000000000001}.Debug|x64.Build.0 = Debug|x64
        {00000000-0000-0000-0000-000000000002}.Debug|x64.ActiveCfg = Debug|x64
        {00000000-0000-0000-0000-000000000002}.Debug|x64.Build.0 = Debug|x64
    EndGlobalSection
EndGlobal

Build.bat

@echo off

pushd "%~dp0"
if "%VSCMD_VER%" == "" (
    call "%VS2022INSTALLDIR%\Common7\Tools\VsDevCmd.bat" -arch=amd64
)

set CMD=MSBuild.exe -v:diag -property:Configuration=Debug -property:Platform=x64
set GREP=findstr /b /c:"IntDir ="

%CMD% Solution.sln -target:RootProject | %GREP%
%CMD% Solution.sln -target:SubProject  | %GREP%
%CMD% Project.vcxproj                  | %GREP%
%CMD% Sub\Project.vcxproj              | %GREP%

Output

IntDir = Project\x64\Debug\
IntDir = x64\Debug\
IntDir = Project\x64\Debug\
IntDir = Project\x64\Debug\

dir *.lastbuildstate /s/b (expecting two files, finding three)

.\Project\x64\Debug\Project.tlog\Project.lastbuildstate
.\Sub\Project\x64\Debug\Project.tlog\Project.lastbuildstate
.\Sub\x64\Debug\Project.tlog\Project.lastbuildstate
Share Improve this question edited Nov 18, 2024 at 19:53 bers asked Nov 18, 2024 at 12:03 bersbers 6,0132 gold badges46 silver badges87 bronze badges 5
  • You haven't provided a MWE - emphasis on working. The projects you have provided as examples, fail to build because they do not contain a Configuration/Platform. The targets RootProject and SubProject don't exist -- which would be an error if Debug/x64 existed. You are relying on the diagnostic output (which outputs "initial properties", not property values as used) instead of what a working project actually produces as an intermediate directory. When built via the solution the properties reported by -v:diag include the property values as the solurtion sees them. – Jonathan Dodds Commented Nov 18, 2024 at 17:05
  • @JonathanDodds it shouldn't really matter: the IntDir values that are output are consistent with what I observe when compiling an actual project. Also, if you are right, I can easily change my question to "why are 'initial properties' different ...?" Either way, I will update the answer with a completely MWE. – bers Commented Nov 18, 2024 at 19:43
  • The 'initial properties' can be different because the properties are changed during evaluation. If you have a variable set to 0 and then change the value to 1 before using the variable, do you complain that the initial value was 0? – Jonathan Dodds Commented Nov 19, 2024 at 2:19
  • @JonathanDodds I am not complaining about the initial property values (assuming you are right that these are different from the final ones). I am complaining about the final location where intermediate files are being stored to, and that location is inconsistent: see the dir output in the updated question. Now, it so happens that the initial location equals the final location, so my hypothesis is that the initial location needs to be fixed. If you know another way to fix the final location, by all means, please go ahead. – bers Commented Nov 19, 2024 at 6:04
  • 1 I tested with your revised MWE (except that I didn't bother with the Build.bat file) and I can see that the directories are created as you say. I think your own answer is on-point -- This is a somewhat recent change in behavior that is a somewhat poorly executed fix for an issue. – Jonathan Dodds Commented Nov 19, 2024 at 17:26
Add a comment  | 

1 Answer 1

Reset to default 1

Somewhat hypothetical/heuristical answer:

Why is that?

I think this is primarily to avoid warning MSB8028 ("The intermediate directory (shared-intermediate-path) contains files shared from another project (intermediate-path).")

If so, this somewhat poorly executed, since putting projects in subdirectories does not guarantee they do not share intermediate directories. But I understand the assumption may be that projects are put into individual subdirectories, and in that case the changed behavior does make sense to avoid one level of intermediate directories.

Where is this documented?

I am still looking for anything written. However, I noticed that the Visual Studio IDE correctly shows the default value of "Intermediate Directory" to be different for the two projects in the solution file:

Note the addition of $(ShortProjectName). So at least this is consistent.

So one should probably note that MSBuild uses $(ShortProjectName)\$(Platform)\$(Configuration)\ as a default Intermediate Directory for *.sln root projects as well as when compiling individual *.vcxproj files.

Google-searching for ShortProjectName reveals that this additional level of Intermediate Directory is intended and was introduced in VS 2022 17.9, see Issue with Intermediate Directory (new folder when building) since update to VS 2022 CE 17.9.0.

How can I configure this to stay constant?

Given the previous answer, the solution is straightforward: by overwriting the default value of Intermediate Directory, e.g., in each vcxproj file or, somewhat more elegantly, using a shared property or even a Directory.build.props file:

<?xml version = "1.0" encoding="utf-8"?>
<Project ToolsVersion = "4.0" xmlns="http://schemas.microsoft/developer/msbuild/2003">
  <PropertyGroup>
    <!-- https://stackoverflow/q/79199847/ -->
    <IntDir>$(Platform)\$(Configuration)\</IntDir>
  </PropertyGroup>
</Project>

本文标签: