Bu eğiticide, Bazel ile Java uygulamaları oluşturmanın temelleri açıklanmaktadır. Çalışma alanınızı ayarlayacak ve hedefler ile 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 bölme
- Paketler genelinde hedef görünürlüğünü kontrol etme
- Etiketler aracılığıyla hedeflere referans verme
- Hedef dağıtma
Başlamadan önce
Bazel'i yükleme
Eğitime hazırlanmak için Bazel'i 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..." seçeneğine gidin. .
- "Kullanıcı değişkenleri" listesinde (en üstteki) "Yeni..."yi tıklayın.
- "Değişken adı" alanına
JAVA_HOME
girin. - "Dizine Göz At..."ı 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'in GitHub deposundan 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şturabilmek için önce ç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. Ayrıca Bazel'in ö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ı,Projenin farklı bölümlerinin nasıl oluşturulacağını Bazel'e bildiren bir veya daha fazla
BUILD
dosyası. (Çalışma alanındaBUILD
dosyası içeren bir dizin paket olarak kabul edilir. Paketler hakkında daha fazla bilgiyi bu eğitimin ilerleyen bölümlerinde edineceksiniz.)
Bir dizini Bazel çalışma alanı olarak belirlemek için bu dizinde MODULE.bazel
adlı boş bir dosya oluşturun.
Bazel projeyi oluşturduğunda tüm girişler ve bağımlılıklar aynı çalışma alanında olmalıdır. Farklı çalışma alanlarında bulunan dosyalar, bu eğitimin kapsamı dışında olan bağlantı oluşturma işlemi yapılmadığı sürece birbirinden bağımsızdır.
BUILD dosyasını anlama
Bir BUILD
dosyası, Bazel için çeşitli talimat türleri içerir.
En önemli tür, derleme kuralıdır. Bu kural, Bazel'e yürütülebilir ikili dosyalar veya kitaplıklar gibi istenen çıktıların nasıl oluşturulacağını söyler. BUILD
dosyasındaki her derleme kuralı örneğine hedef denir ve belirli bir kaynak dosyaları ve bağımlılıkları kümesini gösterir. Bir hedef, diğer hedefleri de işaret edebilir.
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ı oluşturur. Kural, Bazel'e .jar
dosyası ve sarmalayıcı kabuk komut dosyası (her ikisi de hedefle aynı ada sahip) 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'in hedefi oluşturmak için kullandığı kaynak dosyaları belirtir ve main_class
, ana yöntemi içeren sınıfı belirtir. (Örneğimizde, kaynak dosyaları tek tek listelemek yerine Bazel'e aktarmak için glob işlevinin 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 etiketteki //
bölümü, BUILD
dosyasının çalışma alanının köküne (bu örnekte kök kendisidir) göre konumu, ProjectRunner
ise BUILD
dosyasındaki hedef adıdır. (Hedef etiketler hakkında daha ayrıntılı bilgiyi bu eğitimin sonunda bulabilirsiniz.)
Bazel, aşağıdakine benzer bir çıktı ü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ündeki bazel-bin
dizinine yerleştirir. Bazel'in çıkış yapısı hakkında fikir edinmek için içeriğine göz atın.
Şimdi yeni oluşturduğunuz ikili dosyayı 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 kullanarak projenin bağımlılık grafiğini oluşturur. Bu grafik, doğru artımlı derlemeler yapılmasını sağlar.
Örnek projenin bağımlılıklarını görselleştirmek için çalışma alanının kök dizininde ş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'e //:ProjectRunner
hedefinin tüm bağımlılıklarını (ana makine ve örtülü 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ıklar olmadan iki kaynak dosyası oluşturan tek bir hedef var:
Çalışma alanınızı ayarladıktan, projenizi oluşturduktan ve bağımlılıklarını inceledikten sonra biraz karmaşıklık ekleyebilirsiniz.
Bazel derlemenizi hassaslaştırma
Küçük projeler için tek bir hedef yeterli olsa da daha büyük projeleri birden fazla hedef ve pakete bölmek isteyebilirsiniz. Böylece hızlı artımlı derlemeler (yani yalnızca değişenleri yeniden derleme) yapabilir ve bir projenin birden fazla bölümünü aynı anda derleyerek derleme işlemlerinizi hızlandırabilirsiniz.
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 dosyasını oluşturur. java_binary
içindeki deps
özelliği, Bazel'e ProjectRunner
ikilisinin oluşturulması 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 bir çıktı ü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 oluşturduğunuz ikili dosyayı test edin:
bazel-bin/ProjectRunner
Şimdi ProjectRunner.java
dosyasını değiştirip projeyi yeniden oluşturursanız Bazel yalnızca bu dosyayı yeniden derler.
Bağımlılık grafiğine baktığınızda ProjectRunner
öğesinin, daha önce olduğu gibi 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 iki kaynak dosyası oluşturur ve bir başka hedefe (:greeter
) bağlıdır. Bu hedef ise bir ek kaynak dosyası oluşturur.
Birden fazla paket kullanma
Şimdi projeyi birden fazla pakete bölelim. src/main/java/com/example/cmdline
dizinine baktığınızda, bu dizinde BUILD
dosyasının yanı sıra bazı kaynak dosyalarının da bulunduğunu 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 BUILD
dosyası var).
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 (bu nedenle 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 runner
hedefinin//src/main/java/com/example/cmdline/BUILD
, visibility
özelliğini kullanarak //BUILD
içindeki hedeflere görünürlüğünü açıkça vermeniz gerekir. Bunun nedeni, varsayılan olarak hedeflerin yalnızca aynı BUILD
dosyasındaki diğer hedeflere görünür olmasıdır. (Bazel, hedef görünürlüğünü kullanarak kitaplıkların herkese açık API'lere sızan uygulama ayrıntılarını içermesi gibi sorunları önler.)
Bunu yapmak için visibility
özelliğini java-tutorial/BUILD
içindeki greeter
hedefine aşağıdaki şekilde ekleyin:
java_library(
name = "greeter",
srcs = ["src/main/java/com/example/Greeting.java"],
visibility = ["//src/main/java/com/example/cmdline:__pkg__"],
)
Şimdi, ç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 bir çıktı ü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 oluşturduğunuz ikili dosyayı test edin:
./bazel-bin/src/main/java/com/example/cmdline/runner
Artık projeyi, her biri bir hedef içeren iki paket olarak oluşturacak şekilde değiştirdiniz ve aralarındaki bağımlılıkları anlıyorsunuz.
Hedeflere referans vermek için etiketleri kullanma
Bazel, BUILD
dosyalarında ve komut satırında hedeflere referans vermek için hedef etiketlerini kullanır. Örneğin, //: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 yolu, target-name
ise BUILD
dosyasında hedefe verdiğiniz addır (name
özelliği). Hedef bir dosya hedefiyse path/to/package
, paketin kökünün yolu, target-name
ise tam yolu da dahil olmak üzere hedef dosyanın adıdır.
Depo kökündeki hedeflere referans verirken paket yolu boş olur. Bu durumda yalnızca //:target-name
kullanın. 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, java-tutorial/BUILD
dosyasındaki hedefler için bir paket yolu belirtmeniz gerekmiyordu. Çünkü çalışma alanı kökü, kendisi bir paketti (//
) ve iki hedef etiketiniz yalnızca //:ProjectRunner
ve //:greeter
idi.
Ancak //src/main/java/com/example/cmdline/BUILD
dosyasındaki hedefler için //src/main/java/com/example/cmdline
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, tüm çalışma zamanı bağımlılıklarıyla ikili dosya oluşturarak dağıtım için bir Java hedefi paketleyelim. Bu, ikili dosyayı geliştirme ortamınızın dışında çalıştırmanıza olanak tanır.
Hatırlayacağınız gibi, java_binary derleme kuralı bir .jar
ve bir sarmalayıcı kabuk komut dosyası oluşturur. runner.jar
içeriğine göz atmak için şu komutu kullanın:
jar tf bazel-bin/src/main/java/com/example/cmdline/runner.jar
İçerikler:
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
öğesini içeriyor ancak bağımlılığı olan Greeting.class
öğesini içermiyor. Bazel'in oluşturduğu runner
komut dosyası, sınıf yoluna greeter.jar
ekler. Bu nedenle, 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 oluşturmanıza olanak tanır. Bunu oluşturmak için hedef adına _deploy.jar
ekleyin:
bazel build //src/main/java/com/example/cmdline:runner_deploy.jar
Bazel, aşağıdakine benzer bir çıktı ü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
adlı bir uygulama oluşturdunuz. Bu bağımsız JAR'ın içeriğine daha önce kullandığınız komutla göz atın:
jar tf bazel-bin/src/main/java/com/example/cmdline/runner_deploy.jar
İçerikler, aşağıdakileri çalıştırmak 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 rules_jvm_external.
Yerel ve uzak depolarla çalışma hakkında daha fazla bilgi edinmek için Harici Bağımlılıklar.
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 üzere Android uygulama eğitimini ve iOS uygulama eğitimini inceleyin.
İyi inşa etmeler!