Bu eğiticide, Bazel ile Java uygulamaları oluşturma hakkındaki temel bilgiler verilmektedir. Çalışma alanınızı oluşturup hedefler ve BUILD
dosyaları gibi temel Bazel kavramlarını gösteren basit bir Java projesi derleyeceksiniz.
Tahmini tamamlanma süresi: 30 dakika.
Neler öğreneceksiniz?
Bu eğiticide şunları öğreneceksiniz:
- Hedef oluşturun
- Projenin bağımlılıklarını görselleştirme
- Projeyi birden çok hedefe ve pakete bölme
- Paketler genelinde hedef görünürlüğünü kontrol etme
- Hedeflere etiketler aracılığıyla referans verme
- Hedef dağıtma
Başlamadan önce
Bazel'ı yükleme
Eğiticiye hazırlanmak için, henüz yüklemediyseniz öncelikle 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..." seçeneğine gidin. .
- "Kullanıcı değişkenleri" listesinin (en üstteki) altında "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 gidin (örneğin,
C:\Program Files\Java\jdk1.8.0_152
). - Tüm iletişim pencerelerinde "Tamam"ı tıklayın.
Örnek projeyi alma
Örnek projeyi Bazel'ın GitHub deposundan 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ılmıştır:
java-tutorial
├── BUILD
├── src
│ └── main
│ └── java
│ └── com
│ └── example
│ ├── cmdline
│ │ ├── BUILD
│ │ └── Runner.java
│ ├── Greeting.java
│ └── ProjectRunner.java
└── WORKSPACE
Bazel ile oluşturma
Çalışma alanını ayarlama
Proje oluşturmadan önce çalışma alanını ayarlamanız gerekir. Çalışma alanı, projenizin kaynak dosyalarını ve Bazel'in derleme çıkışlarını barındıran bir dizindir. Ayrıca, Bazel'ın özel olarak tanıdığı dosyalar da içerir:
Dizini ve içeriklerini bir 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 yer alan veBUILD
dosyası içeren bir dizin, bir pakettir. Bu eğiticinin ilerleyen bölümlerinde paketler hakkında bilgi edineceksiniz.)
Bir dizini Bazel çalışma alanı olarak tanımlamak için ilgili dizinde WORKSPACE
adlı boş bir dosya oluşturun.
Bazel projeyi derlerken 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ığı sürece birbirinden bağımsızdır. Bu, bu eğiticinin kapsamının dışındadır.
BUILD dosyasını anlama
Bir BUILD
dosyası, Bazel için birkaç farklı türde talimat içeriyor.
En önemli tür, Bazel'a yürütülebilir ikili programlar veya kitaplıklar gibi istenen çıkışları nasıl oluşturacağını bildiren oluşturma kuralıdır. BUILD
dosyasındaki bir derleme kuralının her örneğine hedef adı verilir ve bu örneğin, belirli bir kaynak dosyaları ve bağımlılıklar grubuna işaret eder. Bir hedef, 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'ın yerleşik java_binary
kuralını örneklendirir. Kural, Bazel'a bir .jar
dosyası ve bir sarmalayıcı kabuk komut dosyası (her ikisi de hedeften sonra adlandırılmıştır) 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 çoğu isteğe bağlıdır. Örneğin, ProjectRunner
kural hedefinde name
, hedefin adıdır, srcs
, Bazel'ın hedefi oluşturmak için kullandığı kaynak dosyaları ve main_class
, ana yöntemi içeren sınıfı belirtir. (Örneğimizin, bir dizi kaynak dosyayı tek tek listelemek yerine Bazel'a iletmek için glob'u kullandığını fark etmiş olabilirsiniz.)
Projeyi oluşturma
Örnek projenizi oluşturmak için java-tutorial
dizinine gidin ve şu komutu çalıştırın:
bazel build //:ProjectRunner
Hedef etikette //
bölümü, BUILD
dosyasının çalışma alanının köküne göre konumudur (bu örnekte kökün kendisi). ProjectRunner
, BUILD
dosyasındaki hedef addır. (Bu eğiticinin sonunda hedef etiketler hakkında daha ayrıntılı bilgi edineceksiniz.)
Bazel, aşağıdakine benzer bir çıkış ü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 çıktılarını çalışma alanının kök kısmındaki bazel-bin
dizinine yerleştirir. Bazel'ın çıktı yapısı hakkında fikir edinmek için dosyanın içeriğine göz atın.
Şimdi yeni derlediğiniz ikili programı 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 bildirilmesini gerektirir. Bazel bu ifadeleri projenin bağımlılık grafiğini oluşturmak için kullanır. Bu grafik, doğru artımlı derlemeler yapılmasını sağlar.
Örnek projenin bağımlılıklarını görselleştirmek için Workspace kökünde şu komutu çalıştırarak bağımlılık grafiğinin metin sunumunu 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 örtülü bağımlılıklar hariç) aramasını ve çıkışı grafik olarak biçimlendirmesini bildirir.
Ardından metni GraphViz'e yapıştırın.
Gördüğünüz gibi projenin, hiçbir ek bağımlılığı olmayan iki kaynak dosya oluşturan tek bir hedefi var:
Çalışma alanınızı oluşturduktan, projenizi oluşturduktan ve bağımlılıklarını inceledikten sonra, işleri biraz 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ı derlemelere olanak tanımak (yani yalnızca değiştirilenleri yeniden oluşturmak) ve aynı anda projenin birden fazla parçasını derleyerek derlemelerinizi hızlandırmak için büyük projeleri birden fazla hedefe ve pakete bölmek isteyebilirsiniz.
Birden çok derleme hedefi belirtin
Örnek proje yapısını iki hedefe bölebilirsiniz. java-tutorial/BUILD
dosyasının içeriğini şununla 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ı oluşturmak 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 çıkış ü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 derlediğiniz ikili programı test edin:
bazel-bin/ProjectRunner
Şimdi ProjectRunner.java
dosyasını değiştirir ve projeyi yeniden derlerseniz Bazel yalnızca bu dosyayı yeniden derler.
Bağımlılık grafiğine baktığımızda, ProjectRunner
öğesinin daha önce olduğu gibi aynı girişlere bağlı olduğunu görebilirsiniz, ancak derlemenin yapısı farklıdır:
Artık projeyi iki hedefle oluşturdunuz. ProjectRunner
hedefi, iki kaynak dosya oluşturur ve bir ek kaynak dosya oluşturan bir başka 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ı ve bazı kaynak dosyalar da içerdiğini görebilirsiniz. Bu nedenle, Bazel için çalışma alanı artık //src/main/java/com/example/cmdline
ve //
olmak üzere iki paket içeriyor (çalışma alanının kökünde BUILD
dosyası olduğu için).
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 //:greeter
hedef etiketi). 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
bölgesindeki runner
hedefini //BUILD
bölgesindeki hedeflere açıkça belirtmeniz gerekir. Bunun nedeni, varsayılan olarak hedeflerin yalnızca aynı BUILD
dosyasındaki diğer hedefler tarafından görülebilmesidir. (Bazel, uygulama ayrıntılarını içeren kitaplıklar ve herkese açık API'lere sızması 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
öğesindeki 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 derleyebilirsiniz:
bazel build //src/main/java/com/example/cmdline:runner
Bazel, aşağıdakine benzer bir çıkış ü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 derlediğiniz ikili programı test edin:
./bazel-bin/src/main/java/com/example/cmdline/runner
Şimdi de projeyi, her biri bir hedef içeren iki paket halinde derlemek ve bunlar arasındaki bağımlılıkları anlamak için değiştirmiş olursunuz.
Hedeflere referans vermek için etiketleri kullanma
Bazel, BUILD
dosyalarında ve komut satırında hedeflere referans vermek için hedef etiketler kullanır (örneğin, //:ProjectRunner
veya //src/main/java/com/example/cmdline:runner
). 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. target-name
ise BUILD
dosyasında hedefi (name
özelliği) adlandırdığınız yöntemdir. Hedef bir dosya hedefiyse path/to/package
paket kök yolunun yoludur ve target-name
hedef dosyanın tam yolu ile birlikte adıdır.
Depo kökündeki hedeflere referans verirken paket yolu boştur. Yalnızca //:target-name
kullanmanız yeterlidir. Aynı BUILD
dosyasındaki hedeflere referans verirken //
çalışma alanı kök tanımlayıcısını atlayıp yalnızca :target-name
kullanabilirsiniz.
Örneğin, çalışma alanı kökünün kendisi bir paket (//
) olduğundan ve iki hedef etiketiniz sadece //:ProjectRunner
ve //:greeter
olduğundan, java-tutorial/BUILD
dosyasındaki hedefler için paket yolu belirtmeniz gerekmez.
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.
Dağıtım için bir Java hedefini paketleme
Şimdi, tüm çalışma zamanı bağımlılıklarıyla ikili program derleyerek dağıtım için bir Java hedefi paketleyelim. Bu, ikili programı geliştirme ortamınızın dışında çalıştırmanızı sağlar.
Hatırladığınız gibi, java_binary derleme kuralı bir .jar
ve bir 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
İç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
içeriyor ancak bağımlılığı Greeting.class
içermiyor. Bazel'ın oluşturduğu runner
komut dosyası, greeter.jar
dosyasını sınıf yoluna ekler. Dolayısıyla 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 ve dağıtılabilir bir ikili program derlemenize 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 çıkış ü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
programını 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
İçerik, çalışması için gerekli tüm sınıfları içermelidir:
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önetmeye yönelik kurallar için rules_jvm_external.
Harici Bağımlılıklar sayfasına göz atın.
Bazel hakkında daha fazla bilgi edinmeye yönelik diğer kurallar.
Bazel ile C++ projeleri oluşturmaya başlamak için C++ derleme eğiticisi.
Bazel ile Android ve iOS için mobil uygulama oluşturmaya başlamak için Android uygulama eğitimi ve iOS uygulama eğiticisi.
Kolay gelsin!