Derleme İşlemini Anlama

tarafından Jason Lee

Bu konu, kurumsal ölçekli derleme ve dağıtım işlemine ilişkin bir kılavuz sağlar. Bu konuda açıklanan yaklaşım, işlemin her yönü üzerinde ayrıntılı denetim sağlamak için özel Microsoft Build Engine (MSBuild) proje dosyalarını kullanır. Proje dosyalarında, Internet Information Services (IIS) Web Dağıtım Aracı (MSDeploy.exe) ve veritabanı dağıtım yardımcı programı VSDBCMD.exe gibi dağıtım yardımcı programlarını çalıştırmak için özel MSBuild hedefleri kullanılır.

Not

Proje Dosyasını Anlama başlıklı önceki konu başlığında, BIR MSBuild proje dosyasının temel bileşenleri açıklanmış ve birden çok hedef ortam için dağıtımı desteklemek için bölünmüş proje dosyaları kavramı tanıtılmaktadır. Bu kavramlar hakkında bilginiz yoksa, bu konuyu incelemeden önce Proje Dosyasını Anlama konusunu gözden geçirmeniz gerekir.

Bu konu, Fabrikam, Inc. adlı kurgusal bir şirketin kurumsal dağıtım gereksinimlerini temel alan bir dizi öğreticinin bir bölümünü oluşturur. Bu öğretici serisi, ASP.NET MVC 3 uygulaması, Windows Communication Foundation (WCF) hizmeti ve veritabanı projesi dahil olmak üzere gerçekçi bir karmaşıklık düzeyine sahip bir web uygulamasını temsil etmek için örnek bir çözüm (Contact Manager çözümü) kullanır.

Bu öğreticilerin merkezinde yer alan dağıtım yöntemi, derleme işleminin iki proje dosyası tarafından denetlendiği Proje Dosyasını Anlama bölümünde açıklanan bölünmüş proje dosyası yaklaşımını temel alır: biri her hedef ortama uygulanan derleme yönergelerini, diğeri de ortama özgü derleme ve dağıtım ayarlarını içerir. Derleme zamanında, ortama özgü proje dosyası, tam bir derleme yönergeleri kümesi oluşturmak için ortama özgü belirsiz proje dosyasıyla birleştirilir.

Derleme ve Dağıtıma Genel Bakış

Contact Manager çözümünde üç dosya derleme ve dağıtım işlemini denetler:

  • Evrensel proje dosyası (Publish.proj). Bu, hedef ortamlar arasında değişmeyen derleme ve dağıtım yönergelerini içerir.
  • Ortama özgü bir proje dosyası (Env-Dev.proj). Bu, belirli bir hedef ortama özgü derleme ve dağıtım ayarlarını içerir. Örneğin, env-Dev.proj dosyasını kullanarak bir geliştirici veya test ortamı için ayarlar sağlayabilir ve hazırlama ortamı için ayarlar sağlamak üzere Env-Stage.proj adlı alternatif bir dosya oluşturabilirsiniz.
  • Bir komut dosyası (Publish-Dev.cmd). Bu, yürütmek istediğiniz proje dosyalarını belirten bir MSBuild.exe komutu içerir. Her hedef ortam için, her dosyanın ortama özgü farklı bir proje dosyasını belirten bir MSBuild.exe komutu içerdiği bir komut dosyası oluşturabilirsiniz. Bu, geliştiricinin yalnızca uygun komut dosyasını çalıştırarak farklı ortamlara dağıtım yapmasını sağlar.

Örnek çözümde, bu üç dosyayı Çözümü yayımla klasöründe bulabilirsiniz.

Örnek çözümde Çözümü yayımla klasöründe üç dosya bulabilirsiniz.

Bu dosyalara daha ayrıntılı bir şekilde bakmadan önce, bu yaklaşımı kullandığınızda genel derleme işleminin nasıl çalıştığına göz atalım. Yüksek düzeyde derleme ve dağıtım işlemi şöyle görünür:

Derleme ve dağıtım işleminin üst düzeyde nasıl göründüğü.

