Grup Eksekusi

Laporkan masalah Lihat sumber Per Malam · 7,3 · 7,2 · 7,1 · 7,0 · 6,5

Grup eksekusi memungkinkan beberapa platform eksekusi dalam satu target. Setiap grup eksekusi memiliki dependensi toolchain mereka sendiri dan menjalankan resolusi toolchain miliknya sendiri.

Latar belakang

Grup eksekusi memungkinkan pembuat aturan mendefinisikan rangkaian tindakan, masing-masing dengan platform eksekusi yang berbeda. Beberapa platform eksekusi dapat memungkinkan tindakan untuk dieksekusi secara berbeda, misalnya mengompilasi aplikasi iOS di {i>remote<i} (linux) dan kemudian menautkan/penandatanganan kode pada pekerja mac lokal.

Mampu menentukan kelompok tindakan juga membantu mengurangi penggunaan mnemonik sebagai proxy untuk menentukan tindakan. Mnemonik tidak dijamin unik dan hanya dapat mereferensikan satu tindakan. Hal ini sangat membantu dalam mengalokasikan resource tambahan ke memori tertentu dan memproses tindakan yang intensif seperti menautkan dalam build C++ tanpa pengalokasian yang berlebihan ke tugas yang tidak terlalu rumit.

Menentukan grup eksekusi

Selama definisi aturan, penulis aturan dapat deklarasikan satu set grup eksekusi. Pada setiap grup eksekusi, penulis aturan dapat menentukan hal yang diperlukan untuk memilih platform eksekusi untuk grup eksekusi tersebut, yaitu semua batasan melalui exec_compatible_with dan jenis toolchain melalui toolchain.

# foo.bzl
my_rule = rule(
    _impl,
    exec_groups = {
        link: exec_group(
            exec_compatible_with = [ "@platforms//os:linux" ]
            toolchains = ["//foo:toolchain_type"],
        ),
        test: exec_group(
            toolchains = ["//foo_tools:toolchain_type"],
        ),
    },
    attrs = {
        "_compiler": attr.label(cfg = config.exec("link"))
    },
)

Dalam cuplikan kode di atas, Anda dapat melihat bahwa dependensi alat juga dapat menentukan transisi untuk grup {i>exec<i} menggunakan cfg parameter atribut dan config ruang lingkup modul ini. Modul ini mengekspos fungsi exec yang menggunakan satu string parameter yang merupakan nama grup exec yang dependensinya harus dibuat.

Seperti pada aturan native, grup eksekusi test ada secara default di Starlark aturan pengujian.

Pewarisan grup eksekusi

Selain menentukan batasan dan toolchain-nya sendiri, eksekusi baru suatu grup dapat mendeklarasikan bahwa grup tersebut ingin mewarisi dari eksekusi default aturan grup, dengan meneruskan parameter copy_from_rule = True. Adalah kesalahan untuk menyetel copy_from_rule ke benar (true) dan juga meneruskan exec_compatible_with atau toolchains.

Grup eksekusi yang mewarisi dari grup eksekusi default akan menyalin batasan, toolchain, dan properti eksekusi dari setelan default. Ini menyertakan batasan dan properti eksekusi yang ditetapkan pada level target, tidak hanya yang ditentukan oleh aturan itu sendiri. Dengan kata lain, dengan pertimbangan berikut:

# foo.bzl
my_rule = rule(
    _impl,
    exec_groups = {
        copied: exec_group(
            copy_from_rule = True,
            # This will inherit exec_compatible_with and toolchains.
            # Setting them here directly would be an error, however.
        ),
    },
    toolchains = ["//foo_tools:toolchain_type"],
    exec_compatible_with = ["@platforms//os:linux"],
)

# BUILD

my_rule(
    name = "demo",
    exec_compatible_with = [":local_constraint"],
)

Grup eksekusi copied untuk target demo yang dikonfigurasi akan menyertakan semua seperti: - //fool_tools:toolchain_type - @platforms//os:linux - :local_constraint

Mengakses grup eksekusi

