Jak MSBuild sestavuje projekty

Jak nástroj MSBuild skutečně funguje? V tomto článku se dozvíte, jak NÁSTROJ MSBuild zpracovává soubory projektu, ať už vyvolané ze sady Visual Studio, nebo z příkazového řádku nebo skriptu. Znalost fungování nástroje MSBuild vám může pomoct lépe diagnostikovat problémy a lépe přizpůsobit proces sestavení. Tento článek popisuje proces sestavení a je do značné míry použitelný pro všechny typy projektů.

Celý proces sestavení se skládá z počátečního spuštění, vyhodnocení a spuštění cílů a úkolů, které projekt sestaví. Kromě těchto vstupů externí importy definují podrobnosti procesu sestavení, včetně standardních importů , jako jsou Microsoft.Common.targets , a uživatelsky konfigurovatelné importy na úrovni řešení nebo projektu.

Spuštění

Nástroj MSBuild lze vyvolat ze sady Visual Studio prostřednictvím objektového modelu MSBuild v Microsoft.Build.dll nebo vyvoláním spustitelného souboru (MSBuild.exe nebo dotnet build) přímo na příkazovém řádku nebo ve skriptu, například v systémech CI. V obou případech vstupy, které ovlivňují proces sestavení, zahrnují soubor projektu (nebo objekt projektu interní pro Visual Studio), případně soubor řešení, proměnné prostředí a přepínače příkazového řádku nebo jejich ekvivalenty modelu objektu. Během spouštěcí fáze se možnosti příkazového řádku nebo ekvivalenty objektového modelu používají ke konfiguraci nastavení nástroje MSBuild, jako je konfigurace protokolovacích rutin. Vlastnosti nastavené na příkazovém řádku pomocí -property nebo -p přepínače jsou nastaveny jako globální vlastnosti, které přepíší všechny hodnoty, které by se nastavily v souborech projektu, i když se soubory projektu čtou později.

Další části se týkají vstupních souborů, jako jsou soubory řešení nebo soubory projektu.

Řešení a projekty

Instance NÁSTROJE MSBuild se můžou skládat z jednoho projektu nebo mnoha projektů v rámci řešení. Soubor řešení není soubor XML nástroje MSBuild, ale nástroj MSBuild ho interpretuje tak, aby věděl všechny projekty, které jsou potřeba k sestavení pro dané nastavení konfigurace a platformy. Když NÁSTROJ MSBuild zpracuje tento vstup XML, označuje se jako sestavení řešení. Má několik rozšiřitelných bodů, které umožňují spouštět něco v každém sestavení řešení, ale vzhledem k tomu, že toto sestavení je samostatné spuštění od jednotlivých sestavení projektu, nejsou pro každé sestavení projektu relevantní žádná nastavení vlastností ani definice cílů z sestavení řešení.

Postup rozšíření sestavení řešení najdete v části Přizpůsobení sestavení řešení.

Sestavení sady Visual Studio vs. sestavení MSBuild.exe

Mezi sestavením projektů v sadě Visual Studio a voláním nástroje MSBuild přímo prostřednictvím spustitelného souboru MSBuild nebo při spuštění sestavení pomocí objektového modelu MSBuild existují některé významné rozdíly. Visual Studio spravuje pořadí sestavení projektu pro sestavení sady Visual Studio; volá pouze MSBuild na úrovni jednotlivých projektů, a když ano, několik logických vlastností (BuildingInsideVisualStudio, BuildProjectReferences) jsou nastaveny, které významně ovlivňují, co MSBuild dělá. V každém projektu se provádění provádí stejně jako při vyvolání prostřednictvím nástroje MSBuild, ale rozdíl vzniká u odkazovaných projektů. V nástroji MSBuild, pokud jsou požadovány odkazované projekty, sestavení skutečně nastane; to znamená, že spouští úlohy a nástroje a generuje výstup. Když sestavení sady Visual Studio najde odkazovaný projekt, nástroj MSBuild vrátí pouze očekávané výstupy z odkazovaného projektu; umožňuje sadě Visual Studio řídit vytváření těchto dalších projektů. Visual Studio určuje pořadí sestavení a volání do nástroje MSBuild samostatně (podle potřeby), a to vše zcela v rámci ovládacího prvku sady Visual Studio.