İlk olarak, biri evrensel derleme ve dağıtım yönergelerini, diğeri de ortama özgü ayarları içeren iki proje dosyasının tek bir proje dosyasında birleştirilmesi gerçekleşir. MSBuild daha sonra proje dosyasındaki yönergelerle çalışır. Her proje için proje dosyasını kullanarak çözümdeki projelerin her birini oluşturur. Ardından web içeriğinizi ve veritabanlarınızı hedef ortama dağıtmak için Web Dağıtımı (MSDeploy.exe) ve VSDBCMD yardımcı programı gibi diğer araçlara çağrıda bulunur.

Baştan sona derleme ve dağıtım işlemi şu görevleri gerçekleştirir:

  1. Yeni bir derleme hazırlığında çıkış dizininin içeriğini siler.

  2. Çözümdeki her projeyi oluşturur:

    1. Bu durumda bir ASP.NET MVC web uygulaması ve WCF web hizmeti olan web projeleri için derleme işlemi her proje için bir web dağıtım paketi oluşturur.
    2. Veritabanı projeleri için, derleme işlemi her proje için bir dağıtım bildirimi (.deploymanifest dosyası) oluşturur.
  3. .deploymanifest dosyasıyla birlikte proje dosyalarındaki çeşitli özellikleri (hedef bağlantı dizesi ve veritabanı adı) kullanarak çözümdeki her veritabanı projesini dağıtmak için VSDBCMD.exe yardımcı programını kullanır.

  4. Dağıtım işlemini denetlemek için proje dosyalarındaki çeşitli özellikleri kullanarak çözümdeki her web projesini dağıtmak için MSDeploy.exe yardımcı programını kullanır.

Bu işlemi daha ayrıntılı bir şekilde izlemek için örnek çözümü kullanabilirsiniz.

Not

Kendi sunucu ortamlarınız için ortama özgü proje dosyalarını özelleştirme yönergeleri için bkz. Hedef Ortam için Dağıtım Özelliklerini Yapılandırma.

Derleme ve Dağıtım İşlemini Çağırma

Contact Manager çözümünü bir geliştirici test ortamına dağıtmak için geliştirici Publish-Dev.cmd komut dosyasını çalıştırır. Bu, yürütülecek proje dosyası olarak Publish.proj ve parametre değeri olarak Env-Dev.proj belirterek MSBuild.exe çağırır.

msbuild.exe Publish.proj /fl /p:TargetEnvPropsFile=EnvConfig\Env-Dev.proj

Not

/fl anahtarı (/fileLogger kısaltması) derleme çıkışını geçerli dizindeki msbuild.log adlı bir dosyaya kaydeder. Daha fazla bilgi için bkz. MSBuild Komut Satırı Başvurusu.

Bu noktada MSBuild çalışmaya başlar, Publish.proj dosyasını yükler ve içindeki yönergeleri işlemeye başlar. İlk yönerge MSBuild'e TargetEnvPropsFile parametresinin belirttiği proje dosyasını içeri aktarmasını söyler.

<Import Project="$(TargetEnvPropsFile)" />

TargetEnvPropsFile parametresi Env-Dev.proj dosyasını belirtir, bu nedenle MSBuild Env-Dev.proj dosyasının içeriğini Publish.proj dosyasıyla birleştirir.

MSBuild'in birleştirilmiş proje dosyasında karşılaştığı sonraki öğeler özellik gruplarıdır. Özellikler, dosyada göründükleri sırayla işlenir. MSBuild, belirtilen koşulların karşılanması koşuluyla her özellik için bir anahtar-değer çifti oluşturur. Daha sonra dosyada tanımlanan özellikler, daha önce dosyada tanımlanan aynı ada sahip özelliklerin üzerine yazar. Örneğin OutputRoot özelliklerini göz önünde bulundurun.

<OutputRoot Condition=" '$(OutputRoot)'=='' ">..\Publish\Out\</OutputRoot>
<OutputRoot Condition=" '$(BuildingInTeamBuild)'=='true' ">$(OutDir)</OutputRoot>

