如何在Mac或Linux上的.NET Core上构建多目标解决方案?

时间:2017-04-22 04:40:41

标签: linux msbuild .net-core csproj

我有多目标csproj文件的解决方案:

<PropertyGroup>
  <TargetFrameworks>net45;netstandard1.6</TargetFrameworks>
</PropertyGroup>

<PropertyGroup>
  <TargetFrameworks>net45;netcoreapp1.1</TargetFrameworks>
</PropertyGroup>

我试图在Linux上构建此解决方案的.NET Core部分,但无法管理它。如果我跑

dotnet build

它构建所有目标:netcoreapp1.1netstandard1.6net45并在net45上失败,因为.NET Core不在Linux上提供.NET 4.5平台。我试图通过将mono指定为构建框架来解决此问题,但解决方案很复杂,而且并非所有.NET 4.5都支持单声道。但是,这可以帮助其他人避免can't find .NETFramework v4.5运行:

FrameworkPathOverride=/usr/lib/mono/4.5/ dotnet restore
FrameworkPathOverride=/usr/lib/mono/4.5/ dotnet build

当我运行dotnet build /p:TargetFramework=netcoreapp1.1时,我会收到很多错误,我认为因为没有构建netstandard1.6的项目。

如果我通过

  dotnet build /p:TargetFrameworks=netcoreapp1.1\;netstandard1.6

我得到了

MSBUILD : error MSB1006: Property is not valid.
Switch: netstandard1.6

如何从命令行同时将netcoreapp1.1netstandard1.6目标框架传递给msbuild?

我知道我可以添加其他属性并根据它进行条件编译,但我不想更改csproj以使其解决方法。

3 个答案:

答案 0 :(得分:3)

如果你真的不想尝试在linux上构建完整的框架或PCL版本,只想要一个.net核心应用程序或.net标准库,你可以修改项目文件(overlapImage.copyTo(sourceImage, x, y, width, height); )只在Windows上进行多目标,并且行为类似于针对非Windows的单个框架的项目,如下所示:

.csproj

这允许为所有项目单独指定非窗口<PropertyGroup> <TargetFrameworks>netcoreapp1.1;net45</TargetFrameworks> <TargetFrameworks Condition="'$(OS)' != 'Windows_NT'">netcoreapp1.1</TargetFrameworks> </PropertyGroup> netstandard*,并且仅使用普通netcoreapp* / {只能.net核心版本的应用程序构建{1}}命令。

答案 1 :(得分:2)

RefferenceAssembly软件包现已稳定,您所要做的就是在运行以下命令设置所有需要的目标之后对其进行引用:

dotnet add package Microsoft.NETFramework.ReferenceAssemblies --version 1.0.0

或在您的项目中手动进行:

<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0">
    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    <PrivateAssets>all</PrivateAssets>
</PackageReference>

答案 2 :(得分:0)

确保mono是最新的,然后将此样板粘贴到您的项目中。 我非常有信心这不会破坏智能或工具。

<PropertyGroup Condition="$(TargetFramework.StartsWith('net4')) and '$(OS)' == 'Unix'">
  <!-- When compiling .NET SDK 2.0 projects targeting .NET 4.x on Mono using 'dotnet build' you -->
  <!-- have to teach MSBuild where the Mono copy of the reference asssemblies is -->
  <!-- Look in the standard install locations -->
  <BaseFrameworkPathOverrideForMono Condition="'$(BaseFrameworkPathOverrideForMono)' == '' AND EXISTS('/Library/Frameworks/Mono.framework/Versions/Current/lib/mono')">/Library/Frameworks/Mono.framework/Versions/Current/lib/mono</BaseFrameworkPathOverrideForMono>
  <BaseFrameworkPathOverrideForMono Condition="'$(BaseFrameworkPathOverrideForMono)' == '' AND EXISTS('/usr/lib/mono')">/usr/lib/mono</BaseFrameworkPathOverrideForMono>
  <BaseFrameworkPathOverrideForMono Condition="'$(BaseFrameworkPathOverrideForMono)' == '' AND EXISTS('/usr/local/lib/mono')">/usr/local/lib/mono</BaseFrameworkPathOverrideForMono>
  <!-- If we found Mono reference assemblies, then use them -->
  <FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND '$(TargetFramework)' == 'net40'">$(BaseFrameworkPathOverrideForMono)/4.0-api</FrameworkPathOverride>
  <FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND '$(TargetFramework)' == 'net45'">$(BaseFrameworkPathOverrideForMono)/4.5-api</FrameworkPathOverride>
  <FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND '$(TargetFramework)' == 'net451'">$(BaseFrameworkPathOverrideForMono)/4.5.1-api</FrameworkPathOverride>
  <FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND '$(TargetFramework)' == 'net452'">$(BaseFrameworkPathOverrideForMono)/4.5.2-api</FrameworkPathOverride>
  <FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND '$(TargetFramework)' == 'net46'">$(BaseFrameworkPathOverrideForMono)/4.6-api</FrameworkPathOverride>
  <FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND '$(TargetFramework)' == 'net461'">$(BaseFrameworkPathOverrideForMono)/4.6.1-api</FrameworkPathOverride>
  <FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND '$(TargetFramework)' == 'net462'">$(BaseFrameworkPathOverrideForMono)/4.6.2-api</FrameworkPathOverride>
  <FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND '$(TargetFramework)' == 'net47'">$(BaseFrameworkPathOverrideForMono)/4.7-api</FrameworkPathOverride>
  <FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND '$(TargetFramework)' == 'net471'">$(BaseFrameworkPathOverrideForMono)/4.7.1-api</FrameworkPathOverride>
  <EnableFrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != ''">true</EnableFrameworkPathOverride>
  <!-- Add the Facades directory.  Not sure how else to do this. Necessary at least for .NET 4.5 -->
  <AssemblySearchPaths Condition="'$(BaseFrameworkPathOverrideForMono)' != ''">$(FrameworkPathOverride)/Facades;$(AssemblySearchPaths)</AssemblySearchPaths>
</PropertyGroup>

来自https://www.cafe-encounter.net/p2312/multi-targetting-net-framework-and-net-core-in-a-single-project / https://github.com/dotnet/sdk/issues/335#issuecomment-368669050