4

我有以下Directory.Build.props文件:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <LibraryPath>$(BOOST_ROOT)\lib32-msvc-14.2</LibraryPath>
    <IncludePath>$(BOOST_ROOT)\</IncludePath>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <LibraryPath>$(BOOST_ROOT)\lib64-msvc-14.2</LibraryPath>
    <IncludePath>$(BOOST_ROOT)\</IncludePath>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <LibraryPath>$(BOOST_ROOT)\lib32-msvc-14.2</LibraryPath>
    <IncludePath>$(BOOST_ROOT)\</IncludePath>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <LibraryPath>$(BOOST_ROOT)\lib64-msvc-14.2</LibraryPath>
    <IncludePath>$(BOOST_ROOT)\</IncludePath>
  </PropertyGroup>
</Project>

每当我在子文件夹(在 Visual Studio 2019 中)中加载(C++)项目时,该项目都会丢失所有继承的包含和库路径:

继承价值观: 继承的价值观

我在想这可能是因为我没有附加到IncludePathand LibraryPath,所以我这样做并更改了props文件如下:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <LibraryPath>$(LibraryPath);$(BOOST_ROOT)\lib32-msvc-14.2</LibraryPath>
    <IncludePath>$(IncludePath);$(BOOST_ROOT)\</IncludePath>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <LibraryPath>$(LibraryPath);$(BOOST_ROOT)\lib64-msvc-14.2</LibraryPath>
    <IncludePath>$(IncludePath);$(BOOST_ROOT)\</IncludePath>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <LibraryPath>$(LibraryPath);$(BOOST_ROOT)\lib32-msvc-14.2</LibraryPath>
    <IncludePath>$(IncludePath);$(BOOST_ROOT)\</IncludePath>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <LibraryPath>$(LibraryPath);$(BOOST_ROOT)\lib64-msvc-14.2</LibraryPath>
    <IncludePath>$(IncludePath);$(BOOST_ROOT)\</IncludePath>
  </PropertyGroup>
</Project>

然后重新加载项目,再次导致丢失继承的值。

我仔细检查了宏是否存在,它们是(VC_WindowsSDK_宏):

存在宏

我还尝试更改Directory.Build.propsDirectory.Build.targets在加载项目后加载它,但是文件根本没有加载。

如何确保我Directory.Build.props继承默认值并附加我的自定义选项?

我想这样做的原因是因为我正在从已弃用的Microsoft.Cpp.Win32.user.props文件中迁移出来。

将扩展名更改为.targets仅适用于构建过程,但智能感知/视觉工作室不会处理包含文件,并且会显示很多错误(在编译之前)。这不是优选的。

4

2 回答 2

2

如何确保我的 Directory.Build.props 继承默认值并附加我的自定义选项?

我认为您不能使用Directory.Build.props覆盖项目属性 UI 中的系统属性。

根据您的信息,LibraryPathandIncludePath已经失去了那里的价值。请注意有关以下导入顺序的信息Directory.Build.props

Directory.Build.props 很早就在 Microsoft.Common.props 中导入,后面定义的属性对其不可用。因此,请避免引用尚未定义的属性(并将评估为空)。

Directory.Build.targets 在从 NuGet 包导入 .targets 文件后从 Microsoft.Common.targets 导入。因此,它可以覆盖大多数构建逻辑中定义的属性和目标,但有时您可能需要在最终导入后自定义项目文件。

你可以参考这个链接

详细地说,Directory.Build.props例如初始化项目并始终运行的步骤,在此之前Microsoft.Common.props为大多数系统属性设置默认值,例如LibraryPathIncludePath。所以一开始,值为空是正常的。在此之后,当它执行时Microsoft.Common.props,它具有以下内容:

<Includepath Condidtion="'$(Includepath)'==''">$(VC_IncludePath)......</Includepath >

并且你在 中添加了$(BOOST_ROOT)\lib32-msvc-14.2,所以当你执行下一步时,有一个值,所以它会跳过分配系统值的操作,不会覆盖这一步中的值,导致这种奇怪的行为。IncludepathDirectory.Build.propsIncludepath

对于Directory.Build.targets,它在最后执行覆盖操作,当includepath和LibraryPath属性都得到系统值时,覆盖没有问题。但是您只能在运行项目时获取这些值,正如您稍后展示的那样。

简而言之,Directory.Build.props适用于定义一些稍后会使用或覆盖的属性,Directory.Build.targets适用于覆盖在构建过程中已经定义的值。