MSBuild ilk OutputRoot öğesini işlediğinde, benzer adlandırılmış bir parametre sağlanmadığında OutputRoot özelliğinin değerini olarak ayarlar. \Publish\Out. İkinci OutputRoot öğesiyle karşılaştığında koşul true olarak değerlendirilirse OutputRoot özelliğinin değerini OutDir parametresinin değeriyle değiştirir.

MSBuild'in karşılaştığı bir sonraki öğe, ProjectsToBuild adlı bir öğe içeren tek bir öğe grubudur.

<ItemGroup>
   <ProjectsToBuild Include="$(SourceRoot)ContactManager-WCF.sln"/>
</ItemGroup>

MSBuild, ProjectsToBuild adlı bir öğe listesi oluşturarak bu yönergeyi işler. Bu durumda, öğe listesi çözüm dosyasının yolu ve dosya adı olmak üzere tek bir değer içerir.

Bu noktada, kalan öğeler hedeflerdir. Hedefler özelliklerden ve öğelerden farklı işlenir; temelde, kullanıcı tarafından açıkça belirtilmedikçe veya proje dosyasındaki başka bir yapı tarafından çağrılmadıkları sürece hedefler işlenmez. Açılan Project etiketinin defaultTargets özniteliği içerdiğini hatırlayın.

<Project ToolsVersion="4.0" 
         DefaultTargets="FullPublish" 
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

Bu, MSBuild.exe çağrıldığında hedefler belirtilmezse MSBuild'e FullPublish hedefini çağırmasını sağlar. FullPublish hedefi herhangi bir görev içermez; bunun yerine yalnızca bağımlılıkların listesini belirtir.

<PropertyGroup>   
  <FullPublishDependsOn>
     Clean;
     BuildProjects;      
     GatherPackagesForPublishing;
     PublishDbPackages;
     PublishWebPackages;
  </FullPublishDependsOn>
</PropertyGroup>
<Target Name="FullPublish" DependsOnTargets="$(FullPublishDependsOn)" />

Bu bağımlılık, MSBuild'e FullPublish hedefini yürütmek için bu hedef listesini sağlanan sırayla çağırması gerektiğini söyler:

  1. Clean hedefini çağırması gerekir.
  2. BuildProjects hedefini çağırması gerekir.
  3. GatherPackagesForPublishing hedefini çağırması gerekir.
  4. PublishDbPackages hedefini çağırması gerekir.
  5. PublishWebPackages hedefini çağırması gerekir.

Temiz Hedef

Temiz hedef, yeni bir derlemeye hazırlık olarak çıkış dizinini ve tüm içeriğini temel olarak siler.

<Target Name="Clean" Condition=" '$(BuildingInTeamBuild)'!='true' ">
  <Message Text="Cleaning up the output directory [$(OutputRoot)]"/>
  <ItemGroup>
     <_FilesToDelete Include="$(OutputRoot)**\*"/>
  </ItemGroup>
  <Delete Files="@(_FilesToDelete)"/>
  <RemoveDir Directories="$(OutputRoot)"/>
</Target>

Hedefin bir ItemGroup öğesi içerdiğine dikkat edin. Target öğesi içinde özellikler veya öğeler tanımladığınızda dinamik özellikler ve öğeler oluşturursunuz. Başka bir deyişle, özellikler veya öğeler hedef yürütülene kadar işlenmez. Derleme işlemi başlayana kadar çıkış dizini mevcut olmayabilir veya herhangi bir dosya içermeyebilir, bu nedenle _FilesToDelete listesini statik öğe olarak oluşturamazsınız; yürütmenin devam edene kadar beklemeniz gerekir. Bu nedenle, listeyi hedef içinde dinamik bir öğe olarak oluşturursunuz.

Not

Bu durumda, temiz hedef yürütülecek ilk hedef olduğundan dinamik öğe grubu kullanmanıza gerek yoktur. Ancak, bir noktada hedefleri farklı bir sırayla yürütmek isteyebileceğiniz için bu tür senaryolarda dinamik özellikleri ve öğeleri kullanmak iyi bir uygulamadır.
Ayrıca, hiçbir zaman kullanılmayacak öğeleri bildirmekten kaçınmayı da hedeflemeniz gerekir. Yalnızca belirli bir hedef tarafından kullanılacak öğeleriniz varsa, derleme işlemindeki gereksiz yükleri kaldırmak için bunları hedefe yerleştirmeyi göz önünde bulundurun.

