Yapı Tabanlı Derleme Sistemleri

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

Bu sayfada, yapı tabanlı derleme sistemleri ve bu sistemlerin temelinde çok önemli. Bazel, yapı tabanlı bir derleme sistemidir. Görev tabanlı derleme komut dosyalarını oluşturmaktan daha iyi bir adımdır; ona çok fazla güç verir kendi görevlerini tanımlamalarını sağlayarak ayrı ayrı mühendislere yardımcı olabilirler.

Yapı tabanlı derleme sistemlerinde, sistem tarafından tanımlanan az sayıda görev bulunur sınırlı bir şekilde yapılandırabileceği araçlar. Mühendisler sisteme hâlâ ne oluşturulacaktır, ancak nasıl oluşturulacağını derleme sistemi belirler. Olduğu gibi göreve dayalı derleme sistemleri, Bazel gibi yapı tabanlı derleme sistemleri derleme dosyaları bulunuyor, ancak bu derleme dosyalarının içerikleri çok farklı. Paydaşlarınıza Turing'in eksiksiz kodlama dilinde zorunlu bir komut dizisi olmaktan daha çıkışının nasıl oluşturulacağını açıklayan Bazel'deki derleme dosyaları bildirim temelli bağımlılıklarını ve derlenen bir dizi yapıyı açıklayan bir manifesto dosyasıyla nasıl oluşturulduklarını etkileyen sınırlı sayıda seçenek vardır. Mühendisler bazel komut satırında, derlenecek bir dizi hedef (ne) belirtir ve Bazel derlemeyi yapılandırmak, çalıştırmak ve planlamaktan sorumludur adımları (nasıl) yapacağınızı öğrenin. Çünkü derleme sistemi artık üzerinde çalışan daha güçlü garantiler verebilir. Bu da, uzun vadeli daha verimli hale getirir.

İşlevsel bakış açısı

Yapı tabanlı derleme sistemleri ile işlevsel sistemleri kolayca karşılaştırabilir öğreneceğiz. Geleneksel zorunlu programlama dilleri (ör. Java, C ve Python), dizede yürütülecek ifade listelerini göreve dayalı geliştirme sistemlerinin programcıların bir dizi adım tanımlamasına gerekir. İşlevsel programlama dilleri (ör. Haskell ve ML), daha çok bir dizi matematik denklemi gibi yapılandırılmıştır. İçinde programcı, gerçekleştirilecek bir hesaplama işlemi tanımlar ancak bu hesaplamanın derleyici olarak da adlandırılır.

Bu, yapı tabanlı bir derleme sisteminde manifest bildirme fikriyle uyumludur. ve sistemin derlemeyi nasıl yürüteceğini belirlemesine izin vermek. Birçok sorun işlevsel programlamayı kullanarak kolayca ifade edilebiliyor olsa da yardımcı olur: Dil çoğu zaman bu tür şeyleri ve bu bilgilerin doğruluğuna dair güçlü garantiler vermek zorunlu bir dilde olması imkansızdır. Bir dil kullanarak ifade edilmesi en kolay problemler fonksiyonel programlama, bir parçayı yalnızca bir parçayı bir dizi kural veya işlev kullanarak verileri diğerine dönüştürme. İşte tam olarak bu yapı sistemi nedir? Tüm sistem, fonksiyonel olarak matematiksel bir fonksiyondur. kaynak dosyaları (ve derleyici gibi araçları) giriş olarak alıp çıkışlar olarak ikili programların kullanılması anlamına gelir. Bu nedenle, çok sayıda reklam içeren bir projeyi fonksiyonel programlamanın ilkelerine göre hareket eden bir sistemdir.

Yapı tabanlı derleme sistemlerini anlama

Google'ın derleme sistemi olan Blaze, yapı tabanlı ilk derleme sistemidir. Bazel Blaze'in açık kaynak sürümüdür.

Bazel'de bir derleme dosyasının (normal olarak adı BUILD) nasıl göründüğü aşağıda verilmiştir:

java_binary(
    name = "MyBinary",
    srcs = ["MyBinary.java"],
    deps = [
        ":mylib",
    ],
)
java_library(
    name = "mylib",
    srcs = ["MyLibrary.java", "MyHelper.java"],
    visibility = ["//java/com/example/myproduct:__subpackages__"],
    deps = [
        "//java/com/example/common",
        "//java/com/example/myproduct/otherlib",
    ],
)

Bazel'de BUILD dosyaları hedefleri tanımlar. Buradaki iki hedef türü şunlardır: java_binary ve java_library. Her hedef, bir projeye karşılık gelen sistem tarafından oluşturulabilir: İkili hedefler, kitaplık hedefleri doğrudan yürütülür ve kitaplık hedefleri, diğer kitaplıklardan da yararlanabilirsiniz. Her hedefte şunlar bulunur:

  • name: Komut satırında ve diğer öğeler tarafından hedefe nasıl başvurulur? hedef
  • srcs: hedef için yapı oluşturmak üzere derlenecek kaynak dosyalar
  • deps: bu hedeften önce oluşturulması ve bağlanması gereken diğer hedefler o