建议

1)要设置包含目录,您可以将它们添加到您的 INCLUDE 环境变量中。您可以设置 INCLUDE 和 LIB 变量,如下所示:

set INCLUDE=xxxx
set LIB=xxxx\lib32-msvc-14.2

然后添加 /p:"VCBuildAdditionalOptions= /useenv"到 MSBuild 参数,以便它采用 INCLUDE 和 LIB 变量。

你可以参考这个

2)或者你可以使用你的初始函数在路径C:\Users\UserName\AppData\Local\Microsoft\MSBuild\v4.0\Microsoft.Cpp.xxx.user.props中添加额外的includepath,librarypath,比如:</p>

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ImportGroup Label="PropertySheets">
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup>
    <IncludePath>C:\any-name\include;$(IncludePath)</IncludePath>
    <LibraryPath>C:\any-name\lib;$(LibraryPath)</LibraryPath>
  </PropertyGroup>
  <ItemDefinitionGroup />
  <ItemGroup />
</Project>

希望它可以帮助你。

于 2020-01-08T10:29:32.227 回答
2

佩里钱的答案需要改进。以下是我的担忧:

  1. INCLUDE/LIB 环境变量对于所有想要使用此方法的项目都是全局的。
    必须为每个项目设置 MSBuild 参数
  2. 不推荐使用 user.props,并且对于所有项目都是全局的

Directory.Build.props 的问题在于它包含在 $(IncludePath) 和 $(LibraryPath) 定义之前。您可以手动设置 VS 的默认路径,但这是不好的做法。

要使用 user.props 后继Directory.Build.props和 IntelliSense,我建议使用AdditionalIncludeDirectoriesand AdditionalLibraryDirectories
这是 Directory.Build.props 配置的示例:

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ImportGroup Label="PropertySheets" />
  <PropertyGroup Label="UserMacros">
    <BoostPath>$(BOOST_ROOT)</BoostPath>    
    <BoostPlatform Condition="'$(Platform)'=='Win32'">lib32</BoostPlatform>
    <BoostPlatform Condition="'$(Platform)'=='x64'">lib64</BoostPlatform>
    <BoostDebug Condition="'$(Configuration)'=='Debug'">\debug</BoostDebug>
  </PropertyGroup>
  <ItemDefinitionGroup>
    <ClCompile>
      <AdditionalIncludeDirectories>$(BoostPath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ClCompile>
    <Link>
      <AdditionalLibraryDirectories>$(BoostPath)\$(BoostPlatform)-msvc-$([System.Text.RegularExpressions.Regex]::replace($(PlatformToolset), "v(\d+)(\d)$", "$1.$2"))$BoostDebug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
    </Link>
  </ItemDefinitionGroup>
</Project>

如果要在项目中设置其他路径,请确保添加;%(AdditionalIncludeDirectories);%(AdditionalLibraryDirectories)分别包含来自 props 文件的路径。

将该属性设置为BoostDebug编译调试库的位置。在此示例中,它将是lib32-msvc-14.2/debug/

正则表达式术语$([System.Text.RegularExpressions.Regex]::replace($(PlatformToolset), "v(\d+)(\d)$", "$1.$2"))将平台工具集转换为例如v142lib 路径 appendix 14.2

为了可读性,最好在 PropertyGroup 中对其进行初始化,但$(PlatformToolset)不会在解析 props 文件时就进行初始化。幸运AdditionalLibraryDirectories的是,在链接时间期间评估何时$(PlatformToolset)将被设置。

如果您想要更好的可读性或需要更复杂的操作$(PlatformToolset),我建议另外使用Directory.Build.targets配置。当这个文件被解析时,$(PlatformToolset)将已经被初始化。
示例Directory.Build.targets

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ImportGroup Label="PropertySheets" />
  <PropertyGroup Label="UserMacros">
    <BoostToolset>$([System.Text.RegularExpressions.Regex]::replace($(PlatformToolset), "v(\d+)(\d)$", "$1.$2"))</BoostPlatform>
  </PropertyGroup>
  <ItemDefinitionGroup>
    <Link>
      <AdditionalLibraryDirectories>$(BoostPath)\$(BoostPlatform)-msvc-$(BoostToolset)$BoostDebug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
    </Link>
  </ItemDefinitionGroup>
</Project>
于 2020-02-24T17:06:41.017 回答