Sitemap
Ece Akıllı Arıöz

Ece Akıllı Arıöz

Gradle nedir?

7 min readNov 22, 2024

--

Herkese merhabalar efendim,

Android geliştirme yapan arkadaşlarımın hemen hemen her gün ilgilendikleri, karşılaştıkları kimi arkadaşımında aman buraları çok karıştırmayalım düşüncesine kapılıp ufak tefek dokunuşlarla kaçtıkları Gradle mevzusunu biraz irdeleyelim derim. Buyurun iyi okumalar dilerim 🤗

Gradle, açık kaynaklı, hızlı ve uyarlanabilir bir yapı (build) aracıdır. ‘Gradle build etmek’ olarak da ifade edilmesinden aşina olabilirsiniz. Android projelerinde sıkça kullanılır ve Android Gradle Plugin (AGP) ile entegre çalışır. Uygulamanın başlangıcındaki kodları derlemekten başlayıp ta ki APK/AAB oluşumuna kadar tüm süreçte devrededir.

  • Derleme, bağımlılık yönetimi, test çalıştırma ve APK/AAB üretme gibi görevleri otomatikleştirir.

Desteklenen diller : Gradle, Android, Java, Kotlin Multiplatform, Groovy, Scala, Javascript ve C/C++’ı destekler.

Uyumlu IDE’ler : Android Studio, IntelliJ IDEA, Visual Studio Code, Eclipse ve NetBeans dahil olmak üzere tüm büyük IDE’ler Gradle’ı destekler.

Ara bir anekdot da iliştireyim buraya 😊

Android Studio’da projelerde Gradle Wrapper aktif ise (örneğin gradlew dosyası mevcutsa), gradle için herhangi bir kurulum gerekmemektedir. Proje oluşturulduğunda uygun Gradle sürümünü indirir ve çalıştırır. Eğer Gradle Wrapper mevcut değil ise manuel kuruluma ihtiyaç vardır. (gradle-wrapper.properties dosyası gerekli gradle sürümünün belirtildiği yerdiraynı zamanda platform uyumluluğunu da yönetir. ‘gradle wrapper’ komutu ile oluşturulur.)

Evett, şimdi projemizin biraz daha derinlerine inerek sohbetimizi koyulaştıralım. Projemizi dosya dizinlerini incelediğimizde farklı isimlendirmelerle gradle dosyaları görürüz. Bunun sebebi; Gradle, projeleri yapılandırmak ve yönetmek için farklı dosyalar kullanmasıdır. Her bir dosyanın belirli bir görevi vardır ve bu görevler bir araya gelerek projenin başarılı bir şekilde inşa(build) edilmesini sağlar. Android projelerinde Gradle yapılandırmasında kullanılan temel dosyalara hadi birlikte göz atalım…

  • settings.gradle: Alt modüllerin listesini burada tanımlarız. Aynı zamanda eklentilerin(plugins) ve bağımlılıkların(dependencies) hangi depolardan kullanacağımızı belirttiğimiz gradle dosyasıdır.
  • gradle.properties: Proje genelindeki Gradle ayarlarının olduğu dosyadır. Performans ve genel yapılandırma ayarlarını barındırır.
  • build.gradle(project seviyesinde): Tüm projeye ait tüm modüllerin ayarları ve bağımlılıkları bulundurur. Pluginleri ve ilgili sürümlerini burada tanımlarız.(Android Gradle Plugin (AGP) sürümü burada tanımlanır). Bu şekilde tüm modüller için tek bir yerden plugin ve dependency yapılandırmasını sağlar.
  • build.gradle(module seviyesinde): Projemizin her bir modüle ait ayarları içerir. Spesifik ayarlar, bağımlılıklar ve build türlerinin tanımlandığı Gradle dosyasıdır.

Bu dosyaların nasıl yapılandırıldığını ve hangi görevleri üstlendiğini biraz olsa giriş seviyesinde anladığımızı düşünüyorum. Module seviyesindeki build.gradle dosyasını birlikte daha yakından inceleyelim istiyorum. O halde daha yeni başlıyoruz diyebilir miyiz ?

