Büyük bir kod tabanı sorunu (derleme) ile nasıl başa çıkılır?


10

Kod yazabilsem de, büyük projelerde çalışma konusunda henüz deneyimim yok. Şimdiye kadar yaptığım şey saniyeler içinde derlenen küçük programları kodlamaktı (algoritmalar, programlama prensipleri, fikirler, paradigmalar gibi çeşitli c / c ++ alıştırmaları ya da sadece api'yi denemek ...) ya da derleme gerektirmeyen bir betik dil (ler) i (python, php, js) yapılmıştır.

Mesele şu ki, bir betik dilinde kodlama yaparken, bir şey işe yarayıp yaramadığını denemek istediğimde - sadece betiği çalıştırıyorum ve ne olduğunu görüyorum. İşler işe yaramazsa, kodu değiştirebilir ve komut dosyasını tekrar çalıştırarak tekrar deneyebilir ve istediğim sonucu elde edene kadar bunu yapmaya devam edebilirim ... Demek istediğim, beklemek zorunda değilsiniz derlemek için herhangi bir şey ve bu nedenle büyük bir kod tabanı almak, değiştirmek, bir şey eklemek veya sadece onunla oynamak oldukça kolaydır - değişiklikleri anında görebilirsiniz.

Örnek olarak Wordpress'i alacağım. Bunun için bir eklenti nasıl oluşturulacağını denemek ve anlamak oldukça kolaydır. İlk önce basit bir "Merhaba Dünya" eklentisi oluşturarak başlıyorsunuz, daha sonra yönetici paneli için API'yı tanımak için basit bir arayüz oluşturuyorsunuz, daha sonra onu oluşturuyor ve daha karmaşık bir şey yapıyorsunuz, bu arada birkaç Her küçük değişiklikten sonra "çalışıyorsa" ve "nasıl çalışır / hissedilir" denemek için WP kadar büyük bir şeyi tekrar tekrar derleme zorunluluğu sadece verimsiz, yavaş ve yanlış görünüyor.

Şimdi, bunu derlenmiş bir dilde yazılmış bir projeyle nasıl yapabilirim? Bazı açık kaynaklı projelere katkıda bulunmak istiyorum ve bu soru beni rahatsız ediyor. Durum muhtemelen projeden projeye farklılık gösterir, bazılarının önceden akıllıca düşünülen bir şekilde "modüler" olacağı, bazıları ise tekrar tekrar derlenmesi gereken büyük bir damla olacaktır.

Bunun nasıl düzgün yapıldığı hakkında daha fazla bilgi edinmek istiyorum. Bununla başa çıkmak için bazı yaygın uygulamalar, yaklaşımlar ve proje tasarımları (kalıpları) nelerdir? Bu "modülerlik" programcıların dünyasında nasıl adlandırılır ve bunun hakkında daha fazla bilgi edinmek için ne yapmalıyım? Projeler bir süre sonra sorun yaratan ilk düşünce oranlarından sık sık büyüyor mu? İyi tasarlanmamış projelerin uzun derlemesinden kaçınmanın bir yolu var mı ? Bunları bir şekilde modüle etmenin bir yolu (belki de geliştirirken programın hayati olmayan bölümlerini hariç tutmak (başka herhangi bir fikir?))?

Teşekkürler.


4
Ob. XKCD ve ilgili thinkgeek t-shirt * 8 ')
Mark Booth

1
Yeterince büyük bir bütçeye sahip yeterince büyük bir proje üzerinde çalışıyorsanız, sizin için derleme yapmak için sunucular inşa edebilirsiniz :)
SoylentGray

@Chad - Bunu biliyorum, ama şu an sadece evim gnu / linux masaüstü
makinem

@Chad Tamam, yani bize Java'nın (veya derlenmiş herhangi bir dilin) yığınıyla başa çıkmak için özel sunuculara ihtiyacımız olduğunu mu söylüyorsunuz ? Bu tamamen saçmalık
Kolob Kanyonu

1
@KolobCanyon - Hayır, çalışabileceğiniz bir ölçek olduğunu söylüyorum. ve testlerin hızlı derlenmesine ve yazılmasına adanmış isteğe bağlı bir VM'ye sahip olmanın, ölçeğin o kadar büyük olmadığı kadar kolay olduğu kadar yeterince ucuz olmaları.
SoylentGray

Yanıtlar:


8

Söylendiği gibi, küçük bir değişiklik yaptığınızda projenin tamamını asla derlemezsiniz. Bunun yerine, yalnızca kodun değişen kısmını ve buna bağlı olarak tüm kodu yeniden derlersiniz.

C / C ++ 'da derleme oldukça basittir. Sen derlemek makine koduna her kaynak dosyasını çevirmek ve sonra (biz onları dosyaları * .o nesne diyoruz) bağlantı tek bir büyük çalışabilen içine tüm nesne dosyalarını.