Dalším rozdílem vzniká, když je vyvolán nástroj MSBuild se souborem řešení, nástroj MSBuild analyzuje soubor řešení, vytvoří standardní vstupní soubor XML, vyhodnotí ho a spustí ho jako projekt. Sestavení řešení se spustí před jakýmkoli projektem. Při sestavování ze sady Visual Studio se nic z toho nestane; Nástroj MSBuild nikdy nevidí soubor řešení. V důsledku toho se přizpůsobení sestavení řešení (používá před tím ). SolutionName.sln.targets a after. SolutionName.sln.targets) platí pouze pro sestavení MSBuild.exe, dotnet buildnebo sestavení řízená objektem, nikoli sestavení sady Visual Studio.

Sady SDK projektu

Funkce SADY SDK pro soubory projektu MSBuild je relativně nová. Před touto změnou soubory projektu explicitně importovali soubory .targets a .props , které definovaly proces sestavení pro konkrétní typ projektu.

Projekty .NET Core importují verzi sady .NET SDK, která je pro ně vhodná. Prohlédni si přehled, sady SDK projektu .NET Core a odkaz na vlastnosti.

Fáze vyhodnocení

Tato část popisuje, jak se tyto vstupní soubory zpracovávají a parsují za účelem vytvoření objektů v paměti, které určují, co se má sestavit.

Účelem fáze vyhodnocení je vytvořit objektové struktury v paměti na základě vstupních souborů XML a místního prostředí. Fáze vyhodnocení se skládá ze šesti průchodů, které zpracovávají vstupní soubory, jako jsou soubory XML projektu, nebo a importované soubory XML, obecně pojmenované jako soubory .props nebo .targets , v závislosti na tom, jestli primárně nastavují vlastnosti nebo definují cíle sestavení. Každý průchod sestaví část objektů v paměti, které se později použijí ve fázi provádění k sestavení projektů, ale během fáze vyhodnocení nedojde k žádným skutečným akcím sestavení. V rámci každého průchodu se prvky zpracovávají v pořadí, v jakém se zobrazují.

Výsledky ve fázi vyhodnocení jsou následující:

  • Vyhodnocení proměnných prostředí
  • Vyhodnocení importů a vlastností
  • Vyhodnocení definic položek
  • Vyhodnocení položek
  • Vyhodnocení elementů UsingTask
  • Vyhodnocení cílů

Importy a vlastnosti se vyhodnocují ve stejném pořadí výskytu, jako kdyby byly importy rozšířeny. Nastavení vlastností v dříve importovaných souborech jsou tedy k dispozici v pozdějších importovaných souborech.

Pořadí těchto průchodů má významný dopad a je důležité vědět při přizpůsobení souboru projektu. Viz Pořadí vyhodnocení vlastností a položek.

Vyhodnocení proměnných prostředí

V této fázi se proměnné prostředí používají k nastavení ekvivalentních vlastností. Například proměnná prostředí PATH je zpřístupněna jako vlastnost $(PATH). Při spuštění z příkazového řádku nebo skriptu se příkazové prostředí použije jako normální a při spuštění ze sady Visual Studio se prostředí použije při spuštění sady Visual Studio.

Vyhodnocení importů a vlastností

V této fázi se přečte celý vstupní KÓD XML, včetně souborů projektu a celého řetězce importů. NÁSTROJ MSBuild vytvoří strukturu XML v paměti, která představuje XML projektu a všechny importované soubory. V tuto chvíli se vyhodnocují a nastavují vlastnosti, které nejsou v cílech.

V důsledku msBuild čtení všech vstupních souborů XML v rané fázi procesu, všechny změny těchto vstupů během procesu sestavení nemají vliv na aktuální sestavení.

Vlastnosti mimo jakýkoli cíl se zpracovávají jinak než vlastnosti v rámci cílů. V této fázi se vyhodnocují pouze vlastnosti definované mimo jakýkoli cíl.

Vzhledem k tomu, že vlastnosti jsou zpracovány v pořadí ve vlastnostech předávají, vlastnost v libovolném bodě vstupu může přistupovat k hodnotám vlastností, které se zobrazí dříve ve vstupu, ale ne vlastnosti, které se zobrazí později.

Vzhledem k tomu, že se vlastnosti zpracovávají před vyhodnocením položek, nemůžete získat přístup k hodnotě žádné položky během jakékoli části průchodu vlastností.

Vyhodnocení definic položek

V této fázi se interpretují definice položek a vytvoří se reprezentace těchto definic v paměti.