Bağımlılıklar aynı paket içinde (ör. MyBinary :mylib) ya da aynı kaynak hiyerarşisindeki farklı bir pakette (örneğin mylib ile //java/com/example/common arasındaki bağımlılık).

Görev tabanlı derleme sistemlerinde olduğu gibi, derlemeleri Bazel'in komut satırını kullanarak gerçekleştirirsiniz. aracını kullanın. MyBinary hedefini oluşturmak için bazel build :MyBinary çalıştırıyorsunuz. Şu tarihten sonra: Şu komutu temiz bir depoya ilk kez girerek Bazel:

  1. Bağımlılık grafiği oluşturmak için çalışma alanındaki her BUILD dosyasını ayrıştırır ortaya çıkarır.
  2. MyBinary grafiğinin geçişli bağımlılıklarını belirlemek için grafiği kullanır. verileri bağlı olan her hedef ve bu hedefe MyBinary ve yinelemeli olarak desteklenmektedir.
  3. Bu bağımlılıkların her birini sırayla oluşturur. Bazel, inşaat işlerinde her birinin hiçbir bağımlılığı olmayan ve hangi bağımlılıkların takip edildiğini gösteren yine de her bir hedef için oluşturulması gerekir. Bir hedefin tamamı oluşturulduğunda, Bazel bu hedefi oluşturmaya başlar. Bu işlem MyBinary öğesinin geçişli bağımlılıklarından her biri tamamen tamamlanana kadar devam eder geliştirmenizi sağlar.
  4. Aşağıdakilerin tümüne bağlantı veren nihai bir yürütülebilir ikili program oluşturmak için MyBinary ve 3. adımda oluşturulan bağımlılıkları inceleyeceğiz.

Temelde, burada yaşananlar o kadar da karmaşık görünmeyebilir. olanlardan farklıdır. Gerçekten de nihai sonuç aynı ikili olur ve bunu üretme süreci aralarındaki bağımlılıkları bulmak için bir dizi adımı analiz eder ve ardından bu adımları sırasıyla takip edin. Ancak kritik farklar var. İlki görünür unutmayın: Bazel her hedefin yalnızca bir Java kitaplığı ürettiğini bildiği için tek yapması gereken, rastgele bir komut dosyası yerine Java derleyiciyi çalıştırmak komut dosyası kullanarak bu adımları paralel olarak çalıştırmanın güvenli olduğunu bilir. Bu durum, derlemelere kıyasla önemli bir performans artışı sağlayabilir. tek seferde bir tane olmak üzere çok çekirdekli bir makinede hedeflenir ve yalnızca yapı temelli yaklaşımda derleme sistemi kendi yürütmesinden sorumlu olur bu yaklaşım, paralellikle ilgili daha güçlü garantiler vermesini mümkün kılar.

Ancak avantajlar paralelliğin ötesine geçiyor. Bu aşamadan sonra, yaklaşımı, geliştirici herhangi bir değişiklik yapmadan ikinci kez bazel build :MyBinary yazdığında belirginleşir. Bazel daha kısa sürede çıkar hedefin güncel olduğunu belirten bir mesajla 1 saniyeden daha uzun bir sürede bırakabilirsiniz. Bu çünkü bahsettiğimiz fonksiyonel programlama paradigması - Bazel her hedefin yalnızca bir Java eklentisi çalıştırmanın bir sonucu olduğunu bilir ile başlar ve Java derleyicisinden gelen çıkışın yalnızca girişlerine izin verir. Dolayısıyla, girişler değişmediği sürece çıkış yeniden kullanılabilir. Bu analiz her düzeyde işe yarar; MyBinary.java değişirse Bazel anlar MyBinary öğesini yeniden derleyin ancak mylib öğesini yeniden kullanın. Projenin kaynak dosyası //java/com/example/common değişiklik, Bazel bu kitaplığı yeniden oluşturmayı biliyor, mylib ve MyBinary, ancak //java/com/example/myproduct/otherlib yeniden kullanılacak. Bazel her adımda çalıştırdığı araçların özelliklerini bildiği için her seferinde yalnızca minimum yapı kümesini yeniden derleyebilir. eski derlemeler oluşturmayacağını garanti eder.

Derleme işlemini görevlerden ziyade eserler açısından yeniden çerçevelemek güçlü bir araç. Programcının maruz kaldığı esnekliği azaltarak, derleme sistemi geliştirmenin her adımında yapılan işlemler hakkında daha fazla bilgi sahibi olabiliyor. O da derleme işlemini paralel hale getirerek yapıyı çok daha verimli kılmak için ve çıktılarını yeniden kullanmak. Ama bu aslında yalnızca ilk adım ve bu paralellik ve yeniden kullanım yapı taşlarını, her bir ekip üyesinin ve yüksek oranda ölçeklenebilir derleme sistemi içeriyor.

Diğer şık Bazel numaraları

Yapı tabanlı derleme sistemleri, paralellikle ilgili sorunları temelden çözer ve yeniden kullanma gibi teknikler ve özellikler sunar. Ancak hâlâ karşılaştığımız birkaç soruna değindik. Bazel, zeki yöntemlerine değineceğiz. Devam etmeden önce bunlar üzerine konuşmalıyız.

Bağımlılık olarak kullanılan araçlar

Daha önce karşılaştığımız sorunlardan biri, derlemelerin yüklü araçlara bağlı olmasıydı. ve derlemeleri farklı sistemlerde yeniden üretmek zor olabilir. farklı araç sürümlerini veya konumlarını kullanabilirsiniz. Bu sorunu çözmek daha da zorlaşıyor projeniz hangi dile bağlı olarak farklı araçlar gerektiren derlendikleri veya derlendikleri platform (örneğin, Windows ve Linux), Bu platformların her biri, dönüşüm işlemini gerçekleştirmek için biraz farklı araçlar gerektirir. işleyeceğiz.

Bazel, bu sorunun ilk kısmını çözmek için araçları bağımlılık olarak ele alır. her bir hedefe bakın. Çalışma alanındaki her java_library dolaylı olarak bir Java'ya bağlıdır derleyici varsayılan olarak iyi bilinen bir derleyiciye ayarlanır. Bazel her oluşturulduğunda java_library, belirtilen derleyicinin kullanılabilir olup olmadığını kontrol eder. bilinen bir konumda görebilirsiniz. Java derleyici, diğer bağımlılıklarda olduğu gibi ona bağlı olan her eser yeniden inşa edilir.

Bazel, problemin ikinci kısmı olan platform bağımsızlığını yapılandırma yapılandırmaları oluşturma. Proje yönetimi hedeflerine bağlı olarak farklı yapılandırma türlerine bağlıdır:

  • Ana makine yapılandırması: Derleme sırasında çalışan araçlar oluşturma
  • Hedef yapılandırma: Nihai olarak istediğiniz ikili programı oluşturma

Derleme sistemini genişletme

Bazel, ancak mühendisler her zaman daha fazlasını yapmak isteyecektir. her tür derleme işlemini destekleme esnekliğine sahiptir. bunu yapı tabanlı bir derleme sisteminde vermemek daha iyi olur. Neyse ki Bazel, desteklediği hedef türlerinin özel kurallar ekleme hakkında daha fazla bilgi edinin.

Kural yazarı, Bazel'de bir kural tanımlamak için kuralın (BUILD dosyasında iletilen özellikler biçiminde) ve kuralın ürettiği çıkış kümesidir. Yazar ayrıca, bu tür içeriklerde bu kural tarafından oluşturulur. Her eylem, kendi giriş ve çıkışlarını açıklar. çalıştırılabilir veya bir dosyaya belirli bir dize yazıyor olabilir. giriş ve çıkışları aracılığıyla diğer işlemlere bağlanmasını sağlar. Bu, işlemlerin derleme sistemindeki en düşük seviyeli composable birimlerdir. Bir işlem yalnızca tanımlanan giriş ve çıkışlarını kullandığı sürece istediği her şeyi ve Bazel, işlemleri planlamaya ve sonuçları uygun şekilde önbelleğe almaya dikkat eder.

İşlem geliştiriciyi durdurmanın mümkün olmadığından sistem hatasız değildir bir süreç başlatarak değişime ayak uydurmak için karar verebilir. Ancak bu durum pratikte pek sık yaşanmaz. eylem düzeyine kadar suistimal olasılığı önemli ölçüde azalıyor. fırsatlara sahip olacaksınız. Birçok yaygın dili ve aracı destekleyen kurallar yaygın olarak kullanılır ve çoğu projenin kendi proje belgelerini kurallar. Tanımlanmış olsa bile kural tanımlarının yalnızca tek bir bu verileri depoda merkezi bir yerde tutar. Böylece çoğu mühendis, Böylece, uygulama konusunda endişelenmenize gerek kalmaz.

Ortamı izole etme

Eylemler, diğer uygulamalardaki görevlerle aynı sorunlarla karşılaşabilir sistemlerden ibaret değildir. Her ikisinin de aynı birbirleriyle çakışır mı? Bazel aslında bunları korumalı alan oluşturma kullanıldığında mümkün olmayan çakışmalar sağlar. Desteklendiğinde her işlem bir dosya sistemi aracılığıyla diğer tüm işlemlerden izole edilir. korumalıdır. Böylece her işlem, dokümanın bildirdiği girişleri ve çıkışları içeren dosya sistemi üretilir. Bu kural, aynı teknoloji olan Linux'taki LXC gibi sistemler tarafından uygulanır. arka planında yararlı bir yaklaşım var. Bu, eylemlerin tek bir kullanıcıyla çelişmesinin belirtmedikleri dosyaları okuyamadıkları için diğer kullanıcılara yazmadıkları ancak bildirmedikleri dosyalar, Drive'da bir bitirir. Bazel, işlemlerin aracılığıyla iletişim kurmasını kısıtlamak için de korumalı alanları kullanır. ağ.

Dış bağımlılıkları belirleyici hale getirme

Hâlâ bir sorun vardır: Derleme sistemlerinin genellikle indirme harici kaynaklardan gelen bağımlılıkları (araç veya kitaplık gibi) inşa etmeye çalışabilirsiniz. Bu, örnekte JAR dosyası indiren @com_google_common_guava_guava//jar bağımlılığı bir uygulamadır.

Mevcut çalışma alanının dışındaki dosyalara bağlı olarak risklidir. Bu dosyalar değiştirebilir ve derleme sisteminin, sistemdeki değişiklikleri sürekli olarak güncellikleri görebiliriz. Uzak bir dosya karşılık gelen bir değişiklik olmadan değişirse Bu durum, çalışma alanı kaynak kodunda tekrar oluşturulamayan derlemelere yol açabilir. fark edilmemiş bir nedenden dolayı bir gün sonra başarısız olabilir ne kadar önemli olduğunu konuşalım. Son olarak, dış bağımlılıklar, büyük bir güvenlik açığı üçüncü bir tarafa ait olduğu durumlarda risk teşkil eder: bir saldırgan sızdırabilirse bağımlı bir dosya olduğu zaman, bağımlılık dosyasını ve geliştirdiğiniz yapı üzerinde tam kontrol sahibi olmalarını sağlar. ve çıktıları arasında fark yaratır.

Temel sorun, derleme sisteminin bunlardan haberdar olmasını kaynak denetiminde kontrol etmek zorunda kalmadan dosyaları gönderin. Bağımlılığı güncelleme Bilinçli bir seçim olmalıdır, ancak bu seçim tek bir merkezde tek bir kez tek tek mühendisler tarafından veya mühendislik ekibi tarafından bahsedeceğim. Çünkü "kafada aktif" modelinde bile olsak deterministiktir. Bu, son kayıttan bir kayda bakarsanız olduğu gibi değil, o hafta olduğu gibi .

Bazel ve diğer bazı derleme sistemleri, Çalışma alanı genelinde uygulanan her harici için şifreleme karmasını listeleyen bir manifest dosyası oluşturur: altını çizeceğiz. Karma, benzersiz bir kitle oluşturmak için kaynak denetiminde kontrol etmenize gerek yoktur. Yeni bir harici bağımlılığa bir çalışma alanından başvuruda bulunuluyor. Bu bağımlılığın karması manuel veya otomatik olarak manifeste eklenir. Bazel, bir önbelleğe alınmış bağımlılığının gerçek karma değerini beklenen karma değeri belirtilen karma değerini döndürür ve dosyayı yalnızca karma farklıysa yeniden indirir.

İndirdiğimiz yapı manifest'teki karma güncellenmezse derleme işlemi başarısız olur. Bu yapabilirsiniz, ancak bu değişikliğin onaylanması ve kontrol kaynak denetiminin yeni bağımlılığı kabul etmesi gerekir. Bunun anlamı, bir bağımlılığın ne zaman güncellendiğinin kaydı her zaman Çalışma alanı kaynağında karşılık gelen bir değişiklik yapılmadan bağımlılık değişemez. Aynı zamanda, kaynak kodun eski bir sürümünü kontrol ederken derlemenin o sırada kullandığı bağımlılıkları kullanması garanti edilir emin olunması gerekir (aksi takdirde, söz konusu bağımlılıklar kullanılabilir durumda değil).

Elbette uzaktaki bir sunucu kullanılamaz hale gelirse veya bozuk veriler sunmaya başlar. Bu, tüm derlemelerinizin başarısız olmaya başlamasına neden olabilir bu bağımlılığın başka bir kopyası yoksa. Bunu önlemek için sıradan bir proje söz konusuysa, onun tüm ayrıntılarını kontrol ettiğiniz sunuculara ya da hizmetlere olan bağımlılığınız olabilir. Aksi halde her zaman üçüncü bir tarafın merhametine inanarak giriş karmaları güvenlik garanti olsa bile kullanılabilirlik durumunu sağlar.