OpenJDK İnşa(Building) Part12

Kerim Fırat
5 min readFeb 15, 2021

OpenJDK build ile ilgili önceki yazılarıma aşağıdaki linklerden ulaşabilirsiniz.

OpenJDK serisinin 1.bölümü için Link
OpenJDK serisinin 2.bölümü için Link
OpenJDK serisinin 3.bölümü için Link
OpenJDK serisinin 4.bölümü için Link
OpenJDK serisinin 5.bölümü için Link
OpenJDK serisinin 6.bölümü için Link
OpenJDK serisinin 7.bölümü için Link
OpenJDK serisinin 8.bölümü için Link
OpenJDK serisinin 9.bölümü için Link
OpenJDK serisinin 10.bölümü için Link
OpenJDK serisinin 11.bölümü için Link

Hata-Problem Giderme

Büyük ve karmaşık projeler üzerinde çalışırken,zaman zaman hatalar ve çeşitli seviyelerde problemler meydana gelmesi muhtemeldir.Dolayısıyla üzerinde çalıştığınız build başarısız olursa,bu sorunu tespit etmek veya uygun bir çözüm bulmak zor olabilir. Bu süreçte yaşanabilecek olası problemleri ve hataları bu yazımızda inceleyeceğiz.

Hatanın Kaynağını Bulma
Build sürecinde hata meydana geldiğinde,hatanın gerçek nedenini belirlemek zor olabilir. Tipik bir build sürecinde,projenin farklı bölümleri paralel olarak oluşturulur ve bu bölümlere ait çıktılar yine paralel olarak taranarak ana build sürecine dahil edilir.

Paralel build sürecine örnek olması açısından üç(3) bölümlük bir projeyi örnek olarak açıklamaya çalışacağım.
Örnek projemiz:”1=Ana Yapı,2=Framework,3=SDK,” şeklinde üç bölümden oluştuğunu varsayalım.Build süreci 1.bölümden başlatılır. 1.Bölümde belirli alanlar build edildikten sonra 3.bölüm build edilmeye başlanır.
Ancak 3.bölüm çıktısı(output) 2.bölüme dahil edilerek paralel olarak 2.bölüm de build edilir. Tüm bunlara bağlı olarak 1.bölüm tüm diğer çıktıları paralel olarak tarayarak ana build sürecini ilerletir. Herhangi bir veya birden fazla bölümün herhangi bir yerinde çıkacak bir hata-eksik-problem tüm build sürecini durduracaktır ve buna bağlı olarak hata çıktıları gösterecektir.

Hata Özeti
Yaşanan bir aksaklık sebebiyle sonlandırılan build süreci,size yardımcı olması açıcından aşağıdakine benzer bir hatayı çıktı olarak gösterecektir.
Hata çıktısı:

ERROR: Build failed for target 'hotspot' in configuration 'linux-x64' (exit code 2)=== Output from failing command(s) repeated here ===
* For target hotspot_variant-server_libjvm_objs_psMemoryPool.o:
/localhome/git/jdk-sandbox/hotspot/src/share/vm/services/psMemoryPool.cpp:1:1: error: 'failhere' does not name a type
... (rest of output omitted)
* All command lines available in /localhome/git/jdk-sandbox/build/linux-x64/make-support/failure-logs.
=== End of repeated output ===
=== Make failed targets repeated here ===
lib/CompileJvm.gmk:207: recipe for target '/localhome/git/jdk-sandbox/build/linux-x64/hotspot/variant-server/libjvm/objs/psMemoryPool.o' failed
make/Main.gmk:263: recipe for target 'hotspot-server-libs' failed
=== End of repeated output ===
Hint: Try searching the build log for the name of the first failed target.
Hint: If caused by a warning, try configure --disable-warnings-as-errors.

Oldukça açık,anlaşılır ve küçük bir hata çıktısı olduğu için şanslıyız. Hadi bunu küçük parçalara bölüm inceleyelim.
Hata çıktısının ilk satırında,hata kaynağına ait bir açıklama görülmekte. Bu hata çıktısında linux-64 bit yapılandırmasında “hotspot” kaynaklı bir build hatası olduğu görülmekte.Daha sonra hata çıktısının ikinci bölümünde,yani “Output from failing command(s) repeated here” ile “End of repeated output” arasında ise gerçek başarısız komutun ilk çıktı satırları tekrarlanır. Genellikle build’in başarısız olmasına neden olan hata mesajı budur,yani burada yer alır. Şayet birden fazla komut başarısız olursa(bu durum paralel bir yapıda olabilir),başarısız olan tüm komutların çıktıları burada yer alacaktır.

