Soong Yapı Sistemi

Android 7.0 sürümünden önce Android, oluşturma kurallarını tanımlamak ve yürütmek için yalnızca GNU Make'i kullanıyordu. Make build sistemi geniş çapta destekleniyor ve kullanılıyor, ancak Android ölçeğinde yavaşladı, hataya açık, ölçeklenemez ve test edilmesi zor hale geldi. Soong derleme sistemi, Android derlemeleri için gereken esnekliği sağlar.

Bu nedenle platform geliştiricilerinin bir an önce Make'den geçip Soong'u benimsemeleri bekleniyor. Destek almak için android geliştiren Google Grubuna sorularınızı gönderin.

Soong nedir?

Soong yapı sistemi, Make'in yerini almak üzere Android 7.0'da (Nougat) tanıtıldı. Android yapılarını hızlandırmak için Kati GNU Make klon aracını ve Ninja yapı sistemi bileşenini kullanır.

Genel talimatlar için Android Açık Kaynak Projesi'ndeki (AOSP) Android Make Build System açıklamasına bakın ve Make'den Soong'a uyarlamak için gereken değişiklikler hakkında bilgi edinmek için Android.mk Yazarları için Sistem Değişiklikleri Oluşturun'a bakın.

Anahtar terimlerin tanımları için sözlükteki yapıyla ilgili girişlere ve tüm ayrıntılar için Soong referans dosyalarına bakın.

Make ve Soong karşılaştırması

Burada Soong'un aynısını Soong yapılandırma (Blueprint veya .bp ) dosyasında gerçekleştirmesiyle Make yapılandırmasının karşılaştırması verilmiştir.

Örnek yap

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := libxmlrpc++
LOCAL_MODULE_HOST_OS := linux

LOCAL_RTTI_FLAG := -frtti
LOCAL_CPPFLAGS := -Wall -Werror -fexceptions
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/src

LOCAL_SRC_FILES := $(call \
     all-cpp-files-under,src)
include $(BUILD_SHARED_LIBRARY)

Soong örneği

cc_library_shared {
     name: “libxmlrpc++”,

     rtti: true,
     cppflags: [
           “-Wall”,
           “-Werror”,
           “-fexceptions”,
     ],
     export_include_dirs: [“src”],
     srcs: [“src/**/*.cpp”],

     target: {
           darwin: {
                enabled: false,
           },
     },
}

Teste özel Soong yapılandırma örnekleri için Basit Yapı Yapılandırması'na bakın.

Android.bp dosya biçimi

Android.bp dosyaları tasarım gereği basittir. Koşullu ifadeler veya kontrol akışı ifadeleri içermezler; tüm karmaşıklık Go'da yazılmış yapı mantığı tarafından ele alınır. Mümkün olduğunda Android.bp dosyalarının sözdizimi ve anlambilimi Bazel BUILD dosyalarına benzer.

Modüller

Android.bp dosyasındaki bir modül, bir modül türü ve ardından gelen bir dizi özellik ile başlar name: "value", format:

cc_binary {
    name: "gzip",
    srcs: ["src/test/minigzip.c"],
    shared_libs: ["libz"],
    stl: "none",
}

Her modülün bir name özelliği olması gerekir ve ad alanlarındaki ve önceden oluşturulmuş modüllerdeki tekrarlanabilecek name özelliği değerleri dışında, değer tüm Android.bp dosyalarında benzersiz olmalıdır.

srcs özelliği, modülü oluşturmak için kullanılan kaynak dosyalarını bir dize listesi olarak belirtir. ": ":<module-name>" modül referans sözdizimini kullanarak genrule veya filegroup gibi kaynak dosyalar üreten diğer modüllerin çıktılarına başvurabilirsiniz.

Geçerli modül türlerinin ve özelliklerinin bir listesi için Soong Modül Referansı'na bakın.

Türler