Dinamik öğeler bir yana, Temizleme hedefi oldukça basittir ve aşağıdakiler için yerleşik Message, Delete ve RemoveDir görevlerini kullanır:

  1. Günlükçüye bir ileti gönderin.
  2. Silinecek dosyaların listesini oluşturun.
  3. Dosyaları silin.
  4. Çıkış dizinini kaldırın.

BuildProjects Hedefi

BuildProjects hedefi temel olarak örnek çözümdeki tüm projeleri oluşturur.

<Target Name="BuildProjects" Condition=" '$(BuildingInTeamBuild)'!='true' ">
   <MSBuild Projects="@(ProjectsToBuild)"
            Properties="OutDir=$(OutputRoot);
                        Configuration=$(Configuration);
                        DeployOnBuild=true;
                        DeployTarget=Package"
            Targets="Build" />
  </Target>

Bu hedef, görevlerin ve hedeflerin özelliklere ve öğelere nasıl başvurdığını göstermek için proje dosyasını anlama başlıklı önceki konu başlığında ayrıntılı olarak açıklanmıştır. Bu noktada, asıl olarak MSBuild göreviyle ilgileniyorsunuz. Bu görevi birden çok proje oluşturmak için kullanabilirsiniz. Görev yeni bir MSBuild.exe örneği oluşturmaz; her projeyi derlemek için geçerli çalışan örneği kullanır. Bu örnekteki önemli noktalar dağıtım özellikleridir:

  • DeployOnBuild özelliği, MSBuild'e her projenin derlemesi tamamlandığında proje ayarlarında dağıtım yönergelerini çalıştırmasını emreder.
  • DeployTarget özelliği, proje oluşturulduktan sonra çağırmak istediğiniz hedefi tanımlar. Bu durumda , Paket hedefi proje çıkışını dağıtılabilir bir web paketinde oluşturur.

Not

Paket hedefi, MSBuild ile Web Dağıtımı arasında tümleştirme sağlayan Web Yayımlama İşlem Hattı'nı (WPP) çağırır. WPP'nin sağladığı yerleşik hedeflere göz atmak isterseniz, %PROGRAMFILES(x86)%\MSBuild\Microsoft\VisualStudio\v10.0\Web klasöründeki Microsoft.Web.Publishing.targets dosyasını gözden geçirin.

GatherPackagesForPublishing Hedefi

GatherPackagesForPublishing hedefini incelerseniz aslında herhangi bir görev içermediğini fark edersiniz. Bunun yerine, üç dinamik öğe tanımlayan tek bir öğe grubu içerir.

<Target Name="GatherPackagesForPublishing">
   <ItemGroup>
      <PublishPackages 
         Include="$(_ContactManagerDest)ContactManager.Mvc.deploy.cmd">
         <WebPackage>true</WebPackage>
         <!-- More item metadata -->  
      </PublishPackages>
      <PublishPackages 
         Include="$(_ContactManagerSvcDest)ContactManager.Service.deploy.cmd">
         <WebPackage>true</WebPackage>
         <!-- More item metadata -->
      </PublishPackages>
      <DbPublishPackages Include="$(_DbDeployManifestPath)">
         <DbPackage>true</DbPackage>
         <!-- More item metadata -->
      </DbPublishPackages>
   </ItemGroup>
</Target>

Bu öğeler , BuildProjects hedefi yürütülürken oluşturulan dağıtım paketlerine başvurur. Öğelerin başvurdığı dosyalar BuildProjects hedefi yürütülene kadar mevcut olmadığından, bu öğeleri proje dosyasında statik olarak tanımlayamadınız. Bunun yerine, öğeler BuildProjects hedefi yürütülene kadar çağrılmayan bir hedef içinde dinamik olarak tanımlanmalıdır.

