设置所有项目的OutDir和IntDir

3

我正在尝试为解决方案中的所有项目设置默认位置 OutDirIntDir,比如:<OutDir>$(SolutionDir)bld\$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>

当我在 Directory.Build.props 文件中进行设置后,在 Visual Studio 属性对话框中看起来一切正常;但是当我构建时,$(ProjectName) 部分为空。这告诉我,在读取 Directory.Build.props 中的 OutDir 时,该宏不可用。

我尝试将其添加到 Directory.Build.targets 文件中,但似乎完全被忽略了。

另一个目标是在此初始更改之后不修改任何 vcxproj 文件,并且新项目将自动继承这些设置。

这可能吗?也许我将设置放在文件的错误位置/顺序中...?

以下是 Directory.Build.props 的摘录:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ImportGroup Label="PropertySheets">
  </ImportGroup>

  <!-- Define macros for easy and consistent access to various parts of the tree -->
  <PropertyGroup Label="UserMacros">
    <GslInclude>$(SolutionDir)packages\Microsoft.Gsl.0.1.2.1\build\native\include</GslInclude>
    <mySrcDir>$(SolutionDir)src\</mySrcDir>
    <myBldDir>$(SolutionDir)bld\</myBldDir>
    <myBldIntDir>$(SolutionDir)bld_int\</myBldIntDir>
  </PropertyGroup>
  <ItemDefinitionGroup />
  <ItemGroup>
    <BuildMacro Include="GslInclude"> <Value>$(GslInclude)</Value> </BuildMacro>
    <BuildMacro Include="mySrcDir"> <Value>$(mySrcDir)</Value> </BuildMacro>
    <BuildMacro Include="myBldDir"> <Value>$(myBldDir)</Value> </BuildMacro>
    <BuildMacro Include="myBldIntDir"> <Value>$(myBldIntDir)</Value> </BuildMacro>
  </ItemGroup>

  <!-- Platform Toolset, Windows SDK -->
  <PropertyGroup Label="Globals">
    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
  </PropertyGroup>

  <!-- Default Compiler settings -->
  <ItemDefinitionGroup>
    <ClCompile>
      <!-- .... -->
    </ClCompile>
  </ItemDefinitionGroup>

  <!-- Default Folders for target output -->
  <PropertyGroup>
    <OutDir>$(myBldDir)$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
    <IntDir>$(myBldIntDir)$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
  </PropertyGroup>

</Project>

然后,我当然会简单地移除项目文件中的所有<OutDir><IntDir>设置。

我还希望能够根据Visual Studio的版本对设置进行条件限制。我们的一些开发人员使用带有旧ToolSet的VS2017;另一些则使用最新的VS2019....

2个回答

5

感谢那些帮助过我的人。我已经使它能够工作了——至少对于我主要目标来说,即建立一个预定义的“输出”位置。

参考这里的信息:https://learn.microsoft.com/zh-cn/visualstudio/msbuild/customize-your-build?view=vs-2019,并在VS属性文件中搜索,我发现一个早期设置的宏“MSBuildProjectName”。

我在我的构建树的根目录中创建了一个Directory.Build.props文件,其内容如下:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ImportGroup Label="PropertySheets">
  </ImportGroup>

  <!-- Define macros for easy and consistent access to various parts of the tree -->
  <PropertyGroup Label="UserMacros">
    <GslInclude>$(SolutionDir)packages\Microsoft.Gsl.0.1.2.1\build\native\include</GslInclude>
    <myBldDir>$(SolutionDir)bld\</myBldDir>
    <myBldIntDir>$(SolutionDir)bld_int\</myBldIntDir>
  </PropertyGroup>
  <ItemDefinitionGroup />
  <ItemGroup>
    <BuildMacro Include="GslInclude"> <Value>$(GslInclude)</Value> </BuildMacro>
    <BuildMacro Include="myBldDir"> <Value>$(myBldDir)</Value> </BuildMacro>
    <BuildMacro Include="myBldIntDir"> <Value>$(myBldIntDir)</Value> </BuildMacro>
