.NET探索平台条件编译
2021-01-17 22:40
1026 查看
前言
今天偶然机会,翻了一下大学期间的书籍《C程序设计》,好吧,当我翻着翻着,翻到了符号常量(
#define指令)中,是啊,这是一个预处理器指令,记得在Magicodes.IE中针对平台选择不同的库,哈哈,这是一个典型的根据平台进行条件处理,好吧,根据这些内容,让我感觉在今天,我需要对
#define指令以及在.NET中的平台条件处理,以及平台的条件编译进行记录一下。
define
我们可通过
define来定义符号,然后将符号用在
#if指令表达式中,如下所示:
#define PI
通过上面这些内容可能很难去了解这该如何使用,其实
#define在我们的编码过程中也是很少去使用的,我们继续往下看。
其实对于预处理器,在我们调试以及运行时的作用是比较大的,比如说对某些代码限制编译,另一方变其实还可以对代码进行环境或者版本的控制,这些都是Ok的,最后我们结合着控制语句
#if来看一下:
#define PIusing System; namespace ConsoleApp2 { class Program { static void Main(string[] args) { #if (PI) Console.WriteLine("PI is defined"); #else Console.WriteLine("PI is not defined"); #endif Console.ReadKey(); } } }
当我们的头部声明
#define PI时,我们也可以看到编译的感知功能可以为我们将控制语句进行切换,是啊,我们可以在头部进行声明。
条件编译符号
对于上面我们可以直接通过
#define去进行条件编译,而对于在
.cs文件中我们去定义它达到的只是局部的使用,我们如果说想全局的控制,全局的应用该如何操作?其实我们是可以通过
DefineConstants属性进行操作。
我们可以打开项目文件进行查看,属性如下所示:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net5</TargetFramework> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <DefineConstants>TRACE;PI</DefineConstants> </PropertyGroup> </Project>
当然了,我们一方面是可通过VS对项目的属性进行编辑,而另一方面,我们是可通过直接对项目文件进行修改编辑操作.这样其实达到了一个可控制性.
RuntimeInformation
对于代码中也是可以进行平台的逻辑判断的,在
.NET Core 1.0的时候其实已经添加了
System.Runtime.InteropServices.RuntimeInformation对于这个类的添加,使我们可以动态的去判断当前的操作系统(OS),以及我们可通过这些动态判断为我们的业务逻辑进行不同的处理行为。
判断当前操作系统如下所示:
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) Console.WriteLine("Running on Linux!"); else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) Console.WriteLine("Running on macOS!"); else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) Console.WriteLine("Running on Windows!");
MSBuild & RuntimeInformation
对于条件编译,之前我们已经手动的操作过一次了,是我们可以根据不同的环境值进行对代码编译内容的控制,如果说我想根据当前的操作系统(OS)动态的进行条件编译,该如何进行操作。
其实我们在项目文件中进行调用
System.Runtime.InteropServices.RuntimeInformation进行我们的条件处理。下面我们看一下在MSBuild中如何调用
System.Runtime.InteropServices.RuntimeInformation如下所示:
<Project Sdk="Microsoft.NET.Sdk"> <Propert ad8 yGroup> <OutputType>Exe</OutputType> <TargetFramework>net5</TargetFramework> <IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows> <IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX> <IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux> </PropertyGroup> <Target Name="PrintRID" BeforeTargets="Build"> <Message Text="IsWindows $(IsWindows)" Importance="high" /> <Message Text="IsOSX $(IsOSX)" Importance="high" /> <Message Text="IsLinux $(IsLinux)" Importance="high" /> </Target> </Project>
我们是可以通过visual studio或者说通过CLI直接运行构建命令
dotnet build,我们在Windows操作系统中测试一下,输出结果如下所示:
C:\Users\hueif\source\repos\ConsoleApp2\ConsoleApp2>dotnet build 用于 .NET 的 Microsoft (R) 生成引擎版本 16.8.0+126527ff1 版权所有(C) Microsoft Corporation。保留所有权利。 正在确定要还原的项目… 所有项目均是最新的,无法还原。 你正在使用 .NET 的预览版。请查看 https://aka.ms/dotnet-core-preview ConsoleApp2 -> C:\Users\hueif\source\repos\ConsoleApp2\ConsoleApp2\bin\Debug\net5\ConsoleApp2.dll IsWindows true IsOSX IsLinux
可以看出,在
IsWindows中对应着true,说明我们的操作生效了,那么我们继续修改我们的程序,看看如何使用条件编译,去控制我们的代码,我们在项目文件中添加如下片段:
<PropertyGroup Condition="'$(IsWindows)'=='true'"> <DefineConstants>Windows</DefineConstants> </PropertyGroup> <PropertyGroup Condition="'$(IsOSX)'=='true'"> <DefineConstants>OSX</DefineConstants> </PropertyGroup> <PropertyGroup Condition="'$(IsLinux)'=='true'"> <DefineConstants>Linux</DefineConstants> </PropertyGroup>
通过如上语句,我们可以对
DefineConstants属性进行条件判断,条件性处理,同样我们在代码中也是通过该值进行判断,如下所示:
static void Main(string[] args) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) Console.Writ 1bec eLine("Running on Linux!"); else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) Console.WriteLine("Running on macOS!"); else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) Console.WriteLine("Running on Windows!"); #if Linux Console.WriteLine("Build on Linux!"); #elif OSX Console.WriteLine("Build on macOS!"); #elif Windows Console.WriteLine("Build in Windows!"); #endif Console.ReadKey(); }
下面我们来验证一下结果,是否跟我们想象中的一样
Running on Windows! Build in Windows!
结果没问题,已达到预期的效果。
References
https://blog.walterlv.com/post/how-to-define-preprocessor-symbols.html
相关文章推荐
- 实现针对不同.net版本的条件编译
- C#条件编译,发布多平台和多种选择性的项目
- 关于.NET编译的目标平台(AnyCPU,x86,x64)
- .NET跨平台:在CentOS上编译dnx并运行ASP.NET 5示例程序
- 如何判断平台工具集去做条件编译(VC++目录、预处理器定义、$(PlatformToolsetVersion))
- Jenkins结合.net平台综合之监听git仓库并自动摘取最新代码编译
- .NET跨平台:在CentOS上编译dnx并运行ASP.NET 5示例程序
- .NET按条件编译程序
- .NET编译项目时出现《此实现不是 Windows 平台 FIPS 验证的加密算法的一部分》处理方法
- .NET编译、WOW64注册表访问、同时在X86和X64平台上部署应用程序
- 关于.NET编译的目标平台(AnyCPU,x86,x64)
- 关于.NET编译的目标平台(AnyCPU,x86,x64)(转)
- Unity3d C#学习小结(五)[关于不同平台的条件编译]
- .NET跨平台:在Linux Ubuntu上编译coreclr/corefx/dnx(20150617)
- C#基础--.net平台的重要组成部分以及.net程序简单的编译原理
- 针对不同.NET版本的条件编译
- 关于.NET编译的目标平台(AnyCPU,x86,x64)(转)
- 基于.NET平台的Web应用中数据访问技术的深入探索(转)
- 关于.NET编译的目标平台(AnyCPU,x86,x64)(转)
- .net 条件编译