‘‘build.gradle’’ detayları…

Çoklu modüle sahip bir projede dosya dizininin nasıl olduğuna dair fikir sahibi olmanız için aşağıdaki görsel yardımcı olacaktır.

Press enter or click to view image in full size

Hatta yeri gelmişken, modulleri settings.gradledosyasına nasıl eklediği konusunda aşağıdaki kod satırını örnek alabilriz.

// settings.gradle.kts
include("mobile-app", "web-app", "api", "lib", "documentation")

Şimdi build.gradleiçerisindeki kod bloklarını tek tek inceleyelim…

1. Plugins Bloğu

// build.gradle.kts
plugins {
alias(libs.plugins.com.android.application)
alias(libs.plugins.org.jetbrains.kotlin.android)
}

Projeye bu şekilde pluginler dahil edilir. ‘alias’ ile eklenmesinin sebebi libs.versions.toml dosyasındaki kütüphaneleri ve versionlar burada tutulur. Örneğini de yazımın sonuna doğru paylaşacağım.

2. Android Bloğu

Bu blok, uygulama özelliklerini, SDK sürümlerini, build türlerini, flavor’ları ve diğer birçok yapılandırmayı tanımlar.

  • DefaultConfig : Uygulamanın kimliğini barındırır. Version bilgileri buradan güncellenir.

android {
namespace = "com.example.myapp" // Benzersiz alan adı
compileSdk = 34 // Derleme için kullanılan Android SDK sürümü

defaultConfig {
applicationId = "com.example.myapp" // Uygulama kimliği
minSdk = 25 // Minimum desteklenen Android sürümü
targetSdk = 34 // Hedef Android sürümü
versionCode = 1 // Versiyon kodu
versionName = "1.0" // Versiyon adı
}
}
  • SigningConfig: Yayın sürümü için imza anahtarlarının bilgisi tanımlanır.
/* 
APK/ABB paketi çıkmadan önce eğer projeniz için key.jks dosyası oluşturulmuş
ve gradle dosyanızda bu alan mevcut ise ilgili alanları doldurup .jks dosyasını
import etmelisiniz
*/
signingConfigs { // Yayın sürümü için imzalama anahtarlarını tanımlar
release {
storeFile file("my-release-key.jks")
storePassword "password"
keyAlias "keyAlias"
keyPassword "keyPassword"
}
}
  • BuildTypes : Projelerimizde farklı ortamlara ve gereksinimlere göre yapılandırmaları özelleştiren bir özelliktir. Peki tam olarak nedir bu özelleştirme örnekler üzerinde ilerleyelim. Hepimizin bildiği üzere en çok karşılaştığımız ‘debug’ ve ‘release’ yapıları vardır.

debug : geliştirme sırasında geliştiricinin test odaklı, hata ayıklama veya extra bilgi için kullandığı sürümdür.

release : yayımlanmak için olup kullanıcılar için oluşturulan sürümdür.

Bu buildType larımızı özelleştirmek konusuna gelince ilgili kodlara bakalım.

buildTypes {
debug {
applicationIdSuffix = ".debug" // Debug sürümü için ID eklemesi
versionNameSuffix = "-DEBUG" // Debug sürümü için sürüm adı eklemesi
minifyEnabled = false // Kod küçültme kapalı
isDebuggable = true // Hata ayıklama aktif
}
release {
minifyEnabled = true // Kod küçültme aktif
shrinkResources = true // Gereksiz kaynakları kaldırır
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig = signingConfigs.release // İmzalama yapılandırması
isDebuggable = false // Hata ayıklama kapalı
zipAlignEnabled = true // APK boyut optimizasyonu
}
}

İhtiyacınıza göre ilgili kodları kullanabilirsiniz. Hala Android bloğu içerisinde olduğumuzu hatırlatmak isterim.