MainMa'nın belirttiği gibi, bazı kütüphaneler çalışma zamanında yürütülebilir dosya ile dinamik olarak bağlanacak ayrı dosyalara yerleştirilmiştir. Bu kitaplıklara Unix'te Paylaşılan Nesneler (* .so) ve Windows'ta Dinamik Olarak Bağlantılı Kitaplıklar (DLL) adı verilir. Dinamik kütüphanelerin birçok avantajı vardır, bunlardan biri kaynak kodları etkili bir şekilde değişmedikçe bunları derlemeniz / bağlamanız gerekmez.

Size yardımcı olacak yapı otomasyon araçları vardır:

  • Kaynak ağacınızın farklı bölümleri arasındaki bağımlılıkları belirtin.
  • Yalnızca değiştirilen bölümde dakik, gizli derlemeler başlatın.

En ünlü olanlar (make, ant, maven, ...) kodun son derlemesinden bu yana hangi bölümlerinin değiştirildiğini ve tam olarak hangi nesnenin / ikili dosyanın güncellenmesi gerektiğini otomatik olarak algılayabilir.

Ancak, bu bir "komut dosyası" yazmak zorunda kalmanın (nispeten küçük) bir maliyeti gelir. Hedefleriniz ve bağımlılıkları tanımlamak, hangi derleyiciyi kullanmak istediğinizi ve hangi seçenekleri kullanmak, yapı ortamınızı, kütüphane yollarınızı tanımlamak gibi yapınızla ilgili tüm bilgileri içeren bir dosyadır ... Belki Makefiles (çok Unix dünyasında yaygın olan) veya build.xml (Java dünyasında çok popüler). Onların yaptığı budur.


2
Ant (Java) 'dir değil yeniden derlenmesine ihtiyaç duyduğu belirlemek mümkün. Değişen kaynak kodunu yeniden derleyerek işin önemsiz kısmını ele alır, ancak sınıf bağımlılıklarını hiç anlamıyor. Bunun için IDE'lere güveniyoruz ve bir yöntem imzası arama kodunda değişiklik gerektirmeyecek şekilde değiştirilirse yanlış gidiyorlar.
kevin cline 28:11

@kevincline Ben ikinci - build.xmldosyada farklı bir şey belirtmedikçe ANT her şeyi derler
Kolob Kanyonu

7

Tüm projeyi her defasında yeniden derlemezsiniz. Örneğin, bir C / C ++ uygulamasıysa, kitaplıklara (Windows'daki DLL'ler) ayrılma olasılığı vardır, her kitaplık ayrı olarak derlenir.

Projenin kendisi genellikle günlük olarak özel bir sunucuda derlenir: bunlar gece yapılarıdır. Bu işlem çok zaman alabilir, çünkü sadece derleme süresini değil, aynı zamanda birim testlerini, diğer testleri ve diğer işlemleri çalıştırmak için harcanan zamanı da içerir.


3
Eğer hepsini yeniden
derlemezsem

5

Bence şimdiye kadarki cevapların hepsi de büyük yazılım projelerinin neredeyse her zaman çok daha küçük parçalara bölünmüş olması. Her parça normalde kendi dosyasında saklanır.