Vyhodnocení položek

Položky definované uvnitř cíle se zpracovávají jinak než položky mimo jakýkoli cíl. V této fázi se zpracovávají položky mimo jakýkoli cíl a jejich přidružená metadata. Metadata nastavená podle definic položek jsou přepsána metadaty nastavenými u položek. Vzhledem k tomu, že se položky zpracovávají v pořadí, v jakém se zobrazují, můžete odkazovat na dříve definované položky, ale ne na položky, které se zobrazí později. Vzhledem k tomu, že předání položek je po předání vlastností, mohou položky přistupovat k jakékoli vlastnosti, pokud jsou definovány mimo jakékoli cíle, bez ohledu na to, zda se definice vlastnosti zobrazí později.

Vyhodnocení UsingTask elementů

V této fázi se načtou prvky UsingTask a úkoly se deklarují pro pozdější použití během fáze provádění.

Vyhodnocení cílů

V této fázi jsou všechny cílové struktury objektů vytvořeny v paměti při přípravě na spuštění. Neprobíhá žádné skutečné spuštění.

Fáze provádění

Ve fázi provádění jsou cíle seřazené a spuštěné a všechny úlohy se spustí. Nejprve se ale vlastnosti a položky definované v rámci cílů vyhodnocují společně v jedné fázi v pořadí, v jakém se zobrazují. Pořadí zpracování se zejména liší od způsobu zpracování vlastností a položek, které nejsou v cíli: nejprve všechny vlastnosti a pak všechny položky v samostatných průchodech. Změny vlastností a položek v rámci cíle lze pozorovat po změně cíle.

Pořadí sestavení cílů

V jednom projektu se cíle provádějí sériově. Centrálním problémem je určení pořadí sestavení všeho tak, aby se závislosti používaly k sestavení cílů ve správném pořadí.

Pořadí cílového sestavení je určeno použitím atributu BeforeTargets, DependsOnTargetsa AfterTargets atributy pro každý cíl. Pořadí pozdějších cílů může být ovlivněno během provádění dřívějšího cíle, pokud dřívější cíl upraví vlastnost odkazovanou v těchto atributech.

Pravidla řazení jsou popsaná v části Určení pořadí cílového sestavení. Proces je určen strukturou zásobníku obsahující cíle, které se mají sestavit. Cíl v horní části tohoto úkolu spustí spuštění, a pokud závisí na čemkoli jiném, pak se tyto cíle nasdílí do horní části zásobníku a začnou se spouštět. Pokud je cíl bez závislostí, provede se dokončení a jeho nadřazený cíl se obnoví.

Odkazy na projekty

Existují dvě cesty kódu, které msBuild může vzít, normální, popsaný zde, a možnost grafu popsaná v další části.

Jednotlivé projekty určují jejich závislost na jiných projektech prostřednictvím ProjectReference položek. Když projekt v horní části zásobníku začne sestavovat, dosáhne bodu ResolveProjectReferences , kdy se cíl spustí, standardní cíl definovaný v běžných cílových souborech.

ResolveProjectReferences vyvolá úlohu MSBuild se vstupy ProjectReference položek pro získání výstupů. Položky ProjectReference jsou transformovány na místní položky, jako Referenceje . Fáze provádění nástroje MSBuild pro aktuální projekt se pozastaví, zatímco fáze provádění začne zpracovávat odkazovaný projekt (fáze vyhodnocení se provádí nejprve podle potřeby). Odkazovaný projekt se sestaví pouze po zahájení vytváření závislého projektu, a proto se vytvoří strom projektů.

Visual Studio umožňuje vytvářet závislosti projektu v souborech řešení (.sln). Závislosti jsou zadány v souboru řešení a jsou dodrženy pouze při sestavování řešení nebo při sestavování v sadě Visual Studio. Pokud vytvoříte jeden projekt, bude tento typ závislosti ignorován. Odkazy na řešení se transformují nástrojem MSBuild na ProjectReference položky a následně se zachází stejným způsobem.

Možnost Grafu

Pokud zadáte přepínač sestavení grafu (-graphBuild nebo -graph), ProjectReference stane se prvotřídní koncept používaný nástrojem MSBuild. NÁSTROJ MSBuild parsuje všechny projekty a sestaví graf pořadí sestavení, skutečný graf závislostí projektů, který se pak prochází k určení pořadí sestavení. Stejně jako u cílů v jednotlivých projektech nástroj MSBuild zajišťuje, aby odkazované projekty byly vytvořeny po projektech, na které závisejí.

