Přizpůsobení sestavení
MSBuild, které používají standardní proces sestavení (import Microsoft.Common.props a Microsoft.Common.targets), mají několik rozšiřitelnosti, které můžete použít k přizpůsobení procesu sestavení.
Přidání argumentů do příkazového MSBuild volání pro váš projekt
Na sestavení příkazového řádku projektu se použije soubor Directory.Build.rsp ve zdrojovém adresáři nebo vyšším. Podrobnosti najdete v tématu MSBuild souborů s odpověďmi.
Directory.Build.props a Directory.Build.targets
Do každého projektu můžete přidat novou vlastnost tak, že ji definujete v jednom souboru s názvem Directory.Build.props v kořenové složce, která obsahuje váš zdroj. Když MSBuild, microsoft.Common.props prohledá adresářovou strukturu pro soubor Directory.Build.props (a Microsoft.Common.targets hledá Directory.Build.targets). Pokud ho najde, naimportuje soubor a načte vlastnosti, které jsou v ní definované. Directory.Build.props je uživatelem definovaný soubor, který umožňuje přizpůsobení projektů v adresáři.
Poznámka
V linuxových systémech souborů se rozlišují malá a velká písmena. Ujistěte se, že se název souboru Directory.Build.props přesně shoduje, jinak se během procesu sestavení nezjme.
Příklad Directory.Build.props
Pokud například chcete povolit všem projektům přístup k nové funkci Roslyn /deterministic (která je zveřejněná v cíli Roslyn vlastností ), můžete CoreCompile provést následující $(Deterministic) akce.
V kořenovém adresáři vašeho adresáře vytvořte nový soubor s názvem Directory.Build.props.
Do souboru přidejte následující kód XML.
<Project> <PropertyGroup> <Deterministic>true</Deterministic> </PropertyGroup> </Project>Spusťte MSBuild. Existující importy Microsoft.Common.props a Microsoft.Common.targets vašeho projektu najdou soubor a naimportuje ho.
Obor hledání
Při hledání souboru Directory.Build.props MSBuild adresářovou strukturu směrem nahoru od umístění projektu ( ) a zastaví se, jakmile najde soubor $(MSBuildProjectFullPath) Directory.Build.props. Pokud jste například byli $(MSBuildProjectFullPath) c:\users\username\code\test\case1, služba MSBuild by tam mohla začít hledat a pak prohledávat adresářovou strukturu směrem nahoru, dokud by nenašla soubor Directory.Build.props jako v následující adresářové struktuře.
c:\users\username\code\test\case1
c:\users\username\code\test
c:\users\username\code
c:\users\username
c:\users
c:\
Umístění souboru řešení není pro Directory.Build.props relevantní.
Pořadí importu
Directory.Build.props je importován velmi brzy v Microsoft.Common.props a vlastnosti definované později nejsou k dispozici. Proto se vyhněte odkazování na vlastnosti, které ještě nejsou definované (a vyhodnotí se jako prázdné).
Vlastnosti, které jsou nastavené v Directory.Build.props, je možné přepsat jinde v souboru projektu nebo v importovaných souborech, takže byste si měli nastavení v Souboru Directory.Build.props myslet jako na určení výchozích hodnot pro vaše projekty.
Directory.Build.targets se importuje z Microsoft.Common.targets po importu souborů .targets z NuGet balíčků. Může tak přepsat vlastnosti a cíle definované ve většině logiky sestavení nebo nastavit vlastnosti pro všechny projekty bez ohledu na to, co jednotlivé projekty nastaví.
Pokud potřebujete nastavit vlastnost nebo definovat cíl pro jednotlivý projekt, který přepíše předchozí nastavení, dejte tuto logiku do souboru projektu po posledním importu. Abyste to mohli udělat v projektu ve stylu sady SDK, musíte nejprve nahradit atribut ve stylu sady SDK ekvivalentními importy. Viz Jak používat MSBuild sdk projektu.
Poznámka
Modul MSBuild během vyhodnocování čte ve všech importovaných souborech před zahájením provádění sestavení pro projekt (včetně libovolných), takže se neočekává, že tyto soubory budou upraveny v procesu sestavení nebo v žádné jiné části PreBuildEvent PreBuildEvent procesu sestavení. Změny se nepro projeví až při příštím vyvolání MSBuild.exe nebo dalšího Visual Studio sestavení. Pokud proces sestavení obsahuje mnoho sestavení projektu (jako u vícenásobného cílení nebo sestavování závislých projektů), importované soubory, včetně souboru Directory.build.props, se při vyhodnocování pro každé sestavení jednotlivých projektů načtou.
Případ použití: sloučení na více úrovních
Předpokládejme, že máte tuto standardní strukturu řešení:
\
MySolution.sln
Directory.Build.props (1)
\src
Directory.Build.props (2-src)
\Project1
\Project2
\test
Directory.Build.props (2-test)
\Project1Tests
\Project2Tests
Může být žádoucí mít společné vlastnosti pro všechny projekty (1), společné vlastnosti pro projekty src (2-src) a společné vlastnosti pro projekty testů (2-test).
Aby se MSBuild "vnitřní" soubory (2-src a 2-test) správně sloučí s "vnějším" souborem (1), musíte vzít v úvahu, že jakmile MSBuild najde soubor Directory.Build.props, zastaví další kontrolu. Pokud chcete pokračovat v prohledávání a sloučení do vnějšího souboru, umístěte tento kód do obou vnitřních souborů:
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />
Obecný MSBuild tohoto přístupu je následující:
- U libovolného projektu MSBuild první soubor Directory.Build.props ve struktuře řešení směrem nahoru, sloučí ho s výchozími nastaveními a zastaví vyhledávání dalších.
- Pokud chcete najít a sloučit více úrovní,
<Import...>pak (viz výše) vnější soubor z "vnitřního" souboru. - Pokud "vnější" soubor sám naimportuje něco nad něj, zastaví se tam kontrola.
- Pokud chcete řídit proces skenování/slučování, použijte
$(DirectoryBuildPropsPath)a$(ImportDirectoryBuildProps).
Nebo jednodušeji: první Directory.Build.props, který nic neimportuje, je místo, kde MSBuild zastaví.
Volba mezi přidáním vlastností do souboru .props nebo .targets
MSBuild pořadí importu a poslední definicí vlastnosti (nebo UsingTask cíle) je použitá definice.
Při použití explicitních importů můžete kdykoli importovat ze souboru .props nebo .targets. Tady je běžně používaná konvence:
Soubory .props jsou importovány v rané fázi pořadí importu.
Soubory .targets se importuje později v pořadí sestavení.
Tato konvence se vynucuje importy (to znamená, že import <Project Sdk="SdkName"> souboru Sdk.props je na prvním místě, před veškerým obsahem souboru bude sdk.targets na posledním místě po veškerém obsahu souboru).
Při rozhodování, kam umístit vlastnosti, použijte následující obecné pokyny:
U mnoha vlastností nezáleží na tom, kde jsou definovány, protože nejsou přepsány a budou čteny pouze při spuštění.
Pro chování, které lze přizpůsobit v jednotlivých projektech, nastavte výchozí hodnoty v souborech .props.
Vyhněte se nastavení závislých vlastností v souborech .props přečtením hodnoty pravděpodobně přizpůsobené vlastnosti, protože k přizpůsobení nedojde, dokud MSBuild projekt uživatele nečte.
Nastavte závislé vlastnosti v souborech .targets, protože si vyberou vlastní nastavení z jednotlivých projektů.
Pokud potřebujete přepsat vlastnosti, udělejte to v souboru .targets poté, co se všechna přizpůsobení uživatelských projektů projeví. Buďte opatrní při používání odvozených vlastností. Je možné, že bude nutné přepsat také odvozené vlastnosti.
Zahrnutí položek do souborů .props (podmíněných vlastností) Všechny vlastnosti se zvažují před jakoukoli položkou, takže přizpůsobení vlastností uživatelského projektu se převezou, což dává projektu uživatele příležitost nebo jakoukoli položku, kterou import
RemoveUpdatepřináší.Definujte cíle v souborech .targets. Pokud je ale soubor .targets importován sadou SDK, mějte na paměti, že tento scénář ztěžuje přepsání cíle, protože projekt uživatele nemá místo, kde by ho ve výchozím nastavení přepisoval.
Pokud je to možné, upřednostňte přizpůsobení vlastností při vyhodnocování před změnou vlastností uvnitř cíle. Tento návod usnadňuje načtení projektu a pochopení jeho práce.
MSBuildProjectExtensionsPath
Ve výchozím nastavení importuje Microsoft.Common.props a $(MSBuildProjectExtensionsPath)$(MSBuildProjectFile).*.props Microsoft.Common.targets $(MSBuildProjectExtensionsPath)$(MSBuildProjectFile).*.targets . Výchozí hodnota je MSBuildProjectExtensionsPath $(BaseIntermediateOutputPath) , obj/ . NuGet tento mechanismus používá k odkazování na logiku sestavení dodanou s balíčky. To znamená, že při obnovení vytváří soubory, které odkazují {project}.nuget.g.props na obsah balíčku.
Tento mechanismus rozšiřitelnosti můžete zakázat nastavením vlastnosti na hodnotu ImportProjectExtensionProps v false souboru Directory.Build.props nebo před importem souboru Microsoft.Common.props.
Poznámka
Zakázání importů MSBuildProjectExtensionsPath zabrání tomu, aby se logika sestavení NuGet balíčky pro váš projekt. Některé NuGet vyžadují k provádění své funkce logiku sestavení, a pokud je tato možnost zakázaná, budou nepoužitelné.
Soubor .user
Microsoft.Common.CurrentVersion.targets importuje , pokud existuje, takže můžete vytvořit soubor vedle projektu $(MSBuildProjectFullPath).user s tímto dalším rozšířením. U dlouhodobých změn, které plánujete sesouvat do správy zdrojového kódu, upřednostňujte změnu samotného projektu tak, aby o tomto mechanismu rozšíření nemusí vědět budoucí údržbáři.
MSBuildExtensionsPath a MSBuildUserExtensionsPath
Upozornění
Použití těchto rozšiřujících mechanismů ztěžuje opakované sestavení napříč počítači. Zkuste použít konfiguraci, kterou je možné zkontrolovat v systému správy zdrojového kódu a sdílet ji mezi všemi vývojáři vašeho základního kódu.
Podle konvence importuje mnoho základních souborů logiky sestavení.
$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\{TargetFileName}\ImportBefore\*.targets
před jejich obsahem, a
$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\{TargetFileName}\ImportAfter\*.targets
Potom. Tato konvence umožňuje nainstalovaným sdk rozšířit logiku sestavení běžných typů projektů.
Stejná adresářová struktura se prohledá v adresáři , což je složka pro uživatele $(MSBuildUserExtensionsPath) %LOCALAPPDATA%\Microsoft\MSBuild. Soubory umístěné do této složky budou importovány pro všechna sestavení odpovídajícího typu projektu spuštěná pod přihlašovacími údaji tohoto uživatele. Uživatelská rozšíření můžete zakázat nastavením vlastností pojmenovaných podle importovaného souboru ve vzoru ImportUserLocationsByWildcardBefore{ImportingFileNameWithNoDots} . Pokud například nastavíte ImportUserLocationsByWildcardBeforeMicrosoftCommonProps na false , zabráníte importu $(MSBuildUserExtensionsPath)\$(MSBuildToolsVersion)\Imports\Microsoft.Common.props\ImportBefore\* .
Vlastní konfigurace na základě jazyka projektu
Pokud potřebujete jiné chování v závislosti na jazyce .NET (C#, Visual Basic nebo F#), můžete přidat skupiny vlastností s podmínkami, které závisí na příponě souboru projektu v , a definovat vlastnosti specifické pro jazyk a $(MSBuildProjectExtension) jejich hodnoty.
<PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.vbproj'">
<!-- Put VB-only property definitions here -->
</PropertyGroup>
<PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.fsproj'">
<!-- Put F#-only property definitions here -->
</PropertyGroup>
<PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.csproj'">
<!-- Put C#-only property definitions here -->
</PropertyGroup>
Přizpůsobení sestavení řešení
Důležité
Přizpůsobení sestavení řešení tímto způsobem se vztahuje pouze na sestavení příkazového řádku s MSBuild.exe. Nevztahuje se na sestavení uvnitř Visual Studio. Z tohoto důvodu se nedoporučuje přizpůsobovat na úrovni řešení. Lepší alternativou pro přizpůsobení všech projektů v řešení je použití souborů Directory.Build.props a Directory.build.targets ve složce řešení, jak je popsáno jinde v tomto článku.
Když MSBuild soubor řešení, nejprve ho interně přeloží do souboru projektu a pak ho sestaví. Vygenerovaný soubor projektu importuje před definováním cílů a po importu cílů, včetně cílů before.{solutionname}.sln.targets after.{solutionname}.sln.targets nainstalovaných do $(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\SolutionFile\ImportBefore adresářů a $(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\SolutionFile\ImportAfter .
Můžete například definovat nový cíl pro zápis vlastní zprávy protokolu po sestavení MyCustomizedSolution.sln vytvořením souboru ve stejném adresáři pojmenovaném po. MyCustomizedSolution.sln.targets obsahující
<Project>
<Target Name="EmitCustomMessage" AfterTargets="Build">
<Message Importance="High" Text="The solution has completed the Build target" />
</Target>
</Project>
Sestavení řešení je oddělené od sestavení projektu, takže nastavení zde nemají vliv na sestavení projektu.
Přizpůsobení všech sestavení .NET
při údržbě serveru sestavení může být nutné nakonfigurovat MSBuild nastavení globálně pro všechna sestavení na serveru. V zásadě můžete upravit globální soubory Microsoft. Common. targets nebo Microsoft. Common. props , ale existuje lepší způsob. můžete ovlivnit všechna sestavení určitého typu projektu (například všechny projekty jazyka C#) pomocí některých vlastností MSBuild a přidat určité vlastní .targets .props soubory a.
chcete-li ovlivnit všechna sestavení v jazyce C# nebo Visual Basic, se kterými se řídí instalace MSBuild nebo Visual Studio, vytvořte vlastní soubor. Before. microsoft. common. targets nebo custom. After. microsoft. common. targets s cíli, který se spustí před nebo po souboru microsoft. common. props nebo Custom. After. Microsoft. Common. props s vlastnostmi, které se zpracují před nebo po Microsoft
umístění těchto souborů můžete určit pomocí následujících vlastností MSBuild:
- CustomBeforeMicrosoftCommonProps
- CustomBeforeMicrosoftCommonTargets
- CustomAfterMicrosoftCommonProps
- CustomAfterMicrosoftCommonTargets
- CustomBeforeMicrosoftCSharpTargets
- CustomBeforeMicrosoftVisualBasicTargets
- CustomAfterMicrosoftCSharpTargets
- CustomAfterMicrosoftVisualBasicTargets
společné verze těchto vlastností mají vliv na projekty C# i Visual Basic. tyto vlastnosti můžete nastavit na příkazovém řádku MSBuild.
msbuild /p:CustomBeforeMicrosoftCommonTargets="C:\build\config\Custom.Before.Microsoft.Common.Targets" MyProject.csproj
Nejlepší přístup závisí na vašem scénáři. pomocí rozšíření Visual Studio můžete přizpůsobit systém sestavení a poskytnout mechanismus pro instalaci a správu úprav.
Pokud máte vyhrazený server sestavení a chcete zajistit, aby se určité cíle vždy spouštěly na všech sestaveních příslušného typu projektu, které na tomto serveru běží, pak použijte globální vlastní .targets soubor nebo .props smysl. pokud chcete, aby se vlastní cíle prováděly jenom v případě, že platí určité podmínky, použijte jiné umístění souboru a nastavte cestu k tomuto souboru nastavením příslušné vlastnosti MSBuild v příkazovém řádku MSBuild, jenom pokud je to potřeba.
Upozornění
Visual Studio používá vlastní .targets soubory nebo, .props pokud je nalezne ve složce MSBuild vždy, když sestaví libovolný projekt odpovídajícího typu. to může mít nezamýšlené důsledky a v případě nesprávného fungování může zakázat možnost Visual Studio sestavit v počítači.
Přizpůsobení sestavení C++
V případě projektů v jazyce C++ nelze použít dříve zmíněné soubory Custom . targets a . props stejným způsobem, než bude možné přepsat výchozí nastavení. Adresář. Build. props importovala Společnost Microsoft. Common. props, který je importován v Microsoft.Cpp.Default.props i když je většina výchozích hodnot definována v souboru Microsoft. cpp. props a pro určitý počet vlastností a "Pokud ještě není definováno", nelze použít, protože vlastnost je již definována, ale výchozí hodnota musí být odlišná pro konkrétní vlastnosti projektu definované v PropertyGroup with Label="Configuration" (viz struktura souborů. vcxproj a. props).
Pomocí následujících vlastností ale můžete určit soubory . props , které se mají automaticky importovat před nebo po * Microsoft. cpp. Files:
- ForceImportAfterCppDefaultProps
- ForceImportBeforeCppProps
- ForceImportAfterCppProps
- ForceImportBeforeCppTargets
- ForceImportAfterCppTargets
Chcete-li přizpůsobit výchozí hodnoty vlastností pro všechna sestavení v jazyce C++, vytvořte další soubor . props (například MyProps. props) a definujte ForceImportAfterCppProps vlastnost v Directory.Build.props nasměrování:
<PropertyGroup>
<ForceImportAfterCppProps>$(MsbuildThisFileDirectory)\MyProps.props<ForceImportAfterCppProps>
</PropertyGroup>
MyProps. props budou automaticky importovány na konci na konci Microsoft. cpp. props.
Přizpůsobení všech sestavení v jazyce C++
přizpůsobení instalace Visual Studio nedoporučujeme, protože není snadné sledovat taková vlastní nastavení, ale pokud rozšiřujete Visual Studio na přizpůsobení sestavení C++ pro konkrétní platformu, můžete vytvořit .targets soubory pro každou platformu a umístit je do příslušných složek pro import pro tyto platformy jako součást rozšíření Visual Studio.
.targetsSoubor pro platformu Win32, Microsoft. cpp. Win32. targets obsahuje následující Import element:
<Import Project="$(VCTargetsPath)\Platforms\Win32\ImportBefore\*.targets"
Condition="Exists('$(VCTargetsPath)\Platforms\Win32\ImportBefore')"
/>
Poblíž konce stejného souboru je podobný element:
<Import Project="$(VCTargetsPath)\Platforms\Win32\ImportAfter\*.targets"
Condition="Exists('$(VCTargetsPath)\Platforms\Win32\ImportAfter')"
/>
podobné prvky importu existují pro jiné cílové platformy ve *% ProgramFiles32% \ MSBuild \Microsoft.Cpp\v{version}\Platforms * .
po umístění .targets souboru do příslušné ImportAfter složky podle platformy MSBuild soubor importuje do každého sestavení v jazyce C++ pro danou platformu. .targetsV případě potřeby můžete umístit více souborů.
díky rozšiřitelnosti Visual Studio jsou možné další úpravy, jako je například definování nové platformy. Další informace naleznete v tématu rozšiřitelnost projektů C++.
Zadat vlastní import na příkazovém řádku
Pro vlastní .targets , které chcete zahrnout pro konkrétní sestavení projektu C++, nastavte jednu nebo obě vlastnosti ForceImportBeforeCppTargets a ForceImportAfterCppTargets na příkazovém řádku.
msbuild /p:ForceImportBeforeCppTargets="C:\build\config\Custom.Before.Microsoft.Cpp.Targets" MyCppProject.vcxproj
Pro globální nastavení (to znamená, že všechna sestavení C++ pro platformu na serveru sestavení) existují dvě metody. Nejdřív můžete tyto vlastnosti nastavit pomocí proměnné prostředí systému, která je vždycky nastavená. to funguje, protože MSBuild vždy přečte prostředí a vytvoří (nebo přepisuje) vlastnosti pro všechny proměnné prostředí.