Öğeler bu hedef içinde kullanılmaz; bu hedef yalnızca öğeleri ve her öğe değeriyle ilişkili meta verileri oluşturur. Bu öğeler işlendikten sonra PublishPackages öğesi iki değer içerir: ContactManager.Mvc.deploy.cmd dosyasının yolu ve ContactManager.Service.deploy.cmd dosyasının yolu. Web Dağıtımı bu dosyaları her proje için web paketinin bir parçası olarak oluşturur ve bunlar paketleri dağıtmak için hedef sunucuda çağırmanız gereken dosyalardır. Bu dosyalardan birini açarsanız, temel olarak derlemeye özgü çeşitli parametre değerlerine sahip bir MSDeploy.exe komutu görürsünüz.

DbPublishPackages öğesi, ContactManager.Database.deploymanifest dosyasının yolu olan tek bir değer içerir.

Not

Bir veritabanı projesi oluşturduğunuzda bir .deploymanifest dosyası oluşturulur ve MSBuild proje dosyasıyla aynı şemayı kullanır. Veritabanı şemasının konumu (.dbschema) ve dağıtım öncesi ve dağıtım sonrası betiklerinin ayrıntıları dahil olmak üzere bir veritabanını dağıtmak için gereken tüm bilgileri içerir. Daha fazla bilgi için bkz. Veritabanı Derlemesine ve Dağıtımına Genel Bakış.

Web Uygulaması Projeleri Oluşturma ve Paketleme ve Veritabanı Projelerini Dağıtma bölümünde dağıtım paketlerinin ve veritabanı dağıtım bildirimlerinin nasıl oluşturulduğu ve kullanıldığı hakkında daha fazla bilgi edineceksiniz.

PublishDbPackages Hedefi

Kısaca konuşmak gerekirse PublishDbPackages hedefi, ContactManager veritabanını hedef ortama dağıtmak için VSDBCMD yardımcı programını çağırır. Veritabanı dağıtımını yapılandırmak için çok sayıda karar ve nüans gerekir. Veritabanı Projelerini Dağıtma ve Birden Çok Ortam için Veritabanı Dağıtımlarını Özelleştirme makalesinde bu konuda daha fazla bilgi edineceksiniz. Bu konu başlığında, bu hedefin gerçekte nasıl işlev göreceğine odaklanacağız.

İlk olarak, açma etiketinin outputs özniteliği içerdiğine dikkat edin.

<Target Name="PublishDbPackages" Outputs="%(DbPublishPackages.Identity)">

Bu, hedef toplu işlem örneğidir. MSBuild proje dosyalarında toplu işlem, koleksiyonlar üzerinde yinelemeye yönelik bir tekniktir. Outputs özniteliğinin değeri olan "%(DbPublishPackages.Identity)", DbPublishPackages öğe listesinin Identity meta veri özelliğini ifade eder. Outputs=%(ItemList.ItemMetadataName)bu gösterimi şu şekilde çevrilir:

  • DbPublishPackages içindeki öğeleri aynı Identity meta veri değerini içeren öğe gruplarına bölün.
  • Hedefi toplu iş başına bir kez yürütür.

Not

Kimlik , oluşturma işlemindeki her öğeye atanan yerleşik meta veri değerlerinden biridir. Item öğesindeki Include özniteliğinin değerine, başka bir deyişle öğenin yolu ve dosya adına başvurur.

Bu durumda, hiçbir zaman aynı yol ve dosya adına sahip birden fazla öğe olmaması gerektiğinden, temelde tek bir toplu iş boyutlarıyla çalışıyoruz. Hedef her veritabanı paketi için bir kez yürütülür.

uygun anahtarlarla bir VSDBCMD komutu oluşturan _Cmd özelliğinde benzer bir gösterimi görebilirsiniz.

<_Cmd>"$(VsdbCmdExe)" 
   /a:Deploy 
   /cs:"%(DbPublishPackages.DatabaseConnectionString)" 
   /p:TargetDatabase=%(DbPublishPackages.TargetDatabase)             
   /manifest:"%(DbPublishPackages.FullPath)" 
   /script:"$(_CmDbScriptPath)" 
   $(_DbDeployOrScript)