Paralelní spouštění

Pokud používáte podporu víceprocesoru (-maxCpuCount nebo -m přepínač), nástroj MSBuild vytvoří uzly, což jsou procesy MSBuild, které používají dostupná jádra procesoru. Každý projekt se odešle do dostupného uzlu. V uzlu se jednotlivé sestavení projektu spouští sériově.

Úlohy mohou být povoleny pro paralelní spouštění nastavením logické proměnné BuildInParallel, která je nastavena podle hodnoty $(BuildInParallel) vlastnosti v MSBuild. U úkolů, které jsou povolené pro paralelní spouštění, spravuje plánovač práce uzly a přiřazuje práci uzlům.

Viz Paralelní sestavování více projektů pomocí nástroje MSBuild

Standardní importy

Microsoft.Common.props a Microsoft.Common.targets jsou importovány soubory projektů .NET (explicitně nebo implicitně v projektech ve stylu sady SDK) a nacházejí se ve složce MSBuild\Current\bin v instalaci sady Visual Studio. Projekty C++ mají vlastní hierarchii importů; Viz interní nástroje MSBuild pro projekty jazyka C++.

Výchozí nastavení souborů Microsoft.Common.props je možné přepsat. Importuje se (explicitně nebo implicitně) na začátku souboru projektu. Tímto způsobem se nastavení projektu zobrazí po výchozích nastaveních, aby je přepsaly.

Soubor Microsoft.Common.targets a cílové soubory, které importuje, definují standardní proces sestavení pro projekty .NET. Poskytuje také body rozšíření, které můžete použít k přizpůsobení sestavení.

Při implementaci je Microsoft.Common.targets tenký obálka, která importuje Microsoft.Common.CurrentVersion.targets. Tento soubor obsahuje nastavení standardních vlastností a definuje skutečné cíle, které definují proces sestavení. Cíl Build je zde definován, ale je ve skutečnosti prázdný. Build Cíl však obsahuje DependsOnTargets atribut, který určuje jednotlivé cíle, které tvoří skutečné kroky sestavení, které jsou BeforeBuild, CoreBuilda AfterBuild. Cíl Build je definován takto:

  <PropertyGroup>
    <BuildDependsOn>
      BeforeBuild;
      CoreBuild;
      AfterBuild
    </BuildDependsOn>
  </PropertyGroup>

  <Target
      Name="Build"
      Condition=" '$(_InvalidConfigurationWarning)' != 'true' "
      DependsOnTargets="$(BuildDependsOn)"
      Returns="@(TargetPathWithTargetPlatformMoniker)" />

BeforeBuild a AfterBuild jsou to rozšiřující body. V souboru Microsoft.Common.CurrentVersion.targets jsou prázdné, ale projekty můžou poskytovat své vlastní BeforeBuild a AfterBuild cíle úkolům, které je potřeba provést před nebo po hlavním procesu sestavení. AfterBuild je spuštěna před cílem no-op, Buildprotože AfterBuild se zobrazí v DependsOnTargets atributu v Build cíli, ale dochází po CoreBuild.

Cíl CoreBuild obsahuje volání nástrojů sestavení následujícím způsobem:

  <PropertyGroup>
    <CoreBuildDependsOn>
      BuildOnlySettings;
      PrepareForBuild;
      PreBuildEvent;
      ResolveReferences;
      PrepareResources;
      ResolveKeySource;
      Compile;
      ExportWindowsMDFile;
      UnmanagedUnregistration;
      GenerateSerializationAssemblies;
      CreateSatelliteAssemblies;
      GenerateManifests;
      GetTargetPath;
      PrepareForRun;
      UnmanagedRegistration;
      IncrementalClean;
      PostBuildEvent
    </CoreBuildDependsOn>
  </PropertyGroup>
  <Target
      Name="CoreBuild"
      DependsOnTargets="$(CoreBuildDependsOn)">

    <OnError ExecuteTargets="_TimeStampAfterCompile;PostBuildEvent" Condition="'$(RunPostBuildEvent)'=='Always' or '$(RunPostBuildEvent)'=='OnOutputUpdated'"/>
    <OnError ExecuteTargets="_CleanRecordFileWrites"/>

  </Target>

