Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
MSBuild to aparat kompilacji firmy Microsoft używany do kompilowania większości projektów programu Visual Studio. Program MSBuild wywołuje kompilatory i inne narzędzia do kompilowania kodu, ale także zawiera elastyczne opcje konfiguracji i dostosowywania oraz infrastrukturę do tworzenia nie tylko skompilowanych plików binarnych, ale także szeroką gamę innych artefaktów wyjściowych. Program MSBuild jest bardzo konfigurowalny i dostosowywalny, ale aby jak najlepiej wykorzystać tę możliwość dostosowywania, ważne jest, aby zrozumieć, jak działa program MSBuild. W tym artykule dowiesz się, jak program MSBuild przetwarza pliki projektu, niezależnie od tego, czy jest wywoływany z programu Visual Studio, czy z wiersza polecenia lub skryptu. Znajomość sposobu działania programu MSBuild może pomóc w lepszym diagnozowaniu problemów i lepszym dostosowaniu procesu kompilacji. W tym artykule opisano proces kompilacji i jest w dużej mierze stosowany do wszystkich typów projektów.
Kompletny proces kompilacji składa się z
- początkowe uruchamianie — przetwarzanie opcji wiersza polecenia.
- evaluation — interpretacja i przetwarzanie tekstu pliku projektu MSBuild.
- execution — uruchamia obiekty docelowe i zadania, które kompilują projekt.
Oprócz plików źródłowych i innych artefaktów wejściowych importy zewnętrzne definiują szczegóły procesu kompilacji, w tym zarówno standardowe importy , jak Microsoft.Common.targets i importy konfigurowalne przez użytkownika na poziomie rozwiązania lub projektu.
Startup
Program MSBuild można wywołać z programu Visual Studio za pomocą modelu obiektów MSBuild w Microsoft.Build.dlllub wywołując plik wykonywalny (MSBuild.exe lub dotnet build) bezpośrednio w wierszu polecenia lub w skrypcie, na przykład w systemach CI. W obu przypadkach dane wejściowe wpływające na proces kompilacji obejmują plik projektu (lub obiekt projektu wewnętrzny w programie Visual Studio), prawdopodobnie plik rozwiązania, zmienne środowiskowe i przełączniki wiersza polecenia lub ich odpowiedniki modelu obiektów. Podczas fazy uruchamiania opcje wiersza polecenia lub odpowiedniki modelu obiektów są używane do konfigurowania ustawień programu MSBuild, takich jak konfigurowanie rejestratorów. Właściwości ustawione w wierszu polecenia przy użyciu przełącznika -property lub -p są ustawiane jako właściwości globalne, które zastępują wszystkie wartości ustawione w plikach projektu, mimo że pliki projektu są odczytywane później.
Następne sekcje dotyczą plików wejściowych, takich jak pliki rozwiązania lub pliki projektu.
Rozwiązania i projekty
Wystąpienia programu MSBuild mogą składać się z jednego projektu lub wielu projektów w ramach rozwiązania. Pliki rozwiązania w formacie .slnx lub .sln są obsługiwane (w programie MSBuild 17.12 lub nowszym). Plik rozwiązania (.sln) nie jest plikiem XML programu MSBuild, ale program MSBuild interpretuje go, aby znać wszystkie projekty wymagane do skompilowania dla danej konfiguracji i ustawień platformy. Gdy program MSBuild przetwarza te dane wejściowe, proces ten jest określany jako budowanie rozwiązania. Ma on pewne rozszerzalne punkty, które umożliwiają uruchamianie czegoś w każdej kompilacji rozwiązania, ale ponieważ ta kompilacja jest oddzielnym uruchomieniem od poszczególnych kompilacji projektu, żadne ustawienia właściwości lub definicji docelowych z kompilacji rozwiązania nie są istotne dla każdej kompilacji projektu.
Aby dowiedzieć się, jak rozszerzyć kompilację rozwiązania, zobacz Dostosowywanie kompilacji rozwiązania.
Kompilacje programu Visual Studio a kompilacje MSBuild.exe
Istnieją pewne istotne różnice między kompilacją projektów w programie Visual Studio a bezpośrednie wywołanie programu MSBuild za pośrednictwem pliku wykonywalnego MSBuild lub użycie modelu obiektów MSBuild do uruchomienia kompilacji. Program Visual Studio zarządza kolejnością kompilacji projektów podczas ich budowania; wywołuje MSBuild jedynie na poziomie pojedynczych projektów, a gdy to robi, ustawia kilka właściwości logicznych (BuildingInsideVisualStudio, BuildProjectReferences), które znacząco wpływają na działanie MSBuild. W każdym projekcie wykonywanie odbywa się tak samo jak w przypadku wywołania za pomocą programu MSBuild, ale różnica występuje w przypadku przywoływanych projektów. W programie MSBuild, gdy wymagane są przywoływane projekty, faktycznie odbywa się budowanie; oznacza to, że wykonuje zadania i używa narzędzi oraz generuje dane wyjściowe. Po znalezieniu odniesionego projektu przez kompilację Visual Studio, MSBuild zwraca tylko oczekiwane dane wyjściowe z tego projektu; pozwala Visual Studio kontrolować budowanie tych innych projektów. Program Visual Studio określa kolejność kompilacji i wykonuje osobno wywołania do MSBuild w razie potrzeby, całkowicie pod pełną kontrolą programu Visual Studio.
Inna różnica występuje, gdy program MSBuild jest wywoływany z plikiem rozwiązania, program MSBuild analizuje plik rozwiązania, tworzy standardowy plik wejściowy XML, ocenia go i wykonuje jako projekt. Kompilacja rozwiązania jest wykonywana przed każdym projektem. Podczas kompilowania z poziomu programu Visual Studio nic z tego nie dzieje się; Program MSBuild nigdy nie widzi pliku rozwiązania. W konsekwencji dostosowanie kompilacji rozwiązania (przy użyciu przed.SolutionName.sln.targets i po.SolutionName.sln.targets) dotyczy tylko kompilacji MSBuild.exe, dotnet buildlub opartych na modelu obiektowym, a nie kompilacji Visual Studio.
Zestawy SDK projektu
Funkcja zestawu SDK dla plików projektu MSBuild jest stosunkowo nowa. Przed tą zmianą, pliki projektu wyraźnie importowały pliki .targets oraz .props, które definiowały proces kompilacji dla danego typu projektu.
Projekty platformy .NET Core importują odpowiednią wersję zestawu .NET SDK. Zobacz omówienie zestawów SDK projektów platformy .NET Core oraz odwołanie do właściwości .
Faza oceny
W tej sekcji omówiono sposób przetwarzania i analizowania tych plików wejściowych w celu utworzenia obiektów w pamięci, które określają, co zostanie skompilowane.
Celem fazy oceny jest utworzenie struktur obiektów w pamięci na podstawie wejściowych plików XML i środowiska lokalnego. Faza oceny składa się z sześciu przebiegów, które przetwarzają pliki wejściowe, takie jak pliki XML projektu lub importowane pliki XML, zazwyczaj nazywane .props lub .targets, w zależności od tego, czy ustawiają właściwości, czy definiują cele kompilacji. Każda passa tworzy część obiektów w pamięci, które są później używane w fazie wykonywania do kompilowania projektów, ale nie występują rzeczywiste akcje kompilacji w fazie oceny. W ramach każdej iteracji elementy są przetwarzane w kolejności, w jakiej się pojawiają.
Przebiegi w fazie oceny są następujące:
- Ocena zmiennych środowiskowych
- Analiza importów i właściwości
- Ocena definicji elementów
- Ocena elementów
- Ocena elementów UsingTask
- Ocena celów
Importy i właściwości są oceniane w tym samym przebiegu, w kolejności występowania, tak jak w przypadku, gdy importy są rozszerzane w miejscu. W związku z tym ustawienia właściwości w wcześniej importowanych plikach są dostępne w późniejszych importowanych plikach.
Ważne jest, aby znać kolejność tych przebiegów, ponieważ ma ona znaczące konsekwencje podczas dostosowywania pliku projektu. Zobacz Atrybut i kolejność oceny elementów.
Ocena zmiennych środowiskowych
W tej fazie zmienne środowiskowe są używane do ustawiania równoważnych właściwości. Na przykład zmienna środowiskowa PATH jest udostępniana jako właściwość $(PATH). Podczas uruchamiania z wiersza poleceń lub skryptu środowisko poleceń jest używane w zwykły sposób, a podczas uruchamiania z programu Visual Studio używane jest środowisko, które obowiązywało w momencie uruchomienia programu Visual Studio.
Analiza importów i właściwości
W tej fazie cały wejściowy kod XML jest odczytywany, w tym pliki projektu i cały łańcuch importu. Program MSBuild tworzy strukturę XML w pamięci, która reprezentuje kod XML projektu i wszystkie zaimportowane pliki. Obecnie właściwości, które nie znajdują się w obiektach docelowych, są oceniane i ustawiane.
W wyniku odczytu wszystkich plików wejściowych XML w programie MSBuild na wczesnym etapie procesu wszelkie zmiany tych danych wejściowych w procesie kompilacji nie mają wpływu na bieżącą kompilację.
Właściwości spoza dowolnego obiektu docelowego są obsługiwane inaczej niż właściwości w ramach obiektów docelowych. W tej fazie oceniane są tylko właściwości zdefiniowane poza dowolnym obiektem docelowym.
Ponieważ właściwości są przetwarzane w kolejności przekazywanej właściwości, właściwość w dowolnym momencie w danych wejściowych może uzyskać dostęp do wartości właściwości, które są wyświetlane wcześniej w danych wejściowych, ale nie właściwości, które pojawią się później.
Ponieważ właściwości są przetwarzane, zanim elementy zostaną ocenione, nie można uzyskać dostępu do wartości dowolnego elementu w trakcie jakiejkolwiek części przetwarzania właściwości.
Ocena definicji elementów
W tej fazie definicje elementów są interpretowane i tworzona jest reprezentacja w pamięci tych definicji.
Ocena elementów
Elementy zdefiniowane wewnątrz obiektu docelowego są obsługiwane inaczej niż elementy spoza dowolnego obiektu docelowego. W tej fazie przetwarzane są elementy spoza dowolnego obiektu docelowego i skojarzonych z nimi metadanych. Metadane ustawiane według definicji elementów są zastępowane przez metadane ustawione dla elementów. Ponieważ elementy są przetwarzane w kolejności ich wyświetlania, można odwoływać się do elementów, które zostały zdefiniowane wcześniej, ale nie tych, które pojawiają się później. Ponieważ przekazywanie elementów następuje po przekazywaniu właściwości, elementy mogą uzyskać dostęp do dowolnej właściwości, jeśli zostały zdefiniowane poza celami, niezależnie od tego, czy definicja właściwości pojawia się później.
Ocena elementów UsingTask
W tej fazie elementy UsingTask są odczytywane, a zadania są deklarowane do późniejszego użycia w fazie wykonywania.
Ocena celów
W tej fazie wszystkie struktury obiektów docelowych są tworzone w pamięci, w ramach przygotowań do wykonania. Nie odbywa się rzeczywiste wykonanie.
Faza realizacji
W fazie wykonywania obiekty docelowe są uporządkowane i uruchamiane, a wszystkie zadania są wykonywane. Najpierw właściwości i elementy zdefiniowane w ramach elementów docelowych są oceniane razem w jednej fazie w kolejności, w jakiej się pojawiają. Kolejność przetwarzania różni się w szczególności od sposobu przetwarzania właściwości i elementów, które nie znajdują się w obiekcie docelowym: najpierw wszystkie właściwości, a następnie wszystkie elementy w osobnych przejściach. Zmiany właściwości i elementów w obiekcie docelowym można zaobserwować po dokonaniu zmian w tym obiekcie.
Docelowa kolejność kompilacji
W jednym projekcie cele są wykonywane szeregowo. Głównym problemem jest określenie kolejności kompilowania wszystkich elementów w taki sposób, aby zależności były używane do kompilowania obiektów docelowych w odpowiedniej kolejności.
Kolejność kompilacji docelowej jest określana przez użycie atrybutów BeforeTargets, DependsOnTargetsi AfterTargets dla każdego obiektu docelowego. Kolejność późniejszych celów może mieć wpływ podczas wykonywania wcześniejszego celu, jeśli wcześniejszy cel modyfikuje właściwość, na którą powołują się te atrybuty.
Reguły porządkowania są opisane w Określanie docelowej kolejności kompilacji. Proces jest określany przez strukturę stosu zawierającą obiekty docelowe do skompilowania. Cele na szczycie tego zadania rozpoczynają wykonywanie, a jeśli zależą od czegokolwiek innego, te cele są umieszczane na szczycie stosu i zaczynają się wykonywać. Gdy cel nie ma żadnych zależności, wykonuje się do końca, a jego nadrzędny cel kontynuuje.
Referencje projektowe
Istnieją dwie ścieżki kodu, którymi MSBuild może podążać: normalna, opisana tutaj, oraz opcja grafu opisana w następnej sekcji.
Poszczególne projekty określają zależność od innych projektów za pośrednictwem elementów ProjectReference. Gdy projekt na szczycie stosu zaczyna się budować, osiąga punkt, w którym cel ResolveProjectReferences jest wykonywany, standardowy cel zdefiniowany w typowych plikach celowych.
ResolveProjectReferences wywołuje zadanie MSBuild z danymi wejściowymi elementów ProjectReference w celu pobrania danych wyjściowych. Elementy ProjectReference są przekształcane na elementy lokalne, takie jak Reference. Faza wykonywania programu MSBuild dla bieżącego projektu wstrzymuje się, gdy faza wykonywania rozpoczyna przetwarzanie przywoływanego projektu (faza oceny jest wykonywana najpierw zgodnie z potrzebami). Przywołyżony projekt kompiluje się tylko po rozpoczęciu kompilowania projektu zależnego, dlatego tworzy drzewo kompilowania projektów.
Program Visual Studio umożliwia tworzenie zależności projektu w plikach rozwiązania (.sln). Zależności są określone w pliku rozwiązania i są przestrzegane tylko podczas tworzenia rozwiązania lub podczas kompilowania wewnątrz programu Visual Studio. Jeśli tworzysz pojedynczy projekt, ten typ zależności jest ignorowany. Odwołania do rozwiązań są przekształcane przez program MSBuild na elementy ProjectReference, a następnie są traktowane w ten sam sposób.
Opcja grafu
Jeśli określisz przełącznik kompilacji grafu (-graphBuild lub -graph), ProjectReference stanie się nadrzędnym pojęciem używanym przez program MSBuild. Program MSBuild przeanalizuje wszystkie projekty i skonstruuje wykres kolejności kompilacji, rzeczywisty graf zależności projektów, który następnie przechodzi w celu określenia kolejności kompilacji. Podobnie jak w przypadku celów w poszczególnych projektach, program MSBuild zapewnia, że przywołane projekty są kompilowane po projektach, od których zależą.
Równoległe wykonywanie
W przypadku korzystania z obsługi wieloprocesorowej (przełącznik-maxCpuCount lub -m) program MSBuild tworzy węzły, które są procesami MSBuild korzystającymi z dostępnych rdzeni procesora CPU. Każdy projekt jest przesyłany do dostępnego węzła. W węźle poszczególne kompilacje projektu są wykonywane szeregowo.
Zadania mogą być włączone na potrzeby wykonywania równoległego, ustawiając zmienną logiczną BuildInParallel, która jest ustawiana zgodnie z wartością właściwości $(BuildInParallel) w programie MSBuild. W przypadku zadań przeznaczonych do wykonywania równoległego, harmonogram pracy zarządza węzłami i przypisuje pracę do węzłów.
Zobacz Budowanie wielu projektów równolegle z programem MSBuild
Importy standardowe
Microsoft.Common.props i Microsoft.Common.targets są importowane przez pliki projektu .NET (jawnie lub niejawnie w projektach w stylu zestawu SDK) i znajdują się w folderze MSBuild\Current\bin w instalacji programu Visual Studio. Projekty języka C++ mają własną hierarchię importu; zobacz MSBuild Internals for C++ projects.
Plik Microsoft.Common.props ustawia domyślne wartości, które można nadpisać. Jest importowany (jawnie lub niejawnie) na początku pliku projektu. W ten sposób ustawienia projektu są wyświetlane po ustawieniach domyślnych, aby je zastąpić.
Plik Microsoft.Common.targets i pliki docelowe, które importuje, definiują standardowy proces kompilacji dla projektów platformy .NET. Udostępnia również punkty rozszerzenia, których można użyć do dostosowania kompilacji.
W implementacji Microsoft.Common.targets jest lekką otoczką, która importuje Microsoft.Common.CurrentVersion.targets. Ten plik zawiera ustawienia właściwości standardowych i definiuje rzeczywiste obiekty docelowe definiujące proces kompilacji. Element docelowy Build jest zdefiniowany w tym miejscu, ale w rzeczywistości sam jest pusty. Jednak obiekt docelowy Build zawiera atrybut DependsOnTargets, który określa poszczególne elementy docelowe, które składają się na rzeczywiste kroki kompilacji, które są BeforeBuild, CoreBuildi AfterBuild. Obiekt docelowy Build jest zdefiniowany w następujący sposób:
<PropertyGroup>
<BuildDependsOn>
BeforeBuild;
CoreBuild;
AfterBuild
</BuildDependsOn>
</PropertyGroup>
<Target
Name="Build"
Condition=" '$(_InvalidConfigurationWarning)' != 'true' "
DependsOnTargets="$(BuildDependsOn)"
Returns="@(TargetPathWithTargetPlatformMoniker)" />
BeforeBuild i AfterBuild to punkty rozszerzenia. Są one puste w pliku Microsoft.Common.CurrentVersion.targets, ale projekty mogą udostępniać własne obiekty docelowe BeforeBuild i AfterBuild z zadaniami, które należy wykonać przed lub po głównym procesie kompilacji.
AfterBuild jest uruchamiane przed obiektem docelowym no-op, Build, ponieważ AfterBuild pojawia się w atrybucie DependsOnTargets obiektu docelowego Build, ale występuje po CoreBuild.
Obiekt docelowy CoreBuild zawiera wywołania narzędzi kompilacji w następujący sposób:
<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>
W poniższej tabeli opisano te cele; niektóre cele mają zastosowanie tylko do niektórych typów projektów.
| Cel | Opis |
|---|---|
| BuildOnlySettings | Ustawienia tylko dla rzeczywistych kompilacji, a nie wtedy, gdy program MSBuild jest wywoływany podczas ładowania projektu przez program Visual Studio. |
| PrepareForBuild | Przygotuj wymagania wstępne do budowania |
| PreBuildEvent | Punkt rozszerzenia dla projektów do definiowania zadań do wykonania przed kompilacją |
| ResolveProjectReferences | Analizowanie zależności projektu i kompilowanie przywołynych projektów |
| RozwiązywanieOdwołańDoAsemblacji | Znajdź zestawy, do których odwołuje się odwołanie. |
| RozwiązywanieOdniesień | Składa się z ResolveProjectReferences i ResolveAssemblyReferences, aby znaleźć wszystkie zależności |
| Przygotuj zasoby | Przetwarzanie plików zasobów |
| ResolveKeySource | Określ klucz silnej nazwy używany do podpisywania zestawu oraz certyfikat używany do podpisywania manifestów ClickOnce. |
| Kompilować | Wywołuje kompilator |
| ExportWindowsMDFile | Wygeneruj plik WinMD z plików WinMDModule wygenerowanych przez kompilator. |
| WyrejestrowanieNiezarządzane | Usuń/wyczyść wpisy rejestru COM Interop z poprzedniej kompilacji |
| GenerujAsemblerySerializacji | Wygeneruj zestaw serializacji XML przy użyciu sgen.exe. |
| CreateSatelliteAssemblies | Utwórz jeden zestaw satelitarny dla każdej unikatowej kultury w zasobach. |
| Generowanie manifestów | Generuje ClickOnce manifesty aplikacji i wdrożenia lub manifestu natywnego. |
| PobierzŚcieżkęDocelową | Zwróć element zawierający produkt kompilacji (plik wykonywalny lub zestaw) dla tego projektu, wraz z metadanymi. |
| PrepareForRun | Skopiuj dane wyjściowe kompilacji do katalogu końcowego, jeśli zostały zmienione. |
| Rejestracja Bez Zarządzania | Ustawianie wpisów rejestru dla międzyoperacyjności COM |
| IncrementalClean | Usuń pliki utworzone w poprzedniej kompilacji, ale nie zostały utworzone w bieżącej kompilacji. Jest to konieczne, aby Clean działał w kompilacjach przyrostowych. |
| Zdarzenie po kompilacji | Punkt rozszerzenia dla projektów do definiowania zadań do uruchomienia po kompilacji |
Wiele obiektów docelowych w poprzedniej tabeli znajduje się w importach specyficznych dla języka, takich jak Microsoft.CSharp.targets. Ten plik definiuje kroki w standardowym procesie kompilacji specyficznym dla projektów .NET języka C#. Zawiera na przykład obiekt docelowy Compile, który faktycznie wywołuje kompilator języka C#.
Importowanie konfigurowalne przez użytkownika
Oprócz standardowych importów istnieje kilka importów, które można dodać, aby dostosować proces kompilacji.
- Directory.Build.props
- Directory.Build.targets
Te pliki są wczytywane przy użyciu standardowych importów dla wszystkich projektów znajdujących się w dowolnym podfolderze pod nimi. Zazwyczaj jest to na poziomie rozwiązania w celu kontrolowania wszystkich projektów w rozwiązaniu, ale może znajdować się również wyżej w systemie plików, aż do katalogu głównego dysku.
Plik Directory.Build.props jest importowany przez Microsoft.Common.props, więc zdefiniowane właściwości są dostępne w pliku projektu. Można je ponownie zdefiniować w pliku projektu, aby dostosować wartości dla poszczególnych projektów. Plik Directory.Build.targets jest odczytywany po pliku projektu. Zazwyczaj zawiera ona obiekty docelowe, ale tutaj można również zdefiniować właściwości, których nie chcesz ponownie definiować w poszczególnych projektach.
Dostosowania w pliku projektu
Program Visual Studio aktualizuje pliki projektu podczas wprowadzania zmian w Eksploratorze rozwiązań , oknie właściwości lub w właściwości projektu, ale możesz również wprowadzić własne zmiany, edytując plik projektu.
Wiele zachowań kompilacji można skonfigurować, ustawiając właściwości programu MSBuild w pliku projektu dla ustawień lokalnych dla projektu lub zgodnie z opisem w poprzedniej sekcji, tworząc plik Directory.Build.props, aby ustawić właściwości globalne dla całych folderów projektów i rozwiązań. W przypadku kompilacji ad hoc w wierszu polecenia lub skryptów można również użyć opcji /p w wierszu polecenia, aby ustawić właściwości dla określonego wywołania MSBuild. Aby uzyskać informacje o właściwościach, które można ustawić, zobacz Właściwości projektu programu MSBuild.