</_Cmd>

Bu durumda, %(DbPublishPackages.DatabaseConnectionString), %(DbPublishPackages.TargetDatabase)ve %(DbPublishPackages.FullPath) DbPublishPackages öğe koleksiyonunun meta veri değerlerine başvurur . _Cmd özelliği, komutu çağıran Exec görevi tarafından kullanılır.

<Exec Command="$(_Cmd)"/>

Bu gösterimin sonucunda , Exec görevi DatabaseConnectionString, TargetDatabase ve FullPath meta veri değerlerinin benzersiz birleşimlerini temel alan toplu işlemler oluşturur ve görev her toplu işlem için bir kez yürütülür. Bu, görev toplu işlemi örneğidir. Ancak, hedef düzeyinde toplu işlem zaten öğe koleksiyonumuzu tek öğeli toplu işlemlere böldüğünden, Exec görevi hedefin her yinelemesi için bir kez ve yalnızca bir kez çalışır. Başka bir deyişle, bu görev çözümdeki her veritabanı paketi için VSDBCMD yardımcı programını bir kez çağırır.

Not

Hedef ve görev toplu işlemi hakkında daha fazla bilgi için bkz. MSBuild Toplu İşlem, Hedef Toplu İşlemde Öğe Meta Verileri ve Görev Toplu İşleminde Öğe Meta Verileri.

PublishWebPackages Hedefi

Bu noktaya kadar, örnek çözümdeki her proje için bir web dağıtım paketi oluşturan BuildProjects hedefini çağırmış oldunuz. Her pakete eşlik eden, paketi hedef ortama dağıtmak için gereken MSDeploy.exe komutlarını içeren bir deploy.cmd dosyası ve hedef ortamın gerekli ayrıntılarını belirten bir SetParameters.xml dosyasıdır. Ayrıca, ilgilendiğiniz deploy.cmd dosyalarını içeren bir öğe koleksiyonu oluşturan GatherPackagesForPublishing hedefini de çağırmıştınız. Temel olarak PublishWebPackages hedefi şu işlevleri gerçekleştirir:

  • XmlPoke görevini kullanarak her paket için SetParameters.xml dosyasını hedef ortamın doğru ayrıntılarını içerecek şekilde düzenler.
  • Uygun anahtarları kullanarak her paket için deploy.cmd dosyasını çağırır.

PublishDbPackages hedefi gibi PublishWebPackages hedefi de hedefin her web paketi için bir kez yürütülmesini sağlamak üzere hedef toplu işlemi kullanır.

<Target Name="PublishWebPackages" Outputs="%(PublishPackages.Identity)">

Hedefte, her web paketi için deploy.cmd dosyasını çalıştırmak için Exec görevi kullanılır.

<PropertyGroup>
   <_Cmd>
      %(PublishPackages.FullPath) 
      $(_WhatifSwitch) 
      /M:$(MSDeployComputerName) 
      %(PublishPackages.AdditionalMSDeployParameters)
   </_Cmd>
</PropertyGroup>
<Exec Command="$(_Cmd)"/>

Web paketlerinin dağıtımını yapılandırma hakkında daha fazla bilgi için bkz. Web Uygulaması Projeleri Oluşturma ve Paketleme.

Sonuç

Bu konuda, Contact Manager örnek çözümü için derleme ve dağıtım işlemini baştan sona denetlemek için bölünmüş proje dosyalarının nasıl kullanıldığına ilişkin bir kılavuz sağlanmıştır. Bu yaklaşımın kullanılması, yalnızca ortama özgü bir komut dosyası çalıştırarak karmaşık, kurumsal ölçekli dağıtımları tek ve yinelenebilir bir adımda çalıştırmanıza olanak tanır.

Daha Fazla Bilgi

Proje dosyalarına ve WPP'ye daha ayrıntılı bir giriş için bkz. inside the Microsoft Build Engine: Using MSBuild and Team Foundation Build by Sayed Ibrahim Hashimi and William Bartholomew, ISBN: 978-0-7356-4524-0.