Bu parçalar, nesneler oluşturmak için ayrı ayrı derlenir . Nesneler daha sonra nihai ürünü oluşturmak için birbirine bağlanır . [Bir bakıma, Legos'tan bir şeyler inşa etmek gibi bir şey. Son şeyi büyük bir plastik parçadan kalıplamaya çalışmayın, bunun yerine bir grup küçük parçayı birleştirin.]

Projeyi ayrı ayrı derlenen parçalara bölmek, bazı düzgün şeylerin gerçekleşmesini sağlar.

Artımlı Bina

Öncelikle, bir parçayı değiştirdiğinizde, genellikle tüm parçaları yeniden derlemeniz gerekmez. Genel olarak konuşursak, diğer parçaların sizin parçanızla etkileşimini değiştirmediğiniz sürece, diğerlerinin yeniden derlenmesi gerekmez.

Bu artımlı bina fikrini doğurur . Artımlı bir yapı yaparken, sadece değişiklikten etkilenen parçalar yeniden derlenir. Bu geliştirme süresini büyük ölçüde hızlandırır. Doğru, yine de her şeyin yeniden bağlanmasını beklemek zorunda kalabilirsiniz, ancak yine de her şeyi yeniden derlemek ve yeniden bağlamak zorunda kalmaktan tasarruf ediyor. (BTW: Bazı sistemler / diller artımlı bağlamayı destekler, böylece yalnızca değişen şeylerin yeniden bağlanması gerekir. Bunun maliyeti genellikle düşük kod performansı ve boyutundadır.)

Birim Testi

Küçük parçalara sahip olmanızı sağlayan ikinci şey, parçaları birleştirmeden önce ayrı ayrı test etmektir . Bu Birim Testi olarak bilinir . Ünite Testinde, her ünite sistemin geri kalanıyla entegre edilmeden (birleştirilmeden) önce ayrı ayrı test edilir. Birim testleri normalde sistemin geri kalanını içermeden hızlı bir şekilde çalıştırılabilmeleri için yazılır.

Testin uygulanmasının sınırlayıcı durumu Teste Dayalı Geliştirme'de (TDD) görülmektedir. Bu geliştirme modelinde, başarısız bir testi düzeltmedikçe hiçbir kod yazılmaz / değiştirilmez.

Daha Kolay

Yani işleri parçalamak iyi görünüyor, ama aynı zamanda projeyi inşa etmek için çok fazla iş gerekiyor gibi görünüyor: hangi parçaların değiştiğini ve bu parçalara neyin bağlı olduğunu bulmamız, her parçayı derlemeniz ve sonra her şeyi birbirine bağlamanız gerekiyor.

Neyse ki, programcılar tembeldir *, bu yüzden işlerini kolaylaştırmak için birçok araç icat ederler. Bu amaçla, yukarıdaki görevi otomatikleştirmek için birçok araç yazılmıştır. Bunların en ünlüsü zaten belirtilmiştir (marka, karınca, maven). Bu araçlar, son projenizi oluşturmak için hangi parçaların bir araya getirilmesi gerektiğini ve parçaların birbirine nasıl bağımlı olduğunu tanımlamanıza olanak tanır (yani bunu değiştirirseniz, bunun yeniden derlenmesi gerekir). Sonuç olarak, yalnızca bir komutun verilmesi neyin yeniden derlenmesi gerektiğini derler, derler ve her şeyi yeniden bırakır.

Ama bu yine de şeylerin birbirleriyle nasıl ilişkili olduğunu bulmaya bırakıyor. Bu çok iş ve daha önce de söylediğim gibi, programcılar tembel. Böylece başka bir sınıf araç geliştirdiler. Bu araçlar sizin için bağımlılıkları belirlemek için yazılmıştır! Araçlar genellikle Eclipse ve Visual Studio gibi Entegre Geliştirme Ortamlarının (IDE) bir parçasıdır, ancak hem genel hem de özel uygulamalar için kullanılan bazı bağımsız araçlar da vardır (makedep, Qt programları için QMake).

* Aslında, programcılar gerçekten tembel değiller, sadece bir program tarafından otomatikleştirilebilecek tekrarlayan görevleri yerine getirerek zamanlarını problemler üzerinde çalışmakla geçirirler.


5

İşte C / C ++ derlemelerini hızlandırmayı deneyebileceğiniz şeyler listem:

  • Sadece nelerin değiştiğini yeniden inşa edecek misiniz? Çoğu ortam bunu varsayılan olarak yapar. Üstbilgilerin hiçbiri değişmediyse veya dosyayı yeniden derlemenize gerek yoktur. Benzer şekilde, objs / lib'deki tüm linkler değişmediyse bir dll / exe dosyasını yeniden oluşturmak için hiçbir neden yoktur.
  • Hiçbir zaman değişmeyen 3. taraf öğeleri ve ilişkili başlıkları salt okunur kod kitaplığı alanına koyun. Yalnızca başlıklara ve ilişkili ikili dosyalara ihtiyacınız vardır. Bunu asla bir kereden başka bir kaynaktan yeniden kurmanız gerekmez.
  • Her şeyi yeniden oluştururken, deneyimlerimdeki iki sınırlayıcı faktör , çekirdek sayısı ve disk hızı oldu . Gerçekten iyi bir hdd ile etli dört çekirdekli, hiper iş parçacıklı bir makine alın ve performansınız artacak. Katı hal sürücüsünü düşünün - ucuz olanların iyi bir hdd'den daha kötü olabileceğini unutmayın. HDD'nizi artırmak için baskını kullanmayı düşünün
  • Derlemeyi ağınızdaki diğer iş istasyonlarına ayıracak Incredibuild gibi dağıtılmış bir derleme sistemi kullanın . (Sağlam bir ağınız olduğundan emin olun).
  • Üstbilgi dosyalarını sürekli olarak yeniden yüklemekten kurtarmak için bir birlik derlemesi kurun.

Benim deneyimime göre (çok değil, ama iyi), projeniz "çok küçük" ün ötesine geçerse, disk hızı önemsiz olmaya başlar. Bir sonraki mermi noktanızda söylediklerinizi düşünün: derlemeyi hızlandırmak için ağı kullanıyorsunuz. Disk büyük bir darboğazdaysa, ağa başvurmak çok iyi bir hareket gibi görünmüyor.
R. Martinho Fernandes

Başka bir ucuz çözüm bir tmpfs içinde derlemektir. Derleme işlemi IO'ya bağlıysa performansı büyük ölçüde artırabilir.
Artefact2

4

Her küçük değişiklikten sonra "çalışıyorsa" ve "nasıl çalışır / hissedilir" denemek için WP kadar büyük bir şeyi tekrar tekrar derleme zorunluluğu sadece verimsiz, yavaş ve yanlış görünüyor.

Yorumlanan bir şeyi yürütmek de çok verimsiz ve yavaş ve tartışmalı bir şekilde yanlıştır. Sen Dev'in PC'de zaman gereksinimleri hakkında şikayet, ama konum değil üzerinde nedenler zaman gereksinimlerini derleme kullanıcının çok daha kötü tartışmalı olan PC,.

Daha da önemlisi, modern sistemler oldukça gelişmiş artımlı yeniden yapılandırmalar yapabilir ve her şeyi küçük değişiklikler için yeniden derlemek yaygın değildir - derlenmiş sistemler, özellikle UI gibi şeyler için yaygın olan komut dosyası bileşenlerini içerebilir.


1
Sorumun, yaklaşım tartışmasını derlemeye karşı yorumlanması amaçlanmadığına inanıyorum. Bunun yerine, büyük (derlenmiş) bir projenin geliştirilmesinin nasıl düzgün bir şekilde yapıldığına dair tavsiye istedim. Yine de artımlı yeniden inşa fikri için teşekkürler.
pootzko

@pootzko: Tercümenin dezavantajlarından da bahsetmediğinizde, derlemenin dezavantajlarını tartışmak oldukça haksızlık.
DeadMG

1
hayır değil. bu başka bir tartışma ve sorumla ilgisi yok. Tartışılmaması gereken bir şey olduğunu söylemiyorum. olmalı, ama burada değil.
pootzko

@pootzko: O zaman sorunuzun çoğunu derleme hakkında sevmediğiniz şeyleri numaralandırmaya adamamalısınız. "Büyük projelerin derleme süreleri nasıl azaltılabilir?" Gibi çok daha kısa ve daha özlü bir şey yazmalıydınız.
DeadMG

Birisine sorumu nasıl "sormam" gerektiğini sormam gerektiğini bilmiyordum ..? : OI, benim bakış açımı daha iyi açıklamak için yaptığım gibi yazdım, böylece diğerleri daha iyi anlayabildi ve bana aynı / benzer şeyi derlenmiş dillerle nasıl elde edeceğimizi açıklayabildi. Tekrar söyledim - yorumlamayan dillerden kullanıcının bilgisayarında daha kötü zaman gereksinimlerine neden olup olmadığını kimseden söylememi istemedim. Bunu biliyorum ve sorumla ilgisi yok - "derlenmiş dillerle nasıl yapılır", üzgünüm. Diğer insanlar ne sorduğumu anladılar gibi görünüyor, bu yüzden
sorumun

4
  • Kısmi Yeniden Oluşturma

Proje uygun derleme bağımlılığı DAG uygularsa, yalnızca değişikliğinizin etkilediği nesne dosyalarını yeniden derlemekten kurtulabilirsiniz.

  • Çoklu Derleme Süreci

Ayrıca uygun bir derleme bağımlılığı DAG'sini varsayarsak, birden çok işlem kullanarak derleyebilirsiniz. Çekirdek / işlemci başına bir iş normdur.

  • Yürütülebilir testler

Test için yalnızca belirli nesne dosyalarını bağlayan birden fazla yürütülebilir dosya oluşturabilirsiniz.


2

MainMa'nın cevabına ek olarak, üzerinde çalıştığımız makineleri de geliştirdik. Yaptığımız en iyi satın almalardan biri, tüm projeyi yeniden derlemenize yardımcı olamayacağınız bir SSD idi.

Başka bir öneri de farklı bir derleyici denemek olacaktır. O zamanlar Java'nın derleyicisinden Jikes'e geçtik ve şimdi çok çekirdekli işlemcilerden daha iyi yararlanan Eclipse (bir adı olup olmadığını bilmiyorum) ile birlikte gelen derleyiciyi kullanmaya başladık.

Bu değişiklikleri yapmadan önce 37.000 dosya projemizin sıfırdan derlenmesi yaklaşık 15 dakika sürdü. Değişikliklerden sonra 2-3 dakikaya indirildi.

Tabii ki, MainMa'nın tekrardan bahsetmeye değer. Her değişiklik görmek istediğinizde projenin tamamını yeniden derlemeyin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.