Bu eğitimde, Bazel ile Java uygulamaları oluşturmanın temelleri ele alınmaktadı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 tamamlama 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 fazla hedefe ve pakete ayırma
- Paketler genelinde hedef görünürlüğünü kontrol etme
- Etiketler aracılığıyla referans hedefleri
- Hedef dağıtma
Başlamadan önce
Bazel'i yükleme
Eğitime hazırlanmak için, henüz yüklemediyseniz önce Bazel'i yükleyin.
JDK'yi yükleme
Java JDK'yi 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'yi 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..."ne gidin. .
- "Kullanıcı değişkenleri" listesinin (üstteki) altında "Yeni..."yi tıklayın.
- "Değişken adı" alanına
JAVA_HOME
yazın. - "Dizin'e göz at..."ı tıklayın.
- JDK dizinine (örneğin,
C:\Program Files\Java\jdk1.8.0_152
) gidin. - Tüm iletişim 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ğitimdeki örnek proje, examples/java-tutorial
dizininde yer alır ve aşağıdaki gibi yapılandırılmıştır:
java-tutorial
├── BUILD
├── src
│ └── main
│ └── java
│ └── com
│ └── example
│ ├── cmdline
│ │ ├── BUILD
│ │ └── Runner.java
│ ├── Greeting.java
│ └── ProjectRunner.java
└── MODULE.bazel
Bazel ile derleme
Çalışma alanını ayarlama
Proje oluşturmadan önce projenin çalışma alanını ayarlamanız gerekir. Çalışma alanı, projenizin kaynak dosyalarını ve Bazel'in derleme çıkışlarını içeren bir dizindir. 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
MODULE.bazel
dosyası,Bazel'e projenin farklı bölümlerinin nasıl derleneceğini söyleyen bir veya daha fazla
BUILD
dosyası. (Çalışma alanındakiBUILD
dosyası içeren bir dizin pakettir. Paketler hakkında daha fazla bilgiyi bu eğitimde bulabilirsiniz.)
Bir dizini Bazel çalışma alanı olarak atamak için söz konusu dizinde MODULE.bazel
adlı boş bir dosya oluşturun.
Bazel projeyi derlediğinde tüm girişler ve bağımlılıklar aynı çalışma alanında olmalıdır. Farklı çalışma alanlarında bulunan dosyalar, bağlanmadıkları sürece birbirinden bağımsızdır. Bu konu bu eğitim kapsamında değildir.
BUILD dosyasını anlama
BUILD
dosyası, Bazel için birkaç farklı türde talimat içerir.
En önemli tür, Bazel'e istenen çıkışları (ör. yürütülebilir ikili dosyalar veya kitaplıklar) nasıl oluşturacağını söyleyen derleme kuralı'dır. BUILD
dosyasında bir derleme kuralının her örneğine hedef denir ve belirli bir kaynak dosya ve bağımlılık grubunu işaret eder. Hedefler diğer 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'e bir .jar
dosyası ve sarmalayıcı kabuk komut dosyası (her ikisi de hedefin adıyla adlandırılır) oluşturmasını söyler.
Hedefteki özellikler, bağımlılıkları ve seçenekleri açıkça belirtir.
name
özelliği zorunludur ancak çoğu isteğe bağlıdır. Örneğin, ProjectRunner
kural hedefinde name
hedefin adı, srcs
Bazel'in hedefi oluşturmak için kullandığı kaynak dosyaları, main_class
ise ana yöntemi içeren sınıfı belirtir. (Örneğimizde, bir grup kaynak dosyayı tek tek listelemek yerine Bazel'e iletmek için glob işlevinin kullanıldığını fark etmiş olabilirsiniz.)
Projeyi oluşturma
Örnek projenizi derlemek için java-tutorial
dizinine gidin ve aşağıdaki komutu çalıştırın:
bazel build //:ProjectRunner
Hedef etiketinde //
kısmı, BUILD
dosyasının çalışma alanının köküne göre konumudur (bu durumda kökün kendisidir) ve ProjectRunner
, BUILD
dosyasındaki hedef addır. (Hedef etiketler hakkında daha fazla bilgiyi bu eğitim makalesinin sonunda bulabilirsiniz.)
Bazel, aşağıdakine benzer bir çıktı oluşturur:
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ündeki bazel-bin
dizinine yerleştirir. Bazel'in çıkış yapısı hakkında fikir edinmek için içeriğine göz atın.
Ardından, yeni oluşturulan ikili dosyanı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 tanımlanmasını gerektirir. Bazel, projenin bağımlılık grafiğini oluşturmak için bu ifadeleri kullanır. Bu sayede doğru artımlı derlemeler yapılabilir.
Örnek projenin bağımlılıklarını görselleştirmek için çalışma alanı kökünde şu 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'e hedef //:ProjectRunner
için tüm bağımlılıkları (ana makine ve gizli bağımlılıklar hariç) aramasını ve çıkışı grafik olarak biçimlendirmesini söyler.
Ardından metni GraphViz'e yapıştırın.
Gördüğünüz gibi, projede ek bağımlılık olmadan iki kaynak dosya oluşturan tek bir hedef vardır:
Çalışma alanınızı ayarladıktan, projenizi oluşturduktan ve bağımlılıkları inceledikten sonra biraz karmaşıklık ekleyebilirsiniz.
Bazel derlemenizi hassaslaştırma
Küçük projeler için tek bir hedef yeterli olsa da hızlı artımlı derlemelere (yani yalnızca değişenleri yeniden derlemeye) izin vermek ve bir projenin birden fazla bölümünü aynı anda derleyerek derlemelerinizi hızlandırmak için 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ırmayla Bazel önce greeter
kitaplığını, ardından ProjectRunner
ikili programını oluşturur. java_binary
içindeki deps
özelliği, Bazel'e ProjectRunner
ikili programını derlemek için greeter
kitaplığının gerekli olduğunu bildirir.
Projenin bu yeni sürümünü derlemek için aşağıdaki komutu çalıştırın:
bazel build //:ProjectRunner
Bazel, aşağıdakine benzer bir çıktı oluşturur:
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
Ardından, yeni oluşturulan ikili dosyanızı test edin:
bazel-bin/ProjectRunner
Artık ProjectRunner.java
dosyasını değiştirip projeyi yeniden oluşturursanız Bazel yalnızca bu dosyayı yeniden derleyecektir.
Bağımlılık grafiğine baktığınızda ProjectRunner
'ün öncekiyle aynı girişlere bağlı olduğunu ancak derlemenin yapısının farklı olduğunu görebilirsiniz:
Artık projeyi iki hedefle oluşturdunuz. ProjectRunner
hedefi bir kaynak dosya oluşturur ve bir ek kaynak dosya oluşturan başka bir hedefe (:greeter
) bağlıdır.
Birden fazla paket kullanma
Şimdi projeyi birden fazla pakete bölelim. src/main/java/com/example/cmdline
dizinine göz atarsanız bir BUILD
dosyasının yanı sıra bazı kaynak dosyaları da içerdiğini görebilirsiniz. Bu nedenle, çalışma alanı artık Bazel için //src/main/java/com/example/cmdline
ve //
olmak üzere iki paket içeriyor (çalışma alanının kökünde bir BUILD
dosyası bulunduğundan).
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 (dolayısıyla hedef etiketi //:greeter
) bağlıdır. 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
'daki runner
hedefine //BUILD
'deki hedeflere yönelik açık bir görünürlük vermeniz gerekir. Bunun nedeni, hedeflerin varsayılan olarak yalnızca aynı BUILD
dosyasındaki diğer hedefler tarafından görülebilmesidir. (Bazel, uygulama ayrıntılarını içeren kitaplıkların herkese açık API'lere sızması gibi sorunların önüne geçmek için hedef görünürlüğü kullanır.)
Bunu yapmak için visibility
özelliğini java-tutorial/BUILD
içindeki greeter
hedefine aşağıdaki gibi 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ünde 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 bir çıktı oluşturur:
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
Ardından, yeni oluşturulan ikili dosyanızı test edin:
./bazel-bin/src/main/java/com/example/cmdline/runner
Artık projeyi, her biri bir hedef içeren iki paket olarak derlenecek şekilde değiştirdiniz ve aralarındaki bağımlılıkları anladınız.
Hedeflere referans vermek için etiketleri kullanma
Bazel, BUILD
dosyalarında ve komut satırında hedeflere referans vermek için hedef etiketleri kullanır (ör. //:ProjectRunner
veya //src/main/java/com/example/cmdline:runner
). Söz dizimleri 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 yolunu, target-name
ise tam yolu da dahil olmak üzere hedef dosyanın adını belirtir.
Depo kökündeki hedeflere referans verirken paket yolu boştur, yalnızca //:target-name
kullanın. Aynı BUILD
dosyasındaki hedeflere referans verirken //
Workspace kök tanımlayıcısını atlayabilir ve yalnızca :target-name
kullanabilirsiniz.
Örneğin, java-tutorial/BUILD
dosyasındaki hedefler için bir paket yolu belirtmeniz gerekmez. Bunun nedeni, çalışma alanı kökünün de bir paket (//
) olması ve iki hedef etiketinizin yalnızca //:ProjectRunner
ve //:greeter
olmasıdır.
Ancak //src/main/java/com/example/cmdline/BUILD
dosyasındaki hedefler için //src/main/java/com/example/cmdline
'un tam paket yolunu belirtmeniz gerekiyordu ve hedef etiketiniz //src/main/java/com/example/cmdline:runner
idi.
Dağıtım için Java hedefini paketleme
Şimdi ikili dosyayı tüm çalışma zamanı bağımlılıkları ile derleyerek dağıtım için bir Java hedefi paketleyelim. Bu sayede, ikili dosyayı geliştirme ortamınızın dışında çalıştırabilirsiniz.
Hatırlayacağınız gibi java_binary derleme kuralı bir .jar
ve sarmalayıcı kabuk komut dosyası oluşturur. Şu komutu kullanarak runner.jar
öğesinin içeriğine göz atın:
jar tf bazel-bin/src/main/java/com/example/cmdline/runner.jar
İçeriklerin özellikleri:
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
'u içerir ancak bağımlılık öğesi Greeting.class
'yi içermez. Bazel'in oluşturduğu runner
komut dosyası, sınıf yoluna greeter.jar
ekler. Bu nedenle, dosyayı 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ı, kendi kendine yeten, dağıtılabilir bir ikili oluşturmanıza olanak tanır. Oluşturmak için hedef adın sonuna _deploy.jar
ekleyin:
bazel build //src/main/java/com/example/cmdline:runner_deploy.jar
Bazel, aşağıdakine benzer bir çıktı oluşturur:
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
runner_deploy.jar
'ü derlediniz. Gerekli çalışma zamanı bağımlılıkları içerdiğinden, geliştirme ortamınızdan bağımsız olarak çalıştırabilirsiniz. Önceki komutu kullanarak bu bağımsız JAR dosyasının içeriğine göz atın:
jar tf bazel-bin/src/main/java/com/example/cmdline/runner_deploy.jar
İçerik, çalıştırılmak için gereken tüm sınıfları içerir:
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
Daha fazla bilgi için:
Geçişli Maven bağımlılıklarını yönetmek için kurallara yönelik rules_jvm_external.
Yerel ve uzak depolarla çalışma hakkında daha fazla bilgi edinmek için Harici Bağımlılıklar başlıklı makaleyi inceleyin.
Bazel hakkında daha fazla bilgi edinmek için diğer kurallar
Bazel ile C++ projeleri oluşturmaya başlamak için C++ derleme eğitimi.
Bazel ile Android ve iOS için mobil uygulamalar oluşturmaya başlamak istiyorsanız Android uygulaması eğitimimiz ve iOS uygulaması eğitimimizi inceleyebilirsiniz.
İyi çalışmalar.