ProductFlavors : Projelerimizde birden fazla sürümü oluşturmak için kullanırız. Bu farklı ortamlara bakan veya bazı uygulamaların ücretli ve ücretsiz olduğu durumlarda ki sürümleri de buradan oluşturabiliriz. Böylelikle aynı projenin birden fazla farklı sürümlerimiz olur. <product-flavor><Build-Type>‘a göre adlandırır (örn:com.example.app.free.staging) sonrasında ihtiyacına göre APK/AAB alabilirsiniz.

 flavorDimensions "version", "environment" // İki dimension
productFlavors {
// Version Dimension
free {
dimension "version"
applicationIdSuffix ".free"
versionNameSuffix "-FREE"
}
pro {
dimension "version"
applicationIdSuffix ".pro"
versionNameSuffix "-PRO"
}

// Environment Dimension
pilot {
dimension "environment"
buildConfigField "String", "BASE_URL", '"https://api.dev.example.com/"'
resValue("string", "app_name", "MyApp-PİLOT")
}
staging {
dimension "environment"
buildConfigField "String", "BASE_URL", '"https://api.staging.example.com/"'
}
prod {
dimension "environment"
buildConfigField "String", "BASE_URL", '"https://api.example.com/"'
resValue("string", "app_name", "MyApp-PROD")
}
}

Dimension kullanarak flavor’ları gruplara ayırabiliyoruz. Birden fazla dimension tanımlayarak kombinasyon oluşturabilirsiniz. resValue ile uygulamanın sürümlerine göre isimlendirme yapabilirsiniz.

Get Ece Akıllı Arıöz’s stories in your inbox

Join Medium for free to get updates from this writer.

Şimdi bir noktaya dikkat çekmek istiyorum. BuildType ve ProductFlavor birbirlerine benzer parametreler ile karşılaşıyoruz. Her ikiside derleme ve dağıtma süreçlerini yönetmek için kullanıyoruz.(örn: buildConfigField, resvValue, applicationIdSuffix gibi ayarlar her ikisi için de özelleştirilebilir.)

⚒️ Build Variants terimi

Android projelerinde oluşturulan her bir uygulama sürümünü temsil etmektedir. Bir Build Variant, projedeki Build Types ile Product Flavors kombinasyonlarından oluşur. Şimdi paylaşacağım ekran görüntüsü ile daha net anlayacaksınız.

Press enter or click to view image in full size

BuildTypes : debug, release
ProductFlower : pilot, prod, staging

Bu şekilde her bir variant için bir APK/ABB oluşturabiliriz. Böylelikle kolay ortam yönetimini bize sunmuş olur.

3. Dependencies Bloğu

Dependencies (Bağımlılıklar); Gradle build dosyasında bir projede kullanılacak kütüphaneleri, modülleri veya araçları tanımlamak için kullanırız. Bir Android projesinde dependencies bloğu, uygulamanın ihtiyaç duyduğu tüm bağımlılıkları yönetir. Gradle, bu bağımlılıkları indirir ve projenize entegre eder. Bu şekilde kodunuzda ihtiyacınız doğrultusunda kullanabilirsiniz.

Bildiğiniz üzere yakın geçmişimize bakarsak çoğunlukla bağımlılıkları implement etmek istediğimiz sadece bu bloğun içerisinde tek bir yerden yapılabiliyor. Örneğin;

dependencies {
implementation("org.codehaus.groovy:groovy:3.0.5")
implementation("org.codehaus.groovy:groovy-json:3.0.5")
implementation("org.codehaus.groovy:groovy-nio:3.0.5")
}

Bu kullanım da doğrudur. Fakat yapısal farklı bağımlılık tanımlama konusundan bahsedeceğim. (Aynı bağımlılıkları kullanacağız.)

“Gradle Version Catalog”

Geleneksel bağımlılık tanımlama yöntemine göre bazı avantajlar sunar.
Bağımlılıkları doğrudan dize gösterimini kullanarak belirtmek yerine, bunları bir gradle version catalog’undan tanımlanıp seçilebilir.

dependencies {
implementation(libs.groovy.core)
implementation(libs.groovy.json)
implementation(libs.groovy.nio)
}

Peki nerede benim kütüphane bilgim ve versiyonum? sorusuna cevap arayalım.

[versions] //Sürümşerin bilgisini bulunur
groovy = "3.0.5"