</BuildMacro>
    <!-- etc .... -->
  </ItemGroup>

  <!-- Platform Toolset, Windows SDK -->
  <PropertyGroup Label="Globals">
    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
  </PropertyGroup>
  <PropertyGroup Label="Configuration">
    <PlatformToolset>v142</PlatformToolset>
  </PropertyGroup>

  <PropertyGroup>
    <IntDir>$(myBldIntDir)$(Platform)\$(MSBuildProjectName)\$(Configuration)\</IntDir>
    <OutDir>$(myBldDir)$(Platform)\$(MSBuildProjectName)\$(Configuration)\</OutDir>
  </PropertyGroup>

  <!-- lots more ....  -->
</Project>

该文件中的设置会影响在其下层目录结构中的所有项目。 如果子文件夹需要不同的值,请在该文件夹下添加一个 Directory.Build.props 文件,导入“父”props文件(可能会有多个层级以上):

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />

  <ImportGroup Label="PropertySheets">
  </ImportGroup>

  <PropertyGroup>
    <IntDir>$(myBldIntDir)$(Platform)\Tests\$(MSBuildProjectName)\$(Configuration)\</IntDir>
    <OutDir>$(myBldDir)$(Platform)\Tests\$(MSBuildProjectName)\$(Configuration)\</OutDir>
  </PropertyGroup>

</Project>

在“child” props文件中的设置将覆盖其父级中设置的任何内容。

一旦我从XML项目文件中移除了所有<OutDir><IntDir>元素,“输出目录”和“中间目录”设置就会以常规字体显示(而不是粗体,表示它没有继承),当我构建时,所有文件都会移动到合并的文件夹树中,远离源代码。而且很酷的是:新项目将自动填充这些新的默认设置。

注意:@dxiv指出,某些设置可能更为挑剔,需要更多的工作。


我很高兴你找到了解决方案,感谢你的分享。如果您能将它们标记为答案,这将有益于其他社区成员。 - Barrnet Chou
嗨@Barrnet-Chou 如何将其标记为答案? 它不允许我将自己的回答标记为答案,下面的回答也不完全符合我的要求。 - Thomas Oatman

1
可以这样做,实际上这是共享设置的推荐方式。唯一需要注意的是方案对于部分标签、包含顺序/位置非常敏感。以下内容适用于OutDirIntDir

Directory.Build.props

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <_PropertySheetDisplayName>Directory.Build</_PropertySheetDisplayName>
  </PropertyGroup>
  <ImportGroup Label="PropertySheets" />
  <PropertyGroup Label="UserMacros">
    <!-- other user macros -->
    <OutDir> ... </OutDir>
    <IntDir> ... </IntDir>
  </PropertyGroup>
  <!-- rest of .props file --->

Project.vcxproj

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- ... -->
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <!-- include custom .props here, can also use full or relative path -->
  <ImportGroup Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
    <Import Project="Directory.Build.props" />
  </ImportGroup>
  <!-- ... -->

嗨dxiv。谢谢你。 我考虑过这种方法,但这是否意味着仍然需要有人编辑新的项目文件? 我想避免未来开发人员犯错误;编辑vcxproj很可能会被忘记。 - Thomas Oatman
@ThomasOatman 要更改未来项目的默认设置,您需要使用项目模板(并确保可能添加项目到解决方案的所有其他人都这样做),或者修改Visual Studio中一个.props文件的安装默认值,默认情况下包含在新项目中。我不知道有没有(内置的,自动的)方法在解决方案级别强制所有子项目必须继承某些自定义设置。 - dxiv
1
Directory.Build.props和Directory.Build.targets似乎就是如此。它们在VS .prop文件中通过目录树进行搜索: [链接]https://learn.microsoft.com/en-us/visualstudio/msbuild/customize-your-build?view=vs-2019我相信真正的问题是,$(ProjectName)何时被定义,以便我可以将新的宏放在其后... - Thomas Oatman
@ThomasOatman 你的情况可能会有所不同,但是当依赖于自动包含时,你无法控制它被插入到.vcxproj中的位置,这就是为什么我更喜欢显式地添加引用。某些设置必须放在单独的.props文件中,并在.vcxproj的不同点处进行包含,以便正确应用设置(例如ProjectConfigurations与其他UserMacros)。 - dxiv

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接