Değişkenler ve özellikler güçlü bir şekilde yazılır; değişkenler dinamik olarak ilk atamaya dayalıdır ve özellikler modül tipine göre statik olarak ayarlanır. Desteklenen türler şunlardır:

  • Boolean'lar ( true veya false )
  • Tamsayılar ( int )
  • Dizeler ( "string" )
  • Dize listeleri ( ["string1", "string2"] )
  • Haritalar ( {key1: "value1", key2: ["value2"]}

Haritalar, iç içe haritalar da dahil olmak üzere her türde değer içerebilir. Listelerde ve haritalarda son değerden sonra virgül bulunabilir.

Küreler

srcs gibi dosyaların listesini alan özellikler aynı zamanda glob desenlerini de alabilir. Glob desenleri normal UNIX joker karakterini * içerebilir; örneğin *.java . Glob desenleri, yol öğesi olarak sıfır veya daha fazla yol öğesiyle eşleşen tek bir ** joker karakteri de içerebilir. Örneğin, java/**/*.java hem java/Main.java hem de java/com/android/Main.java kalıplarıyla eşleşir.

Değişkenler

Bir Android.bp dosyası üst düzey değişken atamaları içerebilir:

gzip_srcs = ["src/test/minigzip.c"],
cc_binary {
    name: "gzip",
    srcs: gzip_srcs,
    shared_libs: ["libz"],
    stl: "none",
}

Değişkenler, bildirildikleri dosyanın geri kalanının yanı sıra tüm alt Blueprint dosyalarının kapsamına alınır. Değişkenler bir istisna dışında değişmezdir: += atamasıyla eklenebilirler, ancak yalnızca referans verilmeden önce.

Yorumlar

Android.bp dosyaları C tarzı çok satırlı /* */ ve C++ tarzı tek satırlı // açıklamalar içerebilir.

Operatörler

+ operatörü kullanılarak dizeler, dize listeleri ve haritalar eklenebilir. Tamsayılar + operatörü kullanılarak toplanabilir. Bir haritanın eklenmesi, her iki haritadaki anahtarların birleşimini sağlar ve her iki haritada da mevcut olan anahtarların değerleri eklenir.

Şartlılar

Soong, Android.bp dosyalarındaki koşul ifadelerini desteklemez. Bunun yerine, koşullu ifadeler gerektiren oluşturma kurallarındaki karmaşıklık, üst düzey dil özelliklerinin kullanılabildiği ve koşullu ifadelerin getirdiği örtülü bağımlılıkların izlenebildiği Go'da ele alınır. Koşulların çoğu, haritadaki değerlerden birinin seçildiği ve üst düzey özelliklere eklendiği bir harita özelliğine dönüştürülür.

Örneğin mimariye özgü dosyaları desteklemek için:

cc_library {
    ...
    srcs: ["generic.cpp"],
    arch: {
        arm: {
            srcs: ["arm.cpp"],
        },
        x86: {
            srcs: ["x86.cpp"],
        },
    },
}

Biçimlendirici

Soong, Blueprint dosyaları için gofmt'ye benzer bir kanonik biçimlendirici içerir. Geçerli dizindeki tüm Android.bp dosyalarını yinelemeli olarak yeniden biçimlendirmek için şunu çalıştırın:

bpfmt -w .

Kanonik format, dört boşluklu girintileri, çok öğeli bir listenin her öğesinden sonra yeni satırları ve listelerde ve haritalarda sondaki virgül içerir.

Özel modüller

Bazı özel modül gruplarının benzersiz özellikleri vardır.

Varsayılan modüller

Aynı özellikleri birden fazla modülde tekrarlamak için bir varsayılan modül kullanılabilir. Örneğin:

cc_defaults {
    name: "gzip_defaults",
    shared_libs: ["libz"],
    stl: "none",
}

cc_binary {
    name: "gzip",
    defaults: ["gzip_defaults"],
    srcs: ["src/test/minigzip.c"],
}

Önceden oluşturulmuş modüller

Bazı önceden oluşturulmuş modül türleri, bir modülün kaynak tabanlı benzerleriyle aynı adı taşımasına izin verir. Örneğin, aynı adda bir cc_binary zaten varken, foo adında bir cc_prebuilt_binary olabilir. Bu, geliştiricilere nihai ürünlerine hangi sürümü dahil edeceklerini seçme esnekliği sağlar. Bir yapı yapılandırması her iki sürümü de içeriyorsa, önceden oluşturulmuş modül tanımındaki prefer bayrağı değeri hangi sürümün önceliğe sahip olduğunu belirler. Bazı önceden oluşturulmuş modüllerin android_app_import gibi prebuilt ile başlamayan adlara sahip olduğunu unutmayın.

Ad alanı modülleri

Android, Make'den Soong'a tamamen dönüştürülene kadar Make ürün yapılandırmasının bir PRODUCT_SOONG_NAMESPACES değeri belirtmesi gerekir. Değeri, Soong'un m komutu tarafından oluşturulmak üzere Make'e aktardığı ad alanlarının boşlukla ayrılmış bir listesi olmalıdır. Android'in Soong'a dönüşümü tamamlandıktan sonra ad alanlarının etkinleştirilmesine ilişkin ayrıntılar değişebilir.

Soong, her modül ayrı bir ad alanı içinde bildirildiği sürece, farklı dizinlerdeki modüllere aynı adı belirtme yeteneği sağlar. Bir ad alanı şu şekilde bildirilebilir:

soong_namespace {
    imports: ["path/to/otherNamespace1", "path/to/otherNamespace2"],
}

Bir ad alanının name özelliğine sahip olmadığını unutmayın; yolu otomatik olarak adı olarak atanır.

Her Soong modülüne ağaçtaki konumuna göre bir ad alanı atanır. Her Soong modülünün, geçerli dizindeki veya en yakın ata dizinindeki bir Android.bp dosyasında bulunan soong_namespace tarafından tanımlanan ad alanında olduğu kabul edilir. Eğer böyle bir soong_namespace modülü bulunamazsa, modülün örtülü kök ad alanında olduğu kabul edilir.

İşte bir örnek: Soong, I1, I2, I3… ad alanlarını içe aktaran N ad alanında M modülü tarafından bildirilen D bağımlılığını çözmeye çalışıyor.

  1. Daha sonra D //namespace:module formunun tam nitelikli adıysa, belirtilen modül adı için yalnızca belirtilen ad alanı aranır.
  2. Aksi takdirde, Soong ilk önce N ad alanında bildirilen D adlı bir modülü arar.
  3. Bu modül mevcut değilse Soong, I1, I2, I3… ad alanlarında D adında bir modül arar.
  4. Son olarak Soong kök ad alanına bakar.