Bu eğiticide, Bazel ile Java uygulamaları geliştirmenin temelleri açıklanmaktadır. Çalışma alanınızı oluşturup hedefler ve BUILD
dosyaları gibi temel Bazel kavramlarını gösteren basit bir Java projesi oluşturacaksınız.
Tahmini tamamlanma süresi: 30 dakika.
Neler öğreneceksiniz?
Bu eğitimde şunları öğreneceksiniz:
- Hedef oluşturma
- Projenin bağımlılıklarını görselleştirme
- Projeyi birden çok hedefe ve pakete bölme
- Paketler genelinde hedef görünürlüğü kontrol edin
- Etiketler aracılığıyla hedeflere başvurma
- Hedef dağıtma
Başlamadan önce
Bazel'i yükleme
Eğiticiye hazırlanmak için, henüz yüklemediyseniz önce Bazel'i yükleyin.
JDK'yı yükleyin
Java JDK'yı yükleyin (tercih edilen sürüm 11'dir ancak 8 ile 15 arasındaki sürümler desteklenir).
JAVA_HOME ortam değişkenini JDK'yı işaret edecek şekilde ayarlayın.
Linux/macOS'te:
export JAVA_HOME="$(dirname $(dirname $(realpath $(which javac))))"
Windows'da:
- Denetim Masası'nı açın.
- "Sistem ve Güvenlik" > "Sistem" > "Gelişmiş Sistem Ayarları" > "Gelişmiş" sekmesi > "Ortam Değişkenleri..." bölümüne gidin. .
- "Kullanıcı değişkenleri" listesi altında (üstteki) "Yeni..." seçeneğini tıklayın.
- "Değişken adı" alanına
JAVA_HOME
yazın. - "Dizine Göz At..." seçeneğini tıklayın.
- JDK dizinine (örneğin,
C:\Program Files\Java\jdk1.8.0_152
) gidin. - Tüm iletişim kutusu pencerelerinde "Tamam"ı tıklayın.
Örnek projeyi alma
Bazel'in GitHub deposundan örnek projeyi alın:
git clone https://github.com/bazelbuild/examples
Bu eğitim için örnek proje examples/java-tutorial
dizinindedir ve aşağıdaki gibi yapılandırılır:
java-tutorial
├── BUILD
├── src
│ └── main
│ └── java
│ └── com
│ └── example
│ ├── cmdline
│ │ ├── BUILD
│ │ └── Runner.java
│ ├── Greeting.java
│ └── ProjectRunner.java
└── WORKSPACE
Bazel ile geliştirin
Çalışma alanını ayarlama
Bir proje oluşturmadan önce projenin çalışma alanını oluşturmanız gerekir. Çalışma alanı, projenizin kaynak dosyalarını ve Bazel'ın derleme çıkışlarını barındıran bir dizindir. Ayrıca, Bazel'in özel olarak tanıdığı dosyaları da içerir:
Dizini ve içeriğini Bazel çalışma alanı olarak tanımlayan ve projenin dizin yapısının kökünde bulunan
WORKSPACE
dosyası,Bazel'a projenin farklı bölümlerini nasıl oluşturacağını bildiren bir veya daha fazla
BUILD
dosyası. (Çalışma alanında bulunan veBUILD
dosyası içeren dizin bir pakettir. Paketler hakkında bilgiyi bu eğiticinin ilerleyen bölümlerinde öğreneceksiniz.)
Bir dizini Bazel çalışma alanı olarak atamak için söz konusu dizinde WORKSPACE
adlı boş bir dosya oluşturun.
Bazel projeyi derlerken tüm giriş ve bağımlılıkların aynı çalışma alanında olması gerekir. Farklı çalışma alanlarında bulunan dosyalar, bağlantılı olmadığı sürece birbirinden bağımsızdır. Bu durum, bu eğiticinin kapsamı dışındadır.
BUILD dosyasını anlama
BUILD
dosyası, Bazel için farklı türde talimatları içerir.
En önemli tür, Bazel'a yürütülebilir ikili programlar veya kitaplıklar gibi istenen çıkışların nasıl oluşturulacağını söyleyen derleme kuralıdır. BUILD
dosyasındaki her derleme kuralının örneği hedef olarak adlandırılır ve belirli bir kaynak dosya ve bağımlılık grubuna işaret eder. Bir hedef başka hedefleri de
gösterebilir.
java-tutorial/BUILD
dosyasına göz atın:
java_binary(
name = "ProjectRunner",
srcs = glob(["src/main/java/com/example/*.java"]),
)
Örneğimizde ProjectRunner
hedefi, Bazel'in yerleşik java_binary
kuralını örneklendirir. Kural, Bazel'a bir .jar
dosyası ve bir sarmalayıcı kabuk komut dosyası (ikisi de hedefin adını taşıyan) oluşturmasını söyler.
Hedefteki özellikler, bağımlılıklarını ve seçeneklerini açıkça belirtir.
name
özelliği zorunlu olsa da birçoğu isteğe bağlıdır. Örneğin, ProjectRunner
kural hedefinde name
hedefin adıdır, srcs
, hedefi oluşturmak için kullandığı kaynak dosyaları ve main_class
, ana yöntemi içeren sınıfı belirtir. (Örneğimizde, bir grup kaynak dosyasını tek tek listelemek yerine Bazel'a iletmek için glob'un kullanıldığını fark etmiş olabilirsiniz.)
Projeyi oluşturma
Örnek projenizi derlemek için java-tutorial
dizinine gidip şu komutu çalıştırın:
bazel build //:ProjectRunner
Hedef etikette //
bölümü, çalışma alanının köküne göre BUILD
dosyasının konumudur (bu örnekte kökün kendisi) ve ProjectRunner
, BUILD
dosyasındaki hedef addır. (Bu eğiticinin sonunda hedef etiketler hakkında daha ayrıntılı bilgi bulacaksınız.)
Bazel, aşağıdakine benzer çıktılar üretir:
INFO: Found 1 target...
Target //:ProjectRunner up-to-date:
bazel-bin/ProjectRunner.jar
bazel-bin/ProjectRunner
INFO: Elapsed time: 1.021s, Critical Path: 0.83s
Tebrikler, ilk Bazel hedefinizi oluşturdunuz. Bazel, derleme çıkışlarını çalışma alanının kök konumuna bazel-bin
dizinine yerleştirir. Bazel'in çıkış yapısına dair fikir edinmek için bu raporun içeriğine göz atın.
Şimdi yeni derlenen ikili programınızı test edin:
bazel-bin/ProjectRunner
Bağımlılık grafiğini inceleme
Bazel, derleme bağımlılıklarının BUILD dosyalarında açıkça belirtilmesini gerektirir. Bazel bu ifadeleri, projenin bağımlılık grafiğini oluşturmak için kullanır. Bu da doğru artımlı derlemeler sağlar.
Örnek projenin bağımlılıklarını görselleştirmek için Workspace kök dizininde aşağıdaki komutu çalıştırarak bağımlılık grafiğinin metin temsilini oluşturabilirsiniz:
bazel query --notool_deps --noimplicit_deps "deps(//:ProjectRunner)" --output graph
Yukarıdaki komut, Bazel'a hedef //:ProjectRunner
için tüm bağımlılıkları aramasını (ana makine ve örtülü bağımlılıklar hariç) ve çıkışı grafik olarak biçimlendirmesini söyler.
Ardından, metni GraphViz içine yapıştırın.
Gördüğünüz gibi projede ek bağımlılıklar olmadan iki kaynak dosya oluşturan tek bir hedef vardır:
Çalışma alanınızı oluşturduktan, projenizi derledikten ve bağımlılıklarını inceledikten sonra, biraz daha karmaşık hale getirebilirsiniz.
Bazel derlemenizi hassaslaştırın
Küçük projeler için tek bir hedef yeterli olsa da hızlı artımlı derlemeler (yani yalnızca değişiklikleri yeniden derleme) sağlamak ve bir projenin birden fazla parçasını tek seferde oluşturarak derlemelerinizi hızlandırmak için daha büyük projeleri birden fazla hedefe ve pakete bölmek isteyebilirsiniz.
Birden fazla derleme hedefi belirtme
Örnek proje derlemesini iki hedefe bölebilirsiniz. java-tutorial/BUILD
dosyasının içeriğini aşağıdakiyle değiştirin:
java_binary(
name = "ProjectRunner",
srcs = ["src/main/java/com/example/ProjectRunner.java"],
main_class = "com.example.ProjectRunner",
deps = [":greeter"],
)
java_library(
name = "greeter",
srcs = ["src/main/java/com/example/Greeting.java"],
)
Bu yapılandırmada Bazel önce greeter
kitaplığını, ardından ProjectRunner
ikili programını oluşturur. java_binary
öğesindeki deps
özelliği, Bazel'a ProjectRunner
ikili programını derlemek için greeter
kitaplığının gerekli olduğunu bildirir.
Projenin bu yeni sürümünü oluşturmak için aşağıdaki komutu çalıştırın:
bazel build //:ProjectRunner
Bazel, aşağıdakine benzer çıktılar üretir:
INFO: Found 1 target...
Target //:ProjectRunner up-to-date:
bazel-bin/ProjectRunner.jar
bazel-bin/ProjectRunner
INFO: Elapsed time: 2.454s, Critical Path: 1.58s
Şimdi yeni derlenen ikili programınızı test edin:
bazel-bin/ProjectRunner
Şimdi ProjectRunner.java
öğesini değiştirip projeyi yeniden derlerseniz Bazel yalnızca bu dosyayı yeniden derler.
Bağımlılık grafiğine baktığınızda ProjectRunner
değerinin daha önce olduğu gibi girişlere bağlı olduğunu ancak derleme yapısının farklı olduğunu görebilirsiniz:
Projeyi iki hedefle oluşturmuş oldunuz. ProjectRunner
hedefi, iki kaynak dosya oluşturur ve bir ek kaynak dosya oluşturan bir diğer hedefe (:greeter
) bağlıdır.
Birden çok paket kullanma
Şimdi projeyi birden çok pakete ayıralım. src/main/java/com/example/cmdline
dizinine göz attığınızda aynı zamanda bir BUILD
dosyası ve bazı kaynak dosyalar içerdiğini görebilirsiniz. Dolayısıyla, Bazel için çalışma alanı artık //src/main/java/com/example/cmdline
ve //
olmak üzere iki paket içeriyor (çünkü çalışma alanının kökünde bir BUILD
dosyası bulunuyor).
src/main/java/com/example/cmdline/BUILD
dosyasına göz atın:
java_binary(
name = "runner",
srcs = ["Runner.java"],
main_class = "com.example.cmdline.Runner",
deps = ["//:greeter"],
)
runner
hedefi, //
paketindeki greeter
hedefine bağlıdır (dolayısıyla hedef etiketi //:greeter
). Bazel bunu deps
özelliği aracılığıyla bilir.
Bağımlılık grafiğine göz atın:
Ancak derlemenin başarılı olması için visibility
özelliğini kullanarak //src/main/java/com/example/cmdline/BUILD
içindeki runner
hedefini //BUILD
içindeki hedeflere açıkça sağlamanız gerekir. Bunun nedeni, hedeflerin varsayılan olarak yalnızca aynı BUILD
dosyasındaki diğer hedefler tarafından görülebilmesidir. (Bazel, herkese açık API'lere sızan uygulama ayrıntılarını içeren kitaplıklar gibi sorunları önlemek için hedef görünürlüğü kullanır.)
Bunu yapmak için visibility
özelliğini aşağıda gösterildiği gibi java-tutorial/BUILD
içindeki greeter
hedefine ekleyin:
java_library(
name = "greeter",
srcs = ["src/main/java/com/example/Greeting.java"],
visibility = ["//src/main/java/com/example/cmdline:__pkg__"],
)
Artık çalışma alanının kök dizininde aşağıdaki komutu çalıştırarak yeni paketi oluşturabilirsiniz:
bazel build //src/main/java/com/example/cmdline:runner
Bazel, aşağıdakine benzer çıktılar üretir:
INFO: Found 1 target...
Target //src/main/java/com/example/cmdline:runner up-to-date:
bazel-bin/src/main/java/com/example/cmdline/runner.jar
bazel-bin/src/main/java/com/example/cmdline/runner
INFO: Elapsed time: 1.576s, Critical Path: 0.81s
Şimdi yeni derlenen ikili programınızı test edin:
./bazel-bin/src/main/java/com/example/cmdline/runner
Bu aşamada projeyi, her biri birer hedef içeren iki paket halinde derleme yapacak şekilde değiştirdiniz ve bunlar arasındaki bağımlılıkları anladınız.
Hedeflere başvurmak için etiketleri kullanma
Bazel, BUILD
dosyalarında ve komut satırında hedeflere referans vermek için hedef etiketleri (ör. //:ProjectRunner
veya //src/main/java/com/example/cmdline:runner
) kullanır. Söz dizimi aşağıdaki gibidir:
//path/to/package:target-name
Hedef bir kural hedefiyse path/to/package
, BUILD
dosyasını içeren dizinin yoludur ve target-name
, BUILD
dosyasında hedefe verdiğiniz addır (name
özelliği). Hedef bir dosya hedefiyse path/to/package
, paketin köküdür; target-name
ise tam yol dahil olmak üzere hedef dosyanın adıdır.
Depo kökünde hedeflere referans verirken paket yolu boştur. Yalnızca //:target-name
kullanmanız yeterlidir. Aynı BUILD
dosyası içindeki hedeflere referans verirken //
çalışma alanı kök tanımlayıcısını atlayıp yalnızca :target-name
yöntemini bile kullanabilirsiniz.
Örneğin, çalışma alanı kökünün kendisi bir paket (//
) olduğundan ve iki hedef etiketiniz yalnızca //:ProjectRunner
ve //:greeter
olduğundan java-tutorial/BUILD
dosyasındaki hedefler için paket yolu belirtmeniz gerekmiyordu.
Ancak //src/main/java/com/example/cmdline/BUILD
dosyasındaki hedefler için //src/main/java/com/example/cmdline
öğesinin tam paket yolunu belirtmeniz gerekiyordu ve hedef etiketiniz //src/main/java/com/example/cmdline:runner
idi.
Bir Java hedefini dağıtım için paketleme
Şimdi de ikili programı, tüm çalışma zamanı bağımlılıklarıyla derleyerek bir Java hedefini dağıtım için paket edelim. Bu sayede ikili programı, geliştirme ortamınızın dışında çalıştırabilirsiniz.
Hatırlayacağınız gibi, java_binary derleme kuralı bir .jar
ve bir sarmalayıcı kabuk komut dosyası oluşturur. Şu komutu kullanarak runner.jar
içeriğine göz atın:
jar tf bazel-bin/src/main/java/com/example/cmdline/runner.jar
İçerik:
META-INF/
META-INF/MANIFEST.MF
com/
com/example/
com/example/cmdline/
com/example/cmdline/Runner.class
Gördüğünüz gibi runner.jar
, Runner.class
değerini içerir ancak Greeting.class
bağımlılığını içermez. Bazel'in oluşturduğu runner
komut dosyası, sınıf yoluna greeter.jar
ekler. Dolayısıyla bu komut dosyasını bu şekilde bırakırsanız yerel olarak çalışır ancak başka bir makinede bağımsız olarak çalışmaz. Neyse ki java_binary
kuralı, bağımsız, dağıtılabilir bir ikili program derlemenizi sağlar. Oluşturmak için hedef ada _deploy.jar
ekleyin:
bazel build //src/main/java/com/example/cmdline:runner_deploy.jar
Bazel, aşağıdakine benzer çıktılar üretir:
INFO: Found 1 target...
Target //src/main/java/com/example/cmdline:runner_deploy.jar up-to-date:
bazel-bin/src/main/java/com/example/cmdline/runner_deploy.jar
INFO: Elapsed time: 1.700s, Critical Path: 0.23s
Gerekli çalışma zamanı bağımlılıklarını içerdiğinden, geliştirme ortamınızdan bağımsız olarak çalıştırabileceğiniz runner_deploy.jar
az önce oluşturdunuz. Önceki komutu kullanarak bu bağımsız JAR'ın içeriğine göz atın:
jar tf bazel-bin/src/main/java/com/example/cmdline/runner_deploy.jar
İçerikte çalıştırılacak gerekli tüm sınıflar yer alır:
META-INF/
META-INF/MANIFEST.MF
build-data.properties
com/
com/example/
com/example/cmdline/
com/example/cmdline/Runner.class
com/example/Greeting.class
Daha fazla bilgi
Ayrıntılı bilgi için:
rules_jvm_external komutunu çalıştırın.
Harici Bağımlılıklar bölümüne göz atın.
Bazel hakkında daha fazla bilgi edinmek için diğer kurallardan yararlanabilirsiniz.
Bazel ile C++ projeleri oluşturmaya başlamak için C++ derleme eğiticisini inceleyin.
Android uygulama eğitimi ve iOS uygulama eğitimi) inceleyin.
Mutlu binalar!