Bu eğitim, Bazel ile Java uygulamaları oluşturma ile ilgili temel bilgileri kapsamaktadır. Çalışma alanınızı ayarlayıp 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ğitimde şunları öğreneceksiniz:
- Hedef oluşturun
- Projenin bağımlılıklarını görselleştirme
- Projeyi birden çok hedefe ve pakete bölme
- Paketler arasında hedef görünürlüğünü kontrol etme
- Etiketler aracılığıyla hedeflere referans verme
- Bir hedefi dağıtma
Başlamadan önce
Bazel'ı yükleyin
Eğiticiye hazırlanmak için öncelikle Bazel'i yükleyin (henüz yüklemediyseniz).
JDK'yi yükleyin
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'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. - "Browse Directory..." (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 pencerelerinde "Tamam"ı tıklayın.
Örnek projeyi alma
Bazel'ın 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 şekilde 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 geliştirme
Çalışma alanını ayarlama
Bir proje derlemeden ö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 Bazel çalışma alanı olarak tanımlayan ve projenin dizin yapısının kök dizininde bulunan
MODULE.bazel
dosyası,Bazel'a projenin farklı bölümlerini nasıl oluşturacağınızı açıklayan bir veya daha fazla
BUILD
dosyası. (Çalışma alanında yer alan veBUILD
dosyası içeren bir dizin, bir pakettir. Bu eğiticide daha sonra paketler hakkında bilgi edineceksiniz.)
Bir dizini Bazel çalışma alanı olarak tanımlamak için ilgili dizinde MODULE.bazel
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ıkları sürece birbirinden bağımsızdır. Bu, bu eğiticinin kapsamı 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 derleyeceğini söyleyen oluşturma kuralıdır. BUILD
dosyasındaki her derleme kuralı örneği, hedef olarak adlandırılır ve belirli bir kaynak dosya ve bağımlılık 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'in 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 birçok özellik isteğe bağlıdır. Örneğin, ProjectRunner
kural hedefinde name
hedefin adı, srcs
, Bazel'ın hedefi oluşturmak için kullandığı kaynak dosyaları ve main_class
, ana yöntemi içeren sınıfı belirtir. (Örneğimizde, kaynak dosyaları tek tek listelemek yerine Bazel'e iletmek için glob etiketinin kullanıldığı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 (bu durumda kökün kendisi) göre konumudur. 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 çıkışlarını çalışma alanının kök dizinine bazel-bin
dizinine yerleştirir. Bazel'in çı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 kullanarak doğru artımlı derlemeler sağlayan projenin bağımlılık grafiğini oluşturur.
Ö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 gösterimini 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ı (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 tek bir hedefi vardır ve bu hedef hiçbir ek bağımlılık olmadan iki kaynak dosya oluşturur:
Çalışma alanınızı oluşturduktan, projenizi derledikten ve bağımlılıklarını inceledikten sonra, biraz karmaşık hale getirebilirsiniz.
Bazel yapınızı hassaslaştırın
Küçük projeler için tek bir hedef yeterli olsa da hızlı artımlı derlemelere (yani yalnızca yapılan değişiklikleri yeniden oluşturmaya) olanak tanımak ve bir projenin birden fazla parçasını tek seferde derleyerek derlemelerinizi hızlandırmak için daha büyük projeleri birden fazla hedefe ve pakete bölmek isteyebilirsiniz.
Birden çok derleme hedefi belirtme
Örnek proje yapısını 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'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 oluşturursanız Bazel yalnızca bu dosyayı yeniden derler.
Bağımlılık grafiğine baktığınızda ProjectRunner
ürününün daha önce olduğu gibi aynı girişlere bağlı olduğunu görebilirsiniz ancak derlemenin yapısı farklıdır:
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 çok 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 (çünkü çalışma alanının kök dizininde bir BUILD
dosyası vardır).
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 //:greeter
hedef etiketi) 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
konumundaki runner
hedefini //BUILD
bölgesindeki hedeflere açıkça 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ı ö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 aşağıdaki komutu çalışma alanının kök dizininde ç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 projeyi, her biri bir hedef içeren iki paket halinde derlenecek ve bunlar arasındaki bağımlılıkları anlayacak şekilde değiştirdiniz.
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 (ö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
paketin kök dizininin yoludur. target-name
ise hedef dosyanın tam yolunu da içeren adıdır.
Depo kökündeki hedeflere başvururken paket yolu boştur. Yalnızca //:target-name
kullanmanız yeterlidir. Hatta aynı BUILD
dosyasındaki hedeflere başvururken //
çalışma alanı kök tanımlayıcısını atlayıp yalnızca :target-name
kullanabilirsiniz.
Örneğin, Workspace 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 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
içerir ancak bağımlılığını (Greeting.class
) içermez. Bazel'in 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 oluşturabilmenizi sağlar. 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ği için geliştirme ortamınızdan bağımsız olarak çalıştırabileceğiniz runner_deploy.jar
aracını 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ç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
Ayrıntılı bilgi için:
Geçişli Maven bağımlılıklarını yönetmek üzere kurallar için rules_jvm_external parametresini kullanın.
Harici Bağımlılıklar'a göz atarak yerel ve uzak depolarla çalışma hakkında daha fazla bilgi edinin.
Bazel hakkında daha fazla bilgi edinebileceğiniz diğer kurallar.
Bazel ile C++ projeleri oluşturmaya başlamayla ilgili C++ derleme eğiticisi.
Android uygulama eğitimi ve iOS uygulama eğitimi) inceleyin.
Kolay gelsin!