参考链接:
https://learn.microsoft.com/zh-cn/visualstudio/msbuild/when-element-msbuild?view=vs-2022
https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-conditions?view=vs-2022
一、需求
dotnet6.0版本中加入大华相机SDK,希望在编译后的可执行文件,在windows环境中引入dll,在linux中引入so,在linux64中调整个别参数。
二、实现方法
引入大华SDK的代码见下,可以看到定义了LINUX常量。如果存在LINUX则使用so。
namespace NetSDKCS
{
internal static class OriginalSDK
{
#if(LINUX)
const string LIBRARYNETSDK = "libdhnetsdk.so";
const string LIBRARYCONFIGSDK = "libdhconfigsdk.so";
const string LIBRARYPLAYSDK = "libdhplay.so";
#else
const string LIBRARYNETSDK = "dhnetsdk.dll";
const string LIBRARYCONFIGSDK = "dhconfigsdk.dll";
const string LIBRARYPLAYSDK = "dhplay.dll";
#endif
[DllImport(LIBRARYNETSDK)]
public static extern int CLIENT_GetLastError();
[DllImport(LIBRARYNETSDK)]
public static extern bool CLIENT_InitEx(fDisConnectCallBack cbDisConnect, IntPtr dwUser, IntPtr lpInitParam);
项目.csproj项目文件中配置见下,可以看到通过Condition中的变量值,动态添加常量。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup Condition="$(RuntimeIdentifier.Contains(`linux`))">
<DefineConstants>LINUX</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$(RuntimeIdentifier.Contains(`linux-x64`)) Or $(RuntimeIdentifier.Contains(`linux-arm64`))">
<DefineConstants>LINUX;LINUX_X64;</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Reference Include="NetSDKCS">
<HintPath>NetSDKCS\bin\x64\Debug\NetSDKCS.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
经过以上配置,实现了使用vs中的发布功能打包的linux-arm/linux-64/windows使用了不同的外部动态链接库。
三、还可以添加哪些变量呢
经过我的猜想+验证,dotnet的PropertyGroup的所有属性应该都可以放到Condition判断。
具体列表见下:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- 指定输出类型:Exe(可执行文件)或 Library(类库) -->
<OutputType>Exe</OutputType>
<!-- 指定目标框架,例如 net5.0、netcoreapp3.1 -->
<TargetFramework>net5.0</TargetFramework>
<!-- 指定生成的程序集的名称 -->
<AssemblyName>MyProject</AssemblyName>
<!-- 指定默认的命名空间 -->
<RootNamespace>MyProjectNamespace</RootNamespace>
<!-- 指定项目的版本号 -->
<Version>1.0.0</Version>
<!-- 指定文件版本号 -->
<FileVersion>1.0.0.0</FileVersion>
<!-- 指定产品的版本信息 -->
<InformationalVersion>1.0.0-beta</InformationalVersion>
<!-- 指定作者信息 -->
<Authors>John Doe</Authors>
<!-- 指定公司信息 -->
<Company>MyCompany</Company>
<!-- 指定产品信息 -->
<Product>MyProduct</Product>
<!-- 指定项目描述 -->
<Description>This is a sample project.</Description>
<!-- 指定版权信息 -->
<Copyright>Copyright © 2024 MyCompany</Copyright>
<!-- 指定 NuGet 包的 ID -->
<PackageId>MyProject.Package</PackageId>
<!-- 指定 NuGet 包的版本号 -->
<PackageVersion>1.0.0</PackageVersion>
<!-- 指定项目的源代码仓库 URL -->
<RepositoryUrl>https://github.com/mycompany/myproject</RepositoryUrl>
<!-- 是否生成程序集信息文件 -->
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<!-- 指定用于签名的密钥文件 -->
<AssemblyOriginatorKeyFile>mykey.snk</AssemblyOriginatorKeyFile>
<!-- 指定是否对程序集进行签名 -->
<SignAssembly>true</SignAssembly>
<!-- 指定是否延迟签名 -->
<DelaySign>false</DelaySign>
<!-- 指定是否启用优化 -->
<Optimize>true</Optimize>
<!-- 指定调试信息的类型,例如 Full、PdbOnly -->
<DebugType>Full</DebugType>
<!-- 定义编译常量 -->
<DefineConstants>DEBUG;TRACE</DefineConstants>
<!-- 指定目标平台,例如 x86、x64、AnyCPU -->
<PlatformTarget>AnyCPU</PlatformTarget>
<!-- 指定 C# 语言版本,例如 latest、9.0 -->
<LangVersion>latest</LangVersion>
<!-- 指定是否启用可空引用类型支持 -->
<Nullable>enable</Nullable>
<!-- 指定是否允许不安全代码块 -->
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
<!-- 指定警告级别 -->
<WarningLevel>4</WarningLevel>
<!-- 指定是否将警告视为错误 -->
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<!-- 指定应忽略的警告代码 -->
<NoWarn>0169;CS8600</NoWarn>
<!-- 指定项目是否可以作为 NuGet 包打包 -->
<IsPackable>true</IsPackable>
<!-- 指定是否在生成时自动生成 NuGet 包 -->
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<!-- 指定源代码仓库的类型 -->
<RepositoryType>git</RepositoryType>
<!-- 指定目标运行时标识符 -->
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<!-- 指定多个目标框架 -->
<TargetFrameworks>net5.0;netcoreapp3.1</TargetFrameworks>
<!-- 指定应用程序图标文件路径 -->
<ApplicationIcon>icon.ico</ApplicationIcon>
<!-- 指定中立语言 -->
<NeutralLanguage>en-US</NeutralLanguage>
<!-- 指定是否发布为单个文件 -->
<PublishSingleFile>true</PublishSingleFile>
<!-- 指定是否修剪已发布的文件 -->
<PublishTrimmed>true</PublishTrimmed>
<!-- 指定是否发布为自包含应用 -->
<SelfContained>true</SelfContained>
<!-- 指定是否生成运行时配置文件 -->
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<!-- 指定是否将文件复制到输出目录 -->
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<!-- 指定是否保留编译上下文 -->
<PreserveCompilationContext>true</PreserveCompilationContext>
</PropertyGroup>
</Project>