.NET CLI的分发版本不包含任何.NET Framework的参考程序集,因此它的MSBuild版本无法解析所需的编译时资源。虽然这种情况在迁移到MSBuild之前已经可以使用(CLI可以使用mono的参考程序集),但是这种情况在
GitHub上被跟踪。
但是还有几个替代方案可用于在非Windows机器上构建库:
1. 使用mono 5+来构建库。
这可能是最稳定的路径。
Mono 5及更高版本包含了构建.NET Standard和.NET Core应用程序所需的构建逻辑。在Linux上,可能需要安装mono的msbuild作为单独的软件包。因此,可以使用以下常用命令的替代方法:
dotnet restore
dotnet build
dotnet publish -c Release
你会使用Mono的MSBuild来执行以下操作:
msbuild /t:Restore
msbuild
msbuild /t:Publish /p:Configuration=Release
针对 mono < 5.2 的解决方法:
唯一的限制是 mono (< 5.2) 不能直接生成 NuGet 包,但是可以通过在项目中使用 NuGet.Build.Tasks.Pack
NuGet 包的方法 来实现 msbuild /t:Pack /p:Configuration=Release
,需要修改项目文件(特别注意在 <Project>
元素上移除了 Sdk="..."
属性):
<Project>
<PropertyGroup>
<NuGetBuildTasksPackTargets>junk-value-to-avoid-conflicts</NuGetBuildTasksPackTargets>
</PropertyGroup>
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
<!-- All your project's other content here -->
<ItemGroup>
<PackageReference Include="NuGet.Build.Tasks.Pack" Version="4.0.0" PrivateAssets="All" />
</ItemGroup>
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
</Project>
2. 使用.NET CLI 并告诉MSBuild使用mono的参考程序集。
当为net*
目标框架构建时,可以将FrameworkPathOverride
属性设置为环境变量或csproj文件中的属性。它需要指向一组参考程序集 - 可以在这里使用mono的参考程序集。但是有些包含特殊文件(redist list),其中包含对.NET CLI中的MSBuild版本无法跟踪的其他目录的引用。尽管如此,在许多场景中它仍能正常工作:
export FrameworkPathOverride=/usr/lib/mono/4.5/
dotnet build -f net45
这是由F#团队使用和记录的。
3. 使用包含引用程序集的NuGet包。
在一些MyGet feeds上,Microsoft发布了包含引用程序集的NuGet包。虽然它们没有被发布或"官方"认可,但这个过程在某些时候可能会失败。不过,他们计划调查使此路径官方化。
首先,在您的解决方案目录中创建一个NuGet.Config文件,并添加以下内容以添加该feed:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="dotnet-core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />
</packageSources>
</configuration>
然后,您可以添加一个项目组来将PackageReference
添加到目标包中,并添加一个PropertyGroup
以设置参考程序集的路径,如下所示:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp1.1;net461</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net461' ">
<RuntimeIdentifier>win7-x64</RuntimeIdentifier>
<FrameworkPathOverride>$(NuGetPackageFolders)microsoft.targetingpack.netframework.v4.6.1\1.0.1\lib\net461\</FrameworkPathOverride>
</PropertyGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net461' ">
<PackageReference Include="Microsoft.TargetingPack.NETFramework.v4.6.1" Version="1.0.1" ExcludeAssets="All" PrivateAssets="All" />
</ItemGroup>
</Project>
如果您使用本地资产(例如获取Linux的.so文件),则可以更改不同平台的
RuntimeIdentifier
,或者在构建库时完全删除它。