Dalam penerapan aturan, Anda dapat mendeklarasikan bahwa tindakan harus dijalankan di platform eksekusi dari grup eksekusi. Anda dapat melakukannya menggunakan exec_group parameter metode yang menghasilkan tindakan, khususnya ctx.actions.run dan ctx.actions.run_shell.

# foo.bzl
def _impl(ctx):
  ctx.actions.run(
     inputs = [ctx.attr._some_tool, ctx.srcs[0]]
     exec_group = "compile",
     # ...
  )

Penulis aturan juga akan dapat mengakses toolchain yang telah di-resolve sama seperti cara Anda dapat mengakses toolchain target yang telah di-resolve:

# foo.bzl
def _impl(ctx):
  foo_info = ctx.exec_groups["link"].toolchains["//foo:toolchain_type"].fooinfo
  ctx.actions.run(
     inputs = [foo_info, ctx.srcs[0]]
     exec_group = "link",
     # ...
  )

Menggunakan grup eksekusi untuk menetapkan properti eksekusi

Grup eksekusi terintegrasi dengan exec_properties yang ada di setiap aturan dan memungkinkan penulis target untuk menentukan {i>string<i} dari properti yang kemudian diteruskan ke mesin eksekusi. Sebagai misalnya, jika Anda ingin menetapkan beberapa properti, katakanlah memori, untuk target dan memberi tindakan tertentu dengan alokasi memori yang lebih tinggi, Anda akan menulis exec_properties dengan kunci execution-group-augmented, seperti:

# BUILD
my_rule(
    name = 'my_target',
    exec_properties = {
        'mem': '12g',
        'link.mem': '16g'
    }
    
)

Semua tindakan dengan exec_group = "link" akan melihat properti exec sebagai {"mem": "16g"}. Seperti yang Anda lihat di sini, execution-group-level setelan menggantikan setelan tingkat target.

Grup eksekusi untuk aturan native

Grup eksekusi berikut tersedia untuk tindakan yang ditentukan oleh aturan native:

  • test: Menguji tindakan runner.
  • cpp_link: Tindakan penautan C++.

Membuat grup exec untuk menetapkan properti exec

Terkadang Anda ingin menggunakan grup {i>exec<i} untuk memberikan tindakan tertentu, {i>exec<i} yang berbeda tetapi tidak menginginkan toolchain atau batasan yang berbeda dari aturan. Untuk situasi ini, Anda dapat membuat grup exec menggunakan copy_from_rule :

# foo.bzl

# Creating an exec group with `copy_from_rule=True` is the same as explicitly
# setting the exec group's toolchains and constraints to the same values as the
# rule's respective parameters.
my_rule = rule(
    _impl,
    exec_compatible_with = ["@platforms//os:linux"],
    toolchains = ["//foo:toolchain_type"],
    exec_groups = {
        # The following two groups have the same toolchains and constraints:
        foo: exec_group(copy_from_rule = True),
        "bar": exec_group(
            exec_compatible_with = ["@platforms//os:linux"],
            toolchains = ["//foo:toolchain_type"],
        ),
    },
)

#

Grup eksekusi dan properti eksekusi platform

exec_properties dapat ditentukan untuk grup eksekusi arbitrer di target platform (tidak seperti exec_properties yang ditetapkan langsung pada target, dengan properti untuk grup eksekusi yang tidak diketahui akan ditolak). Target kemudian mewarisi exec_properties platform eksekusi yang memengaruhi grup eksekusi default dan grup eksekusi lainnya yang relevan.

Sebagai contoh, misalkan menjalankan tes C++ memerlukan beberapa sumber daya yang tersedia, tetapi tidak diperlukan untuk mengompilasi dan menautkan; hal ini dapat dimodelkan sebagai berikut ini:

constraint_setting(name = "resource")
constraint_value(name = "has_resource", constraint_setting = ":resource")

platform(
    name = "platform_with_resource",
    constraint_values = [":has_resource"],
    exec_properties = {
        "test.resource": "...",
    },
)

cc_test(
    name = "my_test",
    srcs = ["my_test.cc"],
    exec_compatible_with = [":has_resource"],
)

exec_properties yang ditentukan langsung pada target akan lebih diprioritaskan daripada yang ditentukan diwarisi dari platform eksekusi.