Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Bagaimana MSBuild benar-benar bekerja? Dalam artikel ini, Anda akan mempelajari cara MSBuild memproses file proyek Anda, baik dipanggil dari Visual Studio, atau dari baris perintah atau skrip. Mengetahui cara kerja MSBuild dapat membantu Anda mendiagnosis masalah dengan lebih baik dan menyesuaikan proses build Anda dengan lebih baik. Artikel ini menjelaskan proses build dan sebagian besar berlaku untuk semua jenis proyek.
Proses build lengkap terdiri dari pemulaan, evaluasi , dan eksekusi target dan tugas yang membentuk proyek. Selain input ini, impor eksternal menentukan detail proses build, termasuk impor standar seperti Microsoft.Common.targets dan impor yang dapat dikonfigurasikan oleh pengguna di tingkat solusi atau proyek.
perusahaan rintisan
MSBuild dapat dipanggil dari Visual Studio melalui model objek MSBuild di Microsoft.Build.dll, atau dengan memanggil executable (MSBuild.exe
atau dotnet build
) langsung di baris perintah, atau dalam skrip, seperti dalam sistem CI. Dalam kedua kasus, input yang memengaruhi proses build mencakup file proyek (atau objek proyek internal ke Visual Studio), mungkin file solusi, variabel lingkungan, dan sakelar baris perintah atau model objeknya yang setara. Selama fase startup, opsi baris perintah atau setara model objek digunakan untuk mengonfigurasi pengaturan MSBuild seperti mengonfigurasi pencatat. Properti yang diatur pada garis perintah menggunakan sakelar -property
atau -p
diatur sebagai properti global, yang menggantikan nilai apa pun yang sudah diatur dalam file proyek, meskipun file proyek dibaca kemudian.
Bagian berikutnya adalah tentang file input, seperti file solusi atau file proyek.
Solusi dan proyek
Instans MSBuild dapat terdiri dari satu proyek, atau banyak proyek sebagai bagian dari solusi. File solusi bukan file XML MSBuild, tetapi MSBuild menafsirkannya untuk mengetahui semua proyek yang diperlukan untuk dibangun untuk konfigurasi dan pengaturan platform yang diberikan. Ketika MSBuild memproses input XML ini, prosesnya disebut sebagai build solusi. Ini memiliki beberapa titik yang dapat diperluas yang memungkinkan Anda menjalankan sesuatu di setiap build solusi, tetapi karena build ini adalah eksekusi terpisah dari build proyek individual, tidak ada pengaturan properti atau definisi target dari build solusi yang relevan dengan setiap build proyek.
Anda dapat mengetahui cara memperluas build solusi di Menyesuaikan build solusi.
Build Visual Studio vs. Build MSBuild.exe
Ada beberapa perbedaan signifikan antara ketika proyek dibangun di Visual Studio vs. ketika Anda memanggil MSBuild secara langsung, baik melalui MSBuild yang dapat dieksekusi, atau saat Anda menggunakan model objek MSBuild untuk memulai build. Visual Studio mengelola urutan build proyek untuk build Visual Studio; Visual Studio hanya memanggil MSBuild di tingkat proyek individu, serta ketika itu terjadi, beberapa properti Boolean (BuildingInsideVisualStudio
, BuildProjectReferences
) diatur yang secara signifikan memengaruhi apa yang dilakukan MSBuild. Di dalam setiap proyek, eksekusi terjadi sama seperti ketika dipanggil melalui MSBuild, tetapi perbedaan muncul dengan proyek yang direferensikan. Dalam MSBuild, ketika proyek yang dirujuk diperlukan, sebuah build benar-benar dilakukan; yaitu, proses ini menjalankan tugas-tugas dan alat, serta menghasilkan output. Saat build Visual Studio menemukan proyek yang dirujuk, MSBuild hanya mengembalikan output yang diharapkan dari proyek yang dirujuk; ini memungkinkan Visual Studio mengontrol pembangunan proyek lain tersebut. Visual Studio menentukan urutan build dan panggilan ke MSBuild secara terpisah (sesuai kebutuhan), semuanya sepenuhnya di bawah kontrol Visual Studio.
Perbedaan lain muncul ketika MSBuild dipanggil dengan file solusi, MSBuild mengurai file solusi, membuat file input XML standar, mengevaluasinya, dan menjalankannya sebagai proyek. Build solusi dijalankan sebelum proyek dimulai. Saat membangun dari Visual Studio, tidak ada yang terjadi; MSBuild tidak pernah melihat file solusi. Akibatnya, penyesuaian build solusi (menggunakan sebelum.SolutionName.sln.targets dan setelah.SolutionName.sln.targets) hanya berlaku untuk build MSBuild.exe, dotnet build
, atau yang berbasis model objek, bukan build Visual Studio.
Kit Pengembangan Perangkat Lunak Proyek
Fitur SDK untuk file proyek MSBuild relatif baru. Sebelum perubahan ini, file proyek secara eksplisit mengimpor .target dan .props file yang menentukan proses build untuk jenis proyek tertentu.
Proyek .NET Core mengimpor versi .NET SDK yang sesuai dengannya. Lihat gambaran umum, .NET Core project SDK, dan referensi ke properti .
Fase evaluasi
Bagian ini membahas bagaimana file input ini diproses dan diurai untuk menghasilkan objek dalam memori yang menentukan apa yang akan dibangun.
Tujuan dari fase evaluasi adalah untuk membuat struktur objek dalam memori berdasarkan file XML input dan lingkungan lokal. Fase evaluasi terdiri dari enam tahap yang memproses file input seperti file XML proyek atau file XML yang diimpor, umumnya dinamai sebagai file .props atau .targets, tergantung pada apakah mereka terutama mengatur properti atau menentukan target build. Setiap langkah membentuk bagian dari objek yang disimpan di dalam memori yang kemudian digunakan dalam fase eksekusi untuk membangun proyek, tetapi tidak ada tindakan pembangunan yang sebenarnya terjadi selama fase evaluasi. Dalam setiap pass, elemen diproses dalam urutan munculnya elemen tersebut.
Langkah-langkah dalam fase evaluasi adalah sebagai berikut:
- Mengevaluasi variabel lingkungan
- Mengevaluasi impor dan karakteristik
- Mengevaluasi definisi dari item
- Mengevaluasi barang
- Mengevaluasi elemen UsingTask
- Mengevaluasi target
Impor dan properti dievaluasi dalam siklus yang sama sesuai urutan kemunculan, seperti impor diperluas di tempat. Dengan demikian, pengaturan properti dalam file yang diimpor sebelumnya tersedia dalam file yang diimpor nanti.
Urutan pass ini memiliki implikasi yang signifikan dan penting untuk diketahui saat menyesuaikan file proyek. Lihat Urutan evaluasi properti dan item.
Mengevaluasi variabel lingkungan
Dalam fase ini, variabel lingkungan digunakan untuk mengatur properti yang setara. Misalnya, variabel lingkungan PATH tersedia sebagai properti $(PATH)
. Saat dijalankan dari baris perintah atau skrip, lingkungan perintah digunakan seperti biasa, dan saat dijalankan dari Visual Studio, lingkungan berlaku saat Visual Studio diluncurkan digunakan.
Evaluasi impor dan sifat
Dalam fase ini, seluruh XML input dibaca, termasuk file proyek dan seluruh rantai impor. MSBuild membuat struktur XML dalam memori yang mewakili XML proyek dan semua file yang diimpor. Saat ini, properti yang tidak berada dalam target dievaluasi dan ditetapkan.
Sebagai konsekuensi dari MSBuild membaca semua file input XML di awal prosesnya, setiap perubahan pada input tersebut selama proses build tidak memengaruhi build saat ini.
Properti di luar target apa pun ditangani secara berbeda dari properti dalam target. Dalam fase ini, hanya properti yang ditentukan di luar target apa pun yang dievaluasi.
Karena properti diproses secara berurutan dalam tahap pemrosesan properti, properti pada setiap titik dalam masukan dapat mengakses nilai properti yang muncul sebelumnya dalam masukan, namun tidak untuk properti yang muncul kemudian.
Karena properti diproses sebelum item dievaluasi, Anda tidak dapat mengakses nilai item apa pun pada tahap manapun dari pemrosesan properti.
Mengevaluasi definisi item bisa
Pada tahap ini, definisi item ditafsirkan dan representasi dalam memori dari definisi ini dibuat.
Evaluasi item
Item yang ditentukan di dalam target ditangani secara berbeda dari item di luar target apa pun. Dalam fase ini, item yang berada di luar setiap target beserta metadata terkaitnya diproses. Metadata yang ditentukan oleh definisi item akan digantikan oleh metadata yang diterapkan langsung pada item. Karena item diproses dalam urutan yang muncul, Anda dapat mereferensikan item yang telah ditentukan sebelumnya, tetapi bukan item yang muncul nanti. Karena tahap item terjadi setelah tahap properti, item dapat mengakses properti apa pun jika ditentukan di luar target mana pun, terlepas dari apakah definisi properti muncul kemudian.
Mengevaluasi elemen UsingTask
Dalam fase ini, elemen UsingTask dibaca, dan tugas dinyatakan untuk digunakan nanti selama fase eksekusi.
Mengevaluasi target
Dalam fase ini, semua struktur objek target dibuat dalam memori, sebagai persiapan untuk eksekusi. Tidak ada eksekusi aktual yang terjadi.
Fase eksekusi
Dalam fase eksekusi, target disusun dan dijalankan, serta semua tugas dijalankan. Tetapi pertama-tama, properti dan item yang ditentukan dalam target dievaluasi bersama-sama dalam satu fase dalam urutan munculnya. Urutan pemrosesan sangat berbeda dari bagaimana properti dan item yang tidak berada dalam target diproses: semua properti terlebih dahulu, lalu semua item, dalam pass terpisah. Perubahan pada properti dan item dalam target dapat diamati setelah modifikasinya dilakukan pada target tersebut.
Urutan pembangunan target
Dalam satu proyek, target dijalankan satu per satu. Masalah pusat adalah cara menentukan urutan apa untuk membangun semuanya sehingga dependensi digunakan untuk membangun target dalam urutan yang tepat.
Urutan build target ditentukan oleh penggunaan atribut BeforeTargets
, DependsOnTargets
, dan AfterTargets
pada setiap target. Urutan target selanjutnya dapat dipengaruhi selama eksekusi target sebelumnya jika target sebelumnya memodifikasi properti yang dirujuk dalam atribut ini.
Aturan untuk urutan pembangunan dijelaskan dalam Menentukan urutan pembangunan target. Proses ini ditentukan oleh struktur tumpukan yang berisi target yang akan dibangun. Target di bagian atas proses ini mulai dieksekusi, dan jika tergantung pada hal lain, maka target tersebut didorong ke bagian atas tumpukan, dan mulai dieksekusi. Ketika ada target yang tidak memiliki dependensi, target dieksekusi hingga selesai dan target induknya dapat dilanjutkan.
Referensi Proyek
Ada dua jalur kode yang dapat diambil MSBuild, yang normal, dijelaskan di sini, dan opsi grafik yang dijelaskan di bagian berikutnya.
Proyek individual menentukan ketergantungannya pada proyek lain melalui item ProjectReference
. Ketika sebuah proyek yang berada di puncak tumpukan mulai dikerjakan, proyek tersebut mencapai titik di mana target ResolveProjectReferences
dieksekusi, sebuah target standar yang ditentukan dalam berkas target umum.
ResolveProjectReferences
memanggil tugas MSBuild dengan input item ProjectReference
untuk mendapatkan output. Item ProjectReference
diubah menjadi item lokal seperti Reference
. Fase eksekusi MSBuild untuk proyek saat ini berhenti sementara fase eksekusi mulai memproses proyek yang direferensikan (fase evaluasi dilakukan terlebih dahulu sesuai kebutuhan). Proyek yang dirujuk hanya dibangun setelah Anda mulai membangun proyek dependen, sehingga ini membuat pohon bangunan proyek.
Visual Studio memungkinkan pembuatan dependensi proyek dalam file solusi (.sln). Dependensi ditentukan dalam file solusi dan hanya dihormati saat membangun solusi, atau saat membangun di dalam Visual Studio. Jika Anda membangun satu proyek, jenis dependensi ini diabaikan. Referensi solusi diubah oleh MSBuild menjadi item ProjectReference
dan setelah itu diperlakukan dengan cara yang sama.
Opsi Grafik
Jika Anda menentukan pengalih build grafik (-graphBuild
atau -graph
), ProjectReference
menjadi konsep utama yang digunakan oleh MSBuild. MSBuild akan mengurai semua proyek dan membangun grafik urutan pembuatan, grafik ketergantungan proyek yang aktual, yang kemudian ditelusuri untuk menentukan urutan pembuatan. Seperti halnya target dalam proyek individual, MSBuild memastikan bahwa proyek yang dirujuk dibangun setelah proyek yang mereka andalkan.
Pelaksanaan paralel
Jika menggunakan dukungan multiprosesor (saklar-maxCpuCount
atau -m
), MSBuild membuat node, yang merupakan proses MSBuild yang menggunakan inti CPU yang tersedia. Setiap proyek dikirimkan ke simpul yang tersedia. Dalam simpul, build proyek individual dijalankan secara serial.
Tugas dapat diaktifkan untuk eksekusi paralel dengan mengatur variabel boolean BuildInParallel, yang diatur sesuai dengan nilai properti $(BuildInParallel)
di MSBuild. Untuk tugas yang memungkinkan eksekusi paralel, penjadwal kerja mengelola simpul dan menugaskan pekerjaan pada simpul.
Lihat Membangun beberapa proyek secara paralel dengan MSBuild
Impor standar
Microsoft.Common.props dan Microsoft.Common.targets diimpor oleh file proyek .NET (secara eksplisit atau implisit dalam proyek gaya SDK) dan terletak di folder MSBuild\Current\bin dalam penginstalan Visual Studio. Proyek C++ memiliki hierarki impor mereka sendiri; lihat MSBuild Internals untuk proyek C++.
Microsoft.Common.props menetapkan pengaturan default yang dapat Anda ubah. Ini diimpor (secara eksplisit atau implisit) di awal file proyek. Dengan begitu, pengaturan proyek Anda muncul setelah pengaturan bawaan, agar dapat menggantikannya.
File Microsoft.Common.targets dan file target yang diimpornya menentukan proses build standar untuk proyek .NET. Ini juga menyediakan titik ekstensi yang dapat Anda gunakan untuk menyesuaikan build.
Dalam pelaksanaannya, Microsoft.Common.targets adalah pembungkus tipis yang mengimpor Microsoft.Common.CurrentVersion.targets. File ini berisi pengaturan untuk properti standar, dan menentukan target aktual yang menentukan proses build. Target Build
didefinisikan di sini, tetapi sebenarnya kosong. Namun, target Build
berisi atribut DependsOnTargets
yang menentukan target individu yang membentuk langkah-langkah build aktual, yaitu BeforeBuild
, CoreBuild
, dan AfterBuild
. Target Build
didefinisikan sebagai berikut:
<PropertyGroup>
<BuildDependsOn>
BeforeBuild;
CoreBuild;
AfterBuild
</BuildDependsOn>
</PropertyGroup>
<Target
Name="Build"
Condition=" '$(_InvalidConfigurationWarning)' != 'true' "
DependsOnTargets="$(BuildDependsOn)"
Returns="@(TargetPathWithTargetPlatformMoniker)" />
BeforeBuild
dan AfterBuild
adalah titik ekstensi. Target tersebut kosong dalam file Microsoft.Common.CurrentVersion.targets, tetapi proyek dapat menyediakan target BeforeBuild
dan AfterBuild
mereka sendiri dengan tugas yang perlu dilakukan sebelum atau sesudah proses build utama.
AfterBuild
dijalankan sebelum target no-op, Build
, karena AfterBuild
muncul di atribut DependsOnTargets
pada target Build
, tetapi terjadi setelah CoreBuild
.
Target CoreBuild
berisi panggilan ke alat build, sebagai berikut:
<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>
Tabel berikut ini menjelaskan target ini; beberapa target hanya berlaku untuk jenis proyek tertentu.
Target | Deskripsi |
---|---|
BuildOnlySettings | Pengaturan untuk build sebenarnya saja, bukan untuk saat MSBuild dijalankan ketika proyek dimuat oleh Visual Studio. |
PrepareForBuild | Siapkan prasyarat untuk membangun |
PreBuildEvent | Titik perpanjangan proyek untuk menentukan tugas yang akan dijalankan sebelum pembangunan |
ResolveProjectReferences | Menganalisis dependensi proyek dan membangun proyek yang dirujuk |
MenyelesaikanReferensiRakitan | Temukan rakitan yang dirujuk. |
ResolveReferences | Terdiri dari ResolveProjectReferences dan ResolveAssemblyReferences untuk menemukan semua dependensi |
PersiapkanSumberDaya | Memproses file sumber daya |
ResolveKeySource | Selesaikan kunci nama kuat yang digunakan untuk menandatangani assembly dan sertifikat yang digunakan untuk menandatangani manifes ClickOnce. |
Mengkompilasi | Memanggil pengkompilasi |
ExportWindowsMDFile | Buat file WinMD dari file WinMDModule yang dihasilkan oleh pengkompilasi. |
Pencabutan Pendaftaran yang Tidak Dikelola | Hapus/bersihkan entri registri Interop COM dari build sebelumnya |
Membuat Majelis Serialisasi | Hasilkan rakitan serialisasi XML menggunakan sgen.exe. |
CreateSatelliteAssemblies | Buat satu rakitan satelit untuk setiap budaya unik dalam sumber daya. |
Hasilkan Manifes | Menghasilkan aplikasi ClickOnce dan manifes penyebaran atau manifes asli. |
DapatkanJalurTujuan | Mengembalikan item yang berisi produk hasil kompilasi (dapat dieksekusi atau rakitan) untuk proyek ini, beserta metadata. |
PrepareForRun | Salin output build ke direktori akhir jika telah berubah. |
Registrasi Tidak Terkelola | Mengatur entri registri untuk Interop COM |
IncrementalClean | Hapus file yang diproduksi dalam build sebelumnya tetapi tidak diproduksi dalam build saat ini. Hal ini diperlukan untuk membuat Clean bekerja dalam build bertahap. |
Peristiwa Pasca-Pembangunan | Titik ekstensi bagi proyek untuk menentukan tugas yang akan dijalankan setelah proses build |
Banyak target dalam tabel sebelumnya ditemukan dalam impor khusus bahasa, seperti Microsoft.CSharp.targets. File ini menentukan langkah-langkah dalam proses build standar khusus untuk proyek C# .NET. Misalnya, berisi target Compile
yang benar-benar memanggil pengkompilasi C#.
Impor yang dapat dikonfigurasi pengguna
Selain impor standar, ada beberapa impor yang dapat Anda tambahkan untuk menyesuaikan proses build.
- Directory.Build.props
- Directory.Build.targets
File-file ini dimasukkan sebagai impor standar untuk proyek apapun di subfolder manapun di bawahnya. Biasanya, ini berada pada tingkat solusi untuk mengatur semua proyek dalam solusi, tetapi juga bisa lebih tinggi di sistem file, sampai ke direktori akar drive.
File Directory.Build.props diimpor oleh Microsoft.Common.props, sehingga properti yang ditentukan di dalamnya tersedia dalam file proyek. Mereka dapat ditentukan ulang dalam file proyek untuk menyesuaikan nilai berdasarkan per proyek. File Directory.Build.targets dibaca setelah file proyek. Biasanya berisi target, tetapi di sini Anda juga dapat menentukan properti yang tidak ingin anda tentukan ulang masing-masing proyek.
Kustomisasi dalam file proyek
Visual Studio memperbarui file proyek saat Anda membuat perubahan di Penjelajah Solusi, jendela Properti, atau di Properti Proyek, tetapi Anda juga dapat membuat perubahan Anda sendiri dengan langsung mengedit file proyek.
Banyak perilaku build dapat dikonfigurasi dengan mengatur properti MSBuild, baik dalam file proyek untuk pengaturan lokal ke proyek, atau seperti yang disebutkan di bagian sebelumnya, dengan membuat Directory.Build.props file untuk mengatur properti secara global untuk seluruh folder proyek dan solusi. Untuk build ad hoc pada baris perintah, atau skrip, Anda juga dapat menggunakan opsi /p
pada baris perintah untuk mengatur properti untuk pemanggilan MSBuild tertentu. Lihat Common MSBuild project properties untuk informasi tentang properti yang dapat Anda atur.