首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Nuget/Dotnet包管理器-如何检索$(<SomeVariable>)

Nuget/Dotnet包管理器-如何检索$(<SomeVariable>)
EN

Stack Overflow用户
提问于 2020-06-29 22:45:34
回答 2查看 115关注 0票数 1

我也曾尝试阅读Nuget和Dotnet中的Microsoft文档,但无法理解相应的行为。

当我和.csproj一起处理C#项目时,我遇到了以下情况,下面是我想要实现的一个示例:

例如,我正在使用以下.csproj文件:

代码语言:javascript
复制
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <ProjectTypeGuids>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
    <Authors>Confluent Inc.;Andreas Heider</Authors>
    <Description>Confluent's .NET Client for Apache Kafka</Description>
    <Copyright>Copyright 2016-2020 Confluent Inc., Andreas Heider</Copyright>
    <PackageProjectUrl>https://github.com/confluentinc/confluent-kafka-dotnet/</PackageProjectUrl>
    <PackageLicenseUrl>https://github.com/confluentinc/confluent-kafka-dotnet/blob/master/LICENSE</PackageLicenseUrl>
    <PackageIconUrl>https://raw.githubusercontent.com/confluentinc/confluent-kafka-dotnet/master/confluent_logo.png</PackageIconUrl>
    <PackageReleaseNotes>https://github.com/confluentinc/confluent-kafka-dotnet/releases</PackageReleaseNotes>
    <PackageTags>Kafka;Confluent;librdkafka</PackageTags>
    <PackageId>Confluent.Kafka</PackageId>
    <Title>Confluent.Kafka</Title>
    <AssemblyName>Confluent.Kafka</AssemblyName>
    <VersionPrefix>1.4.3</VersionPrefix>
    <TargetFrameworks>net45;net46;netcoreapp2.1;netstandard1.3;netstandard2.0</TargetFrameworks>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
    <SignAssembly>true</SignAssembly>
    <AssemblyOriginatorKeyFile>Confluent.Kafka.snk</AssemblyOriginatorKeyFile>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="librdkafka.redist" Version="1.4.2">
        <PrivateAssets Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">None</PrivateAssets>
    </PackageReference>
    <PackageReference Include="System.Memory" Version="4.5.0" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="PeterO.Cbor" Version="3.5.0" />
  </ItemGroup>

  <ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
    <PackageReference Include="System.Console" Version="4.3.0" />
    <PackageReference Include="System.Linq" Version="4.3.0" />
    <PackageReference Include="System.Runtime.InteropServices" Version="4.3.0" />
    <PackageReference Include="System.Runtime.Extensions" Version="4.3.0" />
    <PackageReference Include="System.Threading" Version="4.3.0" />
  </ItemGroup>

</Project>

正如你在最后一个ItemGroup中看到的,这是一个Condition=" '$(TargetFramework)' == 'netstandard1.3',我试图弄清楚的是dotnet从哪里获取这个参数$(TargetFramework)的。

顺便说一句,它似乎是变量符号$(SomeVariable) (不仅仅是TargetFramework),如果我能理解这些变量是从哪里以及如何被提取出来的,那就太好了。

有什么线索吗?

谢谢!

EN

回答 2

Stack Overflow用户

发布于 2020-07-17 17:27:29

由于在一些机制上已经有了非常详细的答案,这里有一些有用的信息可以帮助您详细了解行为:

  1. the "SDK=...“部件在项目的顶部和底部导入内容。

它实际上是项目内容顶部和底部的<Import>语句的语法糖。这意味着SDK的逻辑(及其更深层次的导入)既可以设置您可以在项目中使用的默认值(顶部的自动Sdk.props导入),也可以设置您在项目中设置的值(最底部的自动Sdk.targets导入)。

在处理<ItemGroup>元素之前处理

  1. <PropertyGroup>元素。

MSBuild以非常特定的顺序评估静态内容(即不在<Target>中):属性组和导入,然后是项定义组,最后是项组。

这意味着您可以在最上面的<ItemGroup>中使用$(FooBar),即使<PropertyGroup>在最下面定义<FooBar> i。

软件开发工具包本身使用此行为-您的$(TargetFramework) (单数!,如果设置的话。在导入的SDK目标中的一些属性组中使用)来设置TargetFrameworkIdentifierTargetFrameworkVersionTargetFrameworkMoniker -这里是the code

<PropertyGroup>的处理完成时,这意味着在<ItemGroup>元素的过程中,您可以使用$(TargetFrameworkIdentifier)

对于sdk在项目内容之前的一些项组,可以使用类似的机制,这些项组可以通过项目中设置的属性(DefaultItemExcludesEnableDefaultCompileItems等)进行控制。

  1. TargetFrameworks (多个)项目实际构建多次。

如果项目只有TargetFrameworks (复数)属性而没有TargetFramework,则会导致多个子生成,将为这些子生成设置TargetFramework属性。这意味着,对于“外部”构建,所有内容都会被评估一次,然后对于“内部构建”,每个目标框架都会评估一次。这是the code

票数 2
EN

Stack Overflow用户

发布于 2020-06-29 23:34:34

$(SomeVariable)是用于解析MSBuild property的语法。这些是键值对,可以由environment variables定义,也可以在arguments to MSBuild中定义,可以在MSBuild文件中由a elements定义,也可以由MSBuild目标使用the CreateProperty task定义。

TargetFramework在某种程度上是一个特殊属性。如果项目仅为一个target framework生成,则在项目文件中显式设置该属性,例如:

代码语言:javascript
复制
<PropertyGroup>
  <TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>

在您的示例中,您的项目可以为多个框架构建,如TargetFrameworks属性中指定的(请注意复数),例如:

代码语言:javascript
复制
<PropertyGroup>
  <TargetFrameworks>netcoreapp2.1;net462</TargetFrameworks>
</PropertyGroup>

例如,当你使用dotnet构建这个项目时,它实际上会多次构建项目,每个目标框架一次,本质上是通过调用MSBuild时的参数设置TargetFramework属性。

如果您想了解一下背后的神奇之处,这里有两种方法可以获得关于MSBuild正在做什么的详细信息:

  1. 使用the -pp argument让MSBuild将所有神奇的.NET核心内容,以及所有导入的项目文件解析为单个项目文件,供您检查。这实际上不会运行构建。

  1. 使用the -bl argument运行构建,但以二进制格式记录MSBuild所做的一切。然后,您可以使用this GUI.

查看.binlog文件

MSBuild的其他资源:

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62640651

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档