Následující tabulka popisuje tyto cíle; některé cíle se vztahují pouze na určité typy projektů.

Cíl Popis
BuildOnly Nastavení Nastavení pouze pro skutečné sestavení, ne pro to, kdy je nástroj MSBuild vyvolán při načítání projektu sadou Visual Studio.
PrepareForBuild Příprava předpokladů pro sestavení
PreBuildEvent Bod rozšíření pro projekty definující úkoly, které se mají provést před sestavením
ResolveProjectReferences Analýza závislostí projektu a sestavení odkazovaných projektů
ResolveAssemblyReferences Vyhledejte odkazovaná sestavení.
ResolveReferences Skládá se z ResolveProjectReferences a ResolveAssemblyReferences nalezení všech závislostí
PrepareResources Zpracování souborů prostředků
ResolveKeySource Vyřešte klíč silného názvu použitý k podepsání sestavení a certifikátu použitého k podepsání manifestů ClickOnce .
Kompilovat Vyvolá kompilátor.
ExportWindowsMDFile Vygenerujte soubor WinMD ze souborů WinMDModule vygenerovaných kompilátorem.
Nespravovaný objektUnregistration Odebrání nebo vyčištění položek registru zprostředkovatele komunikace modelu COM z předchozího sestavení
GenerateSerializationAssemblies Generování sestavení serializace XML pomocí sgen.exe.
CreateSatelliteAssemblies Vytvořte jedno satelitní sestavení pro každou jedinečnou jazykovou verzi prostředků.
Generování manifestů Generuje manifesty aplikace a nasazení ClickOnce nebo nativní manifest.
GetTargetPath Vrátí položku obsahující produkt sestavení (spustitelný soubor nebo sestavení) pro tento projekt s metadaty.
PrepareForRun Pokud se změnily, zkopírujte výstupy sestavení do konečného adresáře.
Nespravovanýregistration Nastavení položek registru pro zprostředkovatele komunikace s objekty COM
IncrementalClean Odeberte soubory vytvořené v předchozím buildu, ale v aktuálním buildu se neprodukovaly. To je nezbytné k tomu Clean , aby fungovaly v přírůstkových buildech.
Postbuildevent Bod rozšíření pro projekty definující úkoly, které se mají spustit po sestavení

Mnoho cílů v předchozí tabulce se nachází v importech specifických pro jazyk, jako je Například Microsoft.CSharp.targets. Tento soubor definuje kroky ve standardním procesu sestavení specifickém pro projekty C# .NET. Obsahuje například Compile cíl, který ve skutečnosti volá kompilátor jazyka C#.

Uživatelsky konfigurovatelné importy

Kromě standardních importů existuje několik importů, které můžete přidat pro přizpůsobení procesu sestavení.

  • Directory.Build.props
  • Directory.Build.targets

Tyto soubory se čtou standardními importy pro všechny projekty v jakékoli podsložce. To je obvykle na úrovni řešení pro nastavení pro řízení všech projektů v řešení, ale může být také vyšší v systému souborů až do kořenového adresáře jednotky.

Soubor Directory.Build.props je importován společností Microsoft.Common.props, takže vlastnosti definované v něm jsou k dispozici v souboru projektu. Dají se předefinovat v souboru projektu, aby se hodnoty přizpůsobily pro jednotlivé projekty. Soubor Directory.Build.targets se načte za souborem projektu. Obvykle obsahuje cíle, ale tady můžete také definovat vlastnosti, které nechcete, aby jednotlivé projekty znovu definovaly.

Vlastní nastavení v souboru projektu

Visual Studio aktualizuje soubory projektu při provádění změn v Průzkumník řešení, v okně Vlastnosti nebo ve vlastnostech projektu, ale můžete také provádět vlastní změny přímo úpravou souboru projektu.

Mnoho chování sestavení lze nakonfigurovat nastavením vlastností nástroje MSBuild, a to buď v souboru projektu pro nastavení místního pro projekt, nebo jak je uvedeno v předchozí části, vytvořením souboru Directory.Build.props pro globální nastavení vlastností pro celé složky projektů a řešení. Pro ad hoc sestavení na příkazovém řádku nebo skripty můžete také použít /p možnost na příkazovém řádku k nastavení vlastností pro konkrétní vyvolání nástroje MSBuild. Informace o vlastnostech projektu, které můžete nastavit, naleznete v části Běžné vlastnosti projektu NÁSTROJE MSBuild.