Bir sonraki adımda ise hata günlükleri(failure-logs) dizininin yolu yazdırılır.Bu dizin içinde bu komutun çıktısını bütünüyle içeren bir <target>.log dosyası bulacaksınız. Ve ayrıca aynı dizin içinde bu koutu çalıştırmak için kullanılan komut satırının tamamını içeren bir <target>.cmd dosyası bulacaksınız.
Başarısız olan komutu “.<hata_günlükleri_yolu>/<target>.cmd” şeklinde komut satırında belirterek yeniden çalıştırabilirsiniz.

Hataları izlemenin diğer bir yolu ise Make zincir yapısına ait çıktıyı takip etmektir. İncelenecek yer “Make failed targets repeated here” ve “End of repeated output” arasında kalan bölümdür.
Burada ilk olarak derlenmeyen söz konusu dosyanın tarifi yapılır.
Diğer satırlarda ise tarif edilen dosyanın neden derlemeye çalıştığımızla ilgili bilgiler yer alacaktır.

Son olarak,hatanın nasıl bulunacağına dair bazı ipuçları günlük log dosyasında verilmiştir. Bu örnekte,”psMemoryPool.o” için günlük log dosyasında arama yapmayı deneyeceğiz.

NOT:Derleme hatası özetinin size yalnızca sorunun bir derleme hatası veya benzeri olması durumunda yardımcı olacağını unutmayın. Hata-Problem daha ezoterik ise,veya derleme yaptığınız makine kaynaklı ise,büyük olasılıkla boş “.log” ve “No indication of failed target found” gibi çıktılar alacaksınız.

Build Log Dosyası
Derleme yapılırken,derleme log çıktıları her bölüme ait log dosyalarında tutulabilir. Ayrıca tüm genel süreçler aynı zamanda ana bir log dosyasında tutulabilir. Örneğin X bölümüne ait bir X.log dosyası tutmak mümkün. Bu yapıyı üzerinde çalıştığınız herhangi bir projede uygulayabilirsiniz.
Ancak OpenJDK’da son derlemenin çıktısı her zaman “$BUILD/build.log” dosyasında saklanır. Bir önceki derleme logları ise “build.log.old” dosyasında yer alacaktır. Dolayısıyla log çıktılarını yeniden yönlendirmenize gerek yoktur.

Log dosyasının ayrıntı düzeyini “make” komutuna “LOG” anahtarı belirterek arttırabilirsiniz.Derlemelerde komut satırlarını görmek istiyorsanız aşağıdaki komutu kullanabilirsiniz:

LOG=cmdlines

Genel ayrıntı düzeyini attırmak için aşağıdaki komutları kullanabilirsiniz:

LOG=info
LOG=debug
LOG=trace

Ayrıca bu komutları birbirleriyle kombine etmek de mümkündür. Örneğin yukarıdaki komutları “cmdlines” ile kombine etmek için aşağıdaki gibi kullanabilirsiniz:

LOG=info,cmdlines

debug log düzeyi,make tarafından çalıştırılan çoğu kabuk komutunu gösterir. Ancak “trace” log düzeyi hepsini gösterir. Tercih edeceğiniz her iki log seviyesinin de büyük oranda bir log çıktısı oluşturacağını unutmayın.

Beklenmeyen Derleme Hatalarını Düzeltme(Fixing)
Çoğu durumda,kaynak koddaki hatalı değişiklikler nedeniyle derleme süreci başarısız olarak sonlanır.
Ancak bazı durumlarda ise hataya neden olan hiçbir belirgin değişiklik olmadan başarısız olarak sonlanabilir. Eğer JDK’yı derlemek için makinanızı ilk kez kullanıyorsanız,büyük olasılıkla derleme yaptığınız makina kaynaklı bir problem olabilir. Ancak daha önce aynı makinada JDK’yı başarılı bir şekilde derlediyseniz,bu durumda çalışma ortamınız kaynaklı(işletim sistemi güncellemesi,veya benzeri nedenler) bir problem olabilir.

Derleme Ortamı İle İlgili Problemler
Yaptığınız konfigürasyonun doğru,eksiksiz olduğundan emin olun. Gerekiyorsa “configure”’u yeniden çalıştırın ve herhangi bir uyarı olup olmadığını gözlemleyin. Konfigürasyon sürecine ait tüm loglar “$BUILD/configure.log” dosyası içinde saklanır. Konfigüre sürecinin sonunda,sondaki özetin doğru göründüğünü doğrulayın.
Ve gerçekten Boot JDK ve native toolcahin(araç zinciri) kullandığınızı vb..

