Görev Tabanlı Derleme Sistemleri

. Sorun bildirin Kaynağı göster Gece · 7,3 · 7,2 · 7,1 · 7,0 · 6,5

Bu sayfada, göreve dayalı derleme sistemleri, nasıl çalıştıkları ve komplikasyonları beraberinde getirir. Kabuk komut dosyalarından sonra, göreve dayalı derleme sistemleri, binaların mantıksal evrimidir.

Görev tabanlı derleme sistemlerini anlama

Görev tabanlı bir derleme sisteminde temel çalışma birimi görevdir. Her biri görev, her türlü mantığı yürütebilen bir komut dosyasıdır. Görevler ise diğer önce çalışması gereken bağımlılıklar olarak düşünebilirsiniz. Ant, Maven, Gradle, Grunt ve Rake gibi günümüzde kullanılan büyük yapı sistemlerinin çoğu görev tabanlı. Şunun yerine: kabuk komut dosyalarını, çoğu modern derleme sisteminde mühendislerin bir şablondur.

Bu örneği Ant kılavuzu:

<project name="MyProject" default="dist" basedir=".">
   <description>
     simple example build file
   </description>
   <!-- set global properties for this build -->
   <property name="src" location="src"/>
   <property name="build" location="build"/>
   <property name="dist" location="dist"/>

   <target name="init">
     <!-- Create the time stamp -->
     <tstamp/>
     <!-- Create the build directory structure used by compile -->
     <mkdir dir="${build}"/>
   </target>
   <target name="compile" depends="init"
       description="compile the source">
     <!-- Compile the Java code from ${src} into ${build} -->
     <javac srcdir="${src}" destdir="${build}"/>
   </target>
   <target name="dist" depends="compile"
       description="generate the distribution">
     <!-- Create the distribution directory -->
     <mkdir dir="${dist}/lib"/>
     <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
     <jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/>
   </target>
   <target name="clean"
       description="clean up">
     <!-- Delete the ${build} and ${dist} directory trees -->
     <delete dir="${build}"/>
     <delete dir="${dist}"/>
   </target>
</project>