[libraries]
groovy-core = { module = "org.codehaus.groovy:groovy", version.ref = "groovy" }
groovy-json = { module = "org.codehaus.groovy:groovy-json", version.ref = "groovy" }
groovy-nio = { module = "org.codehaus.groovy:groovy-nio", version.ref = "groovy" }

[bundles]
groovy = ["groovy-core", "groovy-json", "groovy-nio"]

Gradle Version Catalog kullanımı kodumuzun daha okunabilir hale getiriyor . Versiyon bilgisinin merkezi olması, versiyon yönetimi için daha sağlıklı bir hal almasını sağlıyor. Bağımlılık sürümleri farklı modüllerde elle tanımlandığında, çakışmalar ve versiyon uyumsuzlukları yaşanabilir. Fakat Version Catalog, sürümlerin tutarlılığını otomatik olarak sağlar ve bu çakışma gibi durumları ortadan kaldırır. Version Catalog özelliği Gradle 7.0 ve üstü sürümlerde desteklenmektedir. Daha eski projelerde bu yöntem çalışmaz.

Kullanılan diğer terimler

  • CompileOptions : Java kaynak kodunun derlenmesi ile ilgili yapılandırmayı barındırır. Java sürüm uyumluluğu ve eski API’ler ile uyumluluğu kontrol eder.
android {
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}

sourceCompatibility : Kaynak kodun yazıldığı Java sürümünü belirtir.

targetCompatibility : Derlenen bytecode'un çalışacağı JVM sürümünü tanımlar.

  • KotlinOptions : Kotlin kaynak kodunun derlenmesi ile ilgili yapılandırmayı barındırır.
android {
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs += ["-Xopt-in=kotlin.RequiresOptIn"]
}
}
  • BuildFeatures : Projede hangi özelliklerin aktif olacağını belirler (Compose, View Binding, Data Binding vb.).
android {
buildFeatures {
compose = true
viewBinding = true
dataBinding =false
buildConfig = true
}
}
  • ComposeOptions : Jetpack Compose özelliklerini yapılandırmak için kullanılır.
android {
composeOptions {
kotlinCompilerExtensionVersion = "1.4.3"
}
}
  • PackagingOptions: APK/AAB oluşturulurken dosya paketleme ve çakışmalarla ilgili kuralları tanımlar. Kaynak dosyalarının çakışmaları burada çözülür ve gereksiz dosyaları hariç tutulabilir.
android {
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
}
  • TestOptions : Testler sırasında kullanılacak kuralları ve ayarları yapılandırır.
  testOptions {
unitTests.isReturnDefaultValues = true
}

Son olarak tüm bu geliştirmeleri tamamladığımız durumda Sync Now yapıldığında, Gradle tarafından otomatik olarak BuildConfig sınıfı oluşturulur. Bu sınıf, proje yapılandırmalarına ve build.gradle dosyasında tanımladığımız özel sabitlere erişim sağlar. Debug ve release için farklı config dosyası oluşturur.

// (DEBUG) Otomatik olarak oluşturulan BuildConfig.java dosyası
public final class BuildConfig {
public static final boolean DEBUG = true; // Debug build türü için true
public static final String APPLICATION_ID = "com.example.app"; // Uygulama ID'si
public static final String BUILD_TYPE = "debug"; // Build Type bilgisi
public static final String FLAVOR = ""; // Eğer Product Flavors varsa, flavor ismi
public static final int VERSION_CODE = 1; // Versiyon kodu
public static final String VERSION_NAME = "1.0"; // Versiyon adı

// build.gradle'da tanımlanan custom değerler
public static final String API_URL = "https://api.example.com";
}
// Debug kontrolü
if (BuildConfig.DEBUG) {
Log.d("App", "Debug modunda çalışıyor.");
}

Böylece Gradle konumuzun da sonuna geldik. Yazarken keyif aldığım bu makaleden umarım sizler için de keyifli vakit geçmiştir. Başka makalelerde buluşmak dileğiyle..

Konumuzla ilgili yardımcı olacak kaynaklar:

--

--