MSBuild是一種基于XML的構(gòu)建引擎,用于在.NET Framework和.NET Core應(yīng)用程序中自動(dòng)化構(gòu)建過程。它是Visual Studio的構(gòu)建引擎,可在命令行或其他構(gòu)建工具中使用。
MSBuild使用XML文件格式來指定項(xiàng)目的編譯、測(cè)試和部署等各個(gè)階段的任務(wù)。這些XML文件通常以.csproj文件的形式存儲(chǔ)。每個(gè)項(xiàng)目文件都包含一個(gè)或多個(gè) PropertyGroup 元素和一個(gè)或多個(gè) ItemGroup 元素。 PropertyGroup 元素聲明和定義屬性,例如目標(biāo)框架、輸出路徑和程序集名稱等。 ItemGroup 元素創(chuàng)建項(xiàng),例如NuGet包引用、文件和資源等。
可以使用 dotnet build 命令或 msbuild 命令來運(yùn)行MSBuild,它會(huì)自動(dòng)查找與當(dāng)前目錄相關(guān)聯(lián)的項(xiàng)目并執(zhí)行構(gòu)建過程。你還可以使用/t選項(xiàng)指定一個(gè)或多個(gè)目標(biāo),例如Clean、Build和Publish。
MSBuild支持條件和屬性組合,可以為不同的目標(biāo)平臺(tái)自定義構(gòu)建過程。還可以使用自定義任務(wù),例如運(yùn)行代碼靜態(tài)分析器或壓縮構(gòu)建輸出文件等。
MSBuild可以用于多種場景,包括:
以下是一些MSBuild基礎(chǔ)知識(shí):
屬性是聲明和定義變量的方式。可以使用 SetProperty 元素或 PropertyGroup元素來定義屬性。例如:
<PropertyGroup> <MyProperty>MyValue</MyProperty></PropertyGroup>
項(xiàng)用于表示一個(gè)或多個(gè)文件或其他資源。可以使用 ItemGroup 元素和具有Include屬性的元素來創(chuàng)建項(xiàng)。例如:
<ItemGroup> <Compile Include="*.cs" /></ItemGroup>
任務(wù)是執(zhí)行構(gòu)建過程中的特定操作的方式。可以使用 Task 元素和具有TaskName屬性的元素來聲明和定義任務(wù)。例如:
<TaskName Parameter1="Value1" Parameter2="Value2" />
要在命令行上運(yùn)行MSBuild,請(qǐng)使用以下命令:
msbuild MyProject.csproj /t:Build /p:Configuration=Debug
該命令將運(yùn)行名為 "Build" 的構(gòu)建目標(biāo),并使用名為 "Debug" 的配置文件來構(gòu)建項(xiàng)目。
MSBuild還有許多高級(jí)用法,包括:
在項(xiàng)目文件中定義自定義屬性和條件,例如定義一個(gè)自定義屬性來指定構(gòu)建輸出目錄:
<Project> <PropertyGroup> <OutputDirectory>bin/$(Configuration)/</OutputDirectory> </PropertyGroup> ... <Target Name="Build"> <MakeDir Directories="$(OutputDirectory)" /> ... </Target></Project>
此時(shí),可以在通用屬性文件中定義屬性值,然后在不同的項(xiàng)目文件中包含該通用屬性文件,以便重復(fù)使用自定義屬性。
在項(xiàng)目文件中聲明目標(biāo)之間的依賴關(guān)系,例如,在兩個(gè)目標(biāo)之間添加依賴關(guān)系:
<Project> ... <Target Name="Build"> ... </Target> <Target Name="Test" DependsOnTargets="Build"> ... </Target></Project>
這樣,MSBuild在執(zhí)行 "Test" 目標(biāo)時(shí),會(huì)先執(zhí)行 "Build" 目標(biāo)。
編寫自定義任務(wù)來執(zhí)行構(gòu)建過程中的特定任務(wù)。例如,使用 MSBuildCommunityTasks 執(zhí)行 FTP 上傳:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <UsingTask TaskName="FTPTask" AssemblyFile="MSBuild.Community.Tasks.dll" /> <Target Name="UploadFile"> <FTPTask ServerHost="ftp.example.com" RemoteFile="upload.txt" LocalFile="c:/files/upload.txt" Username="user" Password="pass" /> </Target></Project>
這個(gè)示例中,定義了一個(gè)名為 "FTPTask" 的自定義任務(wù),然后在 "UploadFile" 目標(biāo)中調(diào)用該任務(wù)來執(zhí)行 FTP 上傳。
使用條件表達(dá)式根據(jù)條件執(zhí)行不同的任務(wù)。例如,根據(jù)平臺(tái)類型選擇不同的構(gòu)建配置:
<Project> ... <Choose> <When Condition="'$(Platform)' == 'x86'"> <PropertyGroup> <DefineConstants>DEBUG;X86</DefineConstants> ... </PropertyGroup> </When> <When Condition="'$(Platform)' == 'x64'"> <PropertyGroup> <DefineConstants>DEBUG;X64</DefineConstants> ... </PropertyGroup> </When> </Choose> ...</Project>
此示例使用條件表達(dá)式 <Choose> 和 <When> 標(biāo)記,通過判斷 $(Platform) 變量的值來選擇執(zhí)行不同的 PropertyGroup。
自定義構(gòu)建日志以記錄構(gòu)建過程中的詳細(xì)信息。例如,將構(gòu)建日志輸出到文件:
<Project> <PropertyGroup> <LogDirectory>logs/</LogDirectory> </PropertyGroup> <Target Name="Build"> <Exec Command="dotnet build MyApp.csproj" /> </Target> <Target Name="LogBuild" AfterTargets="Build"> <Message Text="Writing build log to $(LogDirectory)/build.log" Importance="high" /> <WriteLinesToFile File="$(LogDirectory)/build.log" Lines="$([System.DateTime]::Now.ToString()) - Build succeeded." /> </Target></Project>
此示例中,定義了一個(gè)名為 "LogBuild" 的目標(biāo),并在執(zhí)行 "Build" 目標(biāo)之后調(diào)用該目標(biāo)。在 "LogBuild" 目標(biāo)中,使用 <Message> 元素將日志輸出到控制臺(tái),使用 <WriteLinesToFile> 元素將日志寫入日志文件。
以下是MSBuild的一些最佳實(shí)踐及代碼示例:
使用命名屬性組,以便更好地組織和管理屬性:
<Project> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <DefineConstants>DEBUG;TRACE</DefineConstants> <Optimize>false</Optimize> <OutputPath>bin/Debug/</OutputPath> ... </PropertyGroup> ...</Project>
在這個(gè)示例中,屬性都被包含在一個(gè)名為 "Debug|AnyCPU" 的 PropertyGroup 中。這樣可以更好地組織和管理屬性,并且可以使用條件表達(dá)式來根據(jù)需要選擇不同的屬性組。
避免硬編碼文件路徑,而是使用相對(duì)路徑和通用屬性:
<Project> <ItemGroup> <Compile Include="src/**/*.cs" /> ... </ItemGroup> <PropertyGroup> <OutputPath>bin/$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), Build.props)/)</OutputPath> </PropertyGroup> ...</Project>
在這個(gè)示例中,使用相對(duì)路徑 "src***.cs" 來指定需要編譯的源代碼文件,并使用通用屬性來獲取輸出路徑,以避免硬編碼路徑并提高可移植性。
使用預(yù)定義的 MSBuild 目標(biāo)和任務(wù),以便重復(fù)使用現(xiàn)有功能:
<Project> ... <Target Name="Clean"> <MSBuild Projects="$(MSBuildThisFileFullPath)" Targets="CleanSolution" Properties="Configuration=$(Configuration)" /> </Target> ...</Project>
在這個(gè)示例中,使用現(xiàn)有的 MSBuild 目標(biāo)和任務(wù)來執(zhí)行 "Clean" 目標(biāo)。這樣可以重復(fù)使用現(xiàn)有功能并提高構(gòu)建效率。
使用條件表達(dá)式來支持多個(gè)版本和平臺(tái):
<Project> ... <Choose> <When Condition="'$(TargetFramework)' == 'netcoreapp3.1'"> <PropertyGroup> <DefineConstants>NET_CORE_3_1</DefineConstants> ... </PropertyGroup> </When> <When Condition="'$(TargetFramework)' == 'net5.0'"> <PropertyGroup> <DefineConstants>NET_5_0</DefineConstants> ... </PropertyGroup> </When> </Choose> ...</Project>
在這個(gè)示例中,使用條件表達(dá)式根據(jù)目標(biāo)框架選擇執(zhí)行不同的操作。這樣可以更好地支持多個(gè)版本和平臺(tái),并保持代碼的簡潔和易于維護(hù)。
禁用 Visual Studio 的自動(dòng)格式化選項(xiàng),以避免與代碼格式化工具沖突:
<Project> ... <PropertyGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'"> <EnableEditorConfig>false</EnableEditorConfig> </PropertyGroup> ...</Project>
在這個(gè)示例中,使用 EnableEditorConfig 屬性來禁用 Visual Studio 的自動(dòng)格式化選項(xiàng),以避免與代碼格式化工具沖突。這樣可以保持代碼格式化的一致性,減少錯(cuò)誤和不必要的麻煩。
參考文檔:https://learn.microsoft.com/zh-cn/visualstudio/msbuild/msbuild-concepts?view=vs-2022。
本文鏈接:http://www.www897cc.com/showinfo-26-94-0.html不容錯(cuò)過的MSBuild技巧,必備用法詳解和實(shí)踐指南
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com