Derleme dosyası XML'de yazılır ve derlemeyle ilgili bazı basit meta verileri tanımlar. ve görev listesi (XML'deki <target> etiketleri) sağlar. (Ant, görev'i temsil etmek için hedef kelimesini, komutları belirtmek için ise görev kelimesini kullanır.) Her görev, Karınca tarafından tanımlanan olası komutların bir listesini yürütür. Bu işlemler arasında dizin oluşturma ve silme, javac çalıştırma ve JAR dosyası oluşturuyoruz. Bu komut grubu, kullanıcı tarafından sağlanan eklentilerle her türlü mantığı kapsayacak şekilde genişletilebilir. Her görev, depends özelliği aracılığıyla bağlı olduğu görevleri de tanımlayabilir. Bu bağımlılıklar, Şekil 1'de görüldüğü gibi döngüsel olmayan bir grafik oluşturur.

Bağımlılıkları gösteren akrilik grafik

Şekil 1. Bağımlılıkları gösteren döngüsel grafik

Kullanıcılar, Ant'ın komut satırı aracına görev vererek derlemeleri gerçekleştirir. Örneğin, bir kullanıcı ant dist yazdığında Karınca şu adımları uygular:

  1. Mevcut dizinde build.xml adlı bir dosya yükler ve Şekil 1'de gösterilen grafik yapısını oluşturmak için dosyayı ayrıştırır.
  2. Komut satırında sağlanan dist adlı görevi arar ve bu görevin, compile adlı göreve bir bağımlılığı olduğunu keşfeder.
  3. compile adlı görevi arar ve şuna bağımlı olduğunu keşfeder: init adlı görev.
  4. init adlı görevi arar ve herhangi bir bağımlılığı olmadığını keşfeder.
  5. init görevinde tanımlanan komutları yürütür.
  6. Tüm bu koşulları göz önünde bulundurarak compile görevinde tanımlanan komutları yürütür ve bu görevin bağımlılıkları yürütüldüğünden emin olun.
  7. Tüm bu koşulları göz önünde bulundurarak dist görevinde tanımlanan komutları yürütür ve bu görevin bağımlılıkları yürütüldüğünden emin olun.

Sonuç olarak, dist görevini çalıştırırken Karınca tarafından yürütülen kod eşdeğerdir şu kabuk komut dosyasına ekleyin:

./createTimestamp.sh
mkdir build/
javac src/* -d build/
mkdir -p dist/lib/
jar cf dist/lib/MyProject-$(date --iso-8601).jar build/*

Söz dizimi kaldırıldığında, derleme dosyası ile derleme komut dosyası aslında çok farklı değildir. Ama bu sayede zaten büyük kazanç elde ettik. Diğer dizinlerde yeni derleme dosyaları oluşturabilir ve bunları birbirine bağlayabiliriz. Mevcut görevlere bağlı yeni görevleri kolayca rastgele ve karmaşık şekillerde ekleyebiliriz. ant komut satırı aracına yalnızca tek bir görevin adını iletmemiz yeterlidir. Araç, çalıştırılması gereken her şeyi belirler.

Karınca, ilk olarak 2000'de piyasaya sürülen eski bir yazılımdır. Örneğin, Maven ve Gradle ara yıllarda Karınca'yı iyileştirdiler. otomatik yönetim gibi özelliklerle değiştirilmiştir. bağımlılıkları ve XML içermeyen daha net bir söz dizimi. Ancak bu yeni platformların doğası aynı kalır: mühendislere komut dosyalarını kolayca prensip haline getirilmiş ve modüler bir şekilde yürüttük ve bu görevlerin yürütülmesi için ve yönetmeyi öğreneceksiniz.

Görev tabanlı derleme sistemlerinin karanlık tarafı

Bu araçlar temelde mühendislerin herhangi bir komut dosyasını görev olarak tanımlamasına olanak tanıdığından son derece güçlü olup hayal edebileceğiniz hemen her şeyi yapmanızı görüntüleyebilirsiniz. Ancak bu gücün dezavantajları da vardır. Görev tabanlı derleme sistemlerinin derleme komut dosyaları daha karmaşık hale geldikçe bu sistemlerle çalışmak zor olabilir. Bu tür sistemlerin sorunu, mühendislere çok fazla, sisteme ise yeterince güç vermesidir. Çünkü sistemin çok ihtiyatlı olması gerektiği için performansta düşüş yaşanır. ve yürütme aşamalarında ne kadar rol oynar? Ayrıca sistemin her komut dosyasının yapması gerekeni yaptığını doğrulaması mümkün değildir. Bu nedenle komut dosyalarının karmaşıklığı artar ve sonunda hata ayıklama gerektiren başka bir öğe haline gelir.

Derleme adımlarını paralelleştirmenin zorluğu

Modern geliştirme iş istasyonları oldukça güçlüdür ve bunların her biri paralel olarak birkaç derleme adımı yürütebilir. Ancak görev tabanlı sistemler, yapabilecekleri halde çoğu zaman görev yürütmeyi paralelleştiremez. A görevinin B ve C görevlerine bağlı olduğunu varsayalım. B ve C görevleri birbirine bağımlı olmadığından, sistemin A görevine daha hızlı ulaşabilmesi için bu görevleri aynı anda çalıştırmak güvenli mi? Belki de herhangi bir birlikte çalışır. Ama belki hayır. Her iki durumda da izleme için aynı dosyayı aynı anda çalıştırılması bir çakışmaya neden olur. Hayır, çoğu zaman sistem bunu bilebilir, o yüzden bu çatışmaları (nadir bulunan ancak hata ayıklaması çok zor yapı sorunlarına yol açar) veya tüm derlemeyi tek bir işlemde tek bir iş parçacığında çalışacak şekilde sınırlandırır. Bu durum, güçlü bir geliştirici makinesinin büyük bir israfına yol açabilir ve derlemenin birden fazla makineye dağıtılmasını tamamen imkansız kılar.

Artımlı derlemeleri gerçekleştirme zorluğu

İyi bir derleme sistemi, mühendisler makine öğrenimi gibi güvenilir artımlı derlemeler ve küçük bir değişikliğin kod tabanının tamamının yeniden oluşturulmasını gerektirmediğini oluşturalım. Bu, özellikle derleme sistemi yavaşsa ve sistem yukarıda belirtilen nedenlerden dolayı derleme adımlarını paralel hale getirin. Ancak maalesef görev tabanlı derleme sistemleri de bu konuda zorlanıyor. Görevler her şeyi yapabildiğinden, genel olarak bu görevlerin daha önce yapılıp yapılmadığını kontrol etmek mümkün değildir. Birçok görev, bir dizi kaynak dosya alır ve bir derleyici çalıştırarak bir dizi ikili dosya oluşturur. Bu nedenle, temel kaynak dosyalar değişmediyse bu görevlerin yeniden çalıştırılması gerekmez. Ancak ek bilgi olmadan sistem bunu söyleyemez emin olabilirsiniz. Görev, değiştirilmiş olabilecek bir dosya indirir veya her çalıştırmada farklı olabilecek bir zaman damgası yazar. Garanti yeniden çalıştırması gerektiği anlamına gelir. Bazı derleme sistemleri, mühendislerin bir görevin yeniden çalıştırılması gereken koşulları belirtmesine izin vererek artımlı derlemeleri etkinleştirmeye çalışır. Bu bazen uygulanabilir ancak genellikle göründüğünden çok daha karmaşık bir problem. Örneğin, dosyaların doğrudan diğer dosyalar tarafından dahil edilmesine izin veren C++ gibi dillerde, giriş kaynaklarını ayrıştırmadan değişiklikler için izlenmesi gereken dosya grubunun tamamını belirlemek mümkün değildir. Mühendisler genellikle kısayollar kullanır ve bu kısayollar, bir görev sonucunun gerekmediği halde yeniden kullanıldığı nadir ve can sıkıcı sorunlara yol açabilir. Bu durum sık sık yaşandığında mühendisler yeni bir durum elde etmek için her derlemeden önce temiz derleme yapma alışkanlığı edinir. Bu da ek derlemenin amacını tamamen ortadan kaldırır. Bir görevi ne zaman tekrar çalıştırmanız gerektiğini belirlemek şaşırtıcı derecede kolay değildir ve insanlardan çok makineler tarafından daha iyi işleme alınır.

Komut dosyalarını yönetme ve hata ayıklama konusunda zorluk

Son olarak, görev tabanlı derleme sistemlerinin zorunlu kıldığı derleme komut dosyalarının kullanımı genellikle zordur. Genellikle daha az inceleme alsalar da derleme komut dosyaları, derlenen sistem gibi koddur ve hataların gizlenmesi için kolay yerlerdir. Görev tabanlı bir derleme sistemiyle çalışırken çok sık karşılaşılan hatalara örnek olarak şunlar verilebilir:

  • Görev A, belirli bir dosyayı çıktı olarak oluşturmak için görev B'ye bağlıdır. Sahibi B görevi diğer görevlerin buna bağlı olduğunun farkında değildir; bu nedenle, ve farklı bir konum üretebilir. Bu durum, bir kullanıcı A görevini çalıştırmayı deneyip başarısız olduğunu görene kadar algılanmaz.
  • Görev A, B görevine bağlıdır. B görevi ise C görevine bağlıdır. Bu görev, gereken çıktı olarak kullanabilirsiniz. B görevinin sahibi artık C görevine bağlı olmadığına karar verir. Bu da B görevi C görevini hiç önemsememesine rağmen A görevi başarısız olur.
  • Yeni bir görevin geliştiricisi yanlışlıkla o görev hakkında bir aracın konumu veya aracın değeri gibi değişkenlerine odaklanacağız. Görev, geliştiricinin makinesinde çalışıyor ancak başka bir geliştirici denediğinde başarısız oluyor.
  • Görev, internetten dosya indirme veya derlemeye zaman damgası ekleme gibi kesin olmayan bir bileşen içerir. Artık kullanıcılar derlemeyi her çalıştırdığında farklı sonuçlar elde ediyor. Bu da mühendislerin her zaman birbirlerinin hatalarını veya otomatik derleme sisteminde oluşan hataları yeniden oluşturup düzeltmelerini zorlaştırıyor.
  • Birden fazla bağımlılığı olan görevler yarış koşulları oluşturabilir. Görev A hem görev B'ye hem de görev C'ye bağlıysa ve görev B ile C aynı dosyayı değiştiriyorsa görev A, B ve C görevlerinden hangisinin önce bittiğine bağlı olarak farklı bir sonuç alır.

Burada açıklanan görev tabanlı çerçevede bu performans, doğruluk veya sürdürülebilirlik sorunlarını çözmenin genel bir yolu yoktur. Mühendisler derleme sırasında çalıştırılacak rastgele kod yazabildikleri sürece sistem, derlemeleri her zaman hızlı ve doğru bir şekilde çalıştırabilecek yeterli bilgiye sahip olamaz. Sorunu çözmek için gücümüzden yararlanmamız gerekiyor. yeniden vererek sistemi yeniden oluşturup değil, eserler üretmekten ibarettir.

Bu yaklaşım, Blaze gibi yapı tabanlı derleme sistemlerinin oluşturulmasını sağladı ve Bazel.