JDK Varsayılan(default) olarak,derleyiciden gelen uyarıları derlemede başarısızlık ve hatalar olarak kabul eden katı bir yaklaşıma sahiptir.Bu katı yaklaşım,çok yeni veya çok eski derleyici sürümlerinde uyarı sınıflarını tetikleyebilir ve dolayısıyla derleme başarısız olur.
Bu davranışı kapatmak(Uyarılar yine gösterilecek fakat derlemenin başarısız olmasına neden olmayacak) için aşağıdaki komutu “configure” ile çalıştırın:

--disable-warnings-as-errors

Artımlı(Aşamalı) Yeniden Derlemeyle ilgili Problemler
Artımlı yeniden derleme,projenin bir bölümünü değiştirdiğinizde yalnızda etkilenen parçaların yeniden derleneceği anlamına gelir. Bu çoğu durumda harika çalışıp geliştirme sürecini önemli ölçüde hızlandırsa da,zaman zaman karmaşık bağımlılıklar yanlış bir yapılanma ile sonuçlanır.
Dolayısıyla beklenmeyen derleme sorunlarının en yaygın nedeni budur.
Bu tür bir duruma mahal vermemek için,geliştirme yaptığınız bölümü belirli aralıklarla diğer bölümlerle birlikte derlemek iyi bir yaklaşım olacaktır.

Bu tür beklenmedik derleme sorunları yaşıyorsanız,deneyebileceğiniz önerilerin listesine aşağıda yer verilmiştir. Listedeki her adım bir öncekinden daha fazla zaman gerektirir.Bu nedenle listedeki önerileri sırayla deneyin. Problemlerin çoğu 1. veya 2. adımda çözülecektir.

  1. Deponuzun(repo) güncel olduğundan emin olun. En son değişikliklere sahip olduğunuzdan emin olmak için aşağıdaki komutu çalıştırın.
git pull origin master

2.Derleme sonuçlarını temizleyin. Yeniden derleme sorunlarını çözmenin en basit yolu “clean” komutunu çalıştırmaktır. Derlemeler yarıda kesildiğinde veya bağımlılıklar değiştiğinde,tüm sonucu temizleyerek olası sorunların önüne geçebilirsiniz. Bunun için aşağıdaki komutu kullanın.

make clean

Bu komut “configure” ile ilgili sonuçları temizlemeyi desteklemez.

3.Derleme dizinini/klasörünü tamamen temizleyin.Eğer bu işlem sorunu çözmez ise,bir sonraki adımda aşağıdaki komutu çalıştırın veya derleme çıktı dizinini($BUILD) tamamen kaldırın:

make dist-clean

Bu işlem “configure” dahil olmak üzere oluşturulmuş tüm çıktıları temizleyecektir. Ancak bu işlemden sonra “configure” komutunu yeniden çalıştırmanız gerekir. Ancak “make dist-clean” komutdan önce “make print-configuration” komutunu çalıştırmak iyi bir fikirdir.
Bu komut mevcut “configure” komut satırını yazdıracaktır.
Bunu aşağıdaki şekilde yapabilirsiniz:

make print-configuration > current-configuration
make dist-clean
bash configure $(cat current-configuration)
make

Git deposunu yeniden çekin/klonlayın
Bazen Git deposu,projenin build edilemez olmasına neden olan bir durum yaratır.Böyle bir durumda yapılacak en basit şey tüm depoyu silmek ve tekrardan çekmek olacaktır. Eğer yerel deponuzda yapıtığınız değişiklikler varsa,öncelikle aşağıdaki komutla değişiklikleri farklı bir konuma kaydedin.

git format-patch

Sonuç
Büyük ve çok bölümlü projeler üzerinde çalışırken,bölümlerin sırasına göre ayrı ayrı derlemek çoğu durumda iyi bir yöntemdir.
Böylelikle büyük oranda hataların önüne geçmek ve hataların-problemlerin kaynağını kolaylıkla tespit etmek ve çözüm bulmak için oldukça iyi bir yaklaşım olacaktır.

Hatalar-problemler 13.bölümde devam edecek.

-end of

--

--

Kerim Fırat
Kerim Fırat

Written by Kerim Fırat

Senior Android Platform(AOSP,AAOS) Architect,Open Source Contributor | Turkey Java User Group Vice Chairman | Author

No responses yet