From 7ad316981dc103fdae2bca2e0eef51ce10d263fa Mon Sep 17 00:00:00 2001 From: Dmitrii Tcimbal Date: Wed, 19 Jun 2024 11:27:19 +1000 Subject: [PATCH] Allows to provide Lipo tool location via custom //toolchain/lipo:toolchain_type toolchain. --- rules/universal_binary.bzl | 38 ++++++++++++++++++++---- toolchain/lipo/BUILD | 4 +++ toolchain/lipo/lipo_toolchain.bzl | 48 +++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 toolchain/lipo/BUILD create mode 100644 toolchain/lipo/lipo_toolchain.bzl diff --git a/rules/universal_binary.bzl b/rules/universal_binary.bzl index 5c0eca5..f81598a 100644 --- a/rules/universal_binary.bzl +++ b/rules/universal_binary.bzl @@ -15,15 +15,15 @@ """Implementation for macOS universal binary rule.""" load("@bazel_skylib//lib:dicts.bzl", "dicts") +load("@bazel_skylib//lib:shell.bzl", "shell") load("//lib:apple_support.bzl", "apple_support") load("//lib:lipo.bzl", "lipo") load("//lib:transitions.bzl", "macos_universal_transition") def _universal_binary_impl(ctx): - inputs = [ - binary.files.to_list()[0] - for binary in ctx.split_attr.binary.values() - ] + inputs = [] + for binary in ctx.split_attr.binary.values(): + inputs += binary.files.to_list() if not inputs: fail("Target (%s) `binary` label ('%s') does not provide any " + @@ -31,7 +31,32 @@ def _universal_binary_impl(ctx): output = ctx.actions.declare_file(ctx.label.name) - if len(inputs) > 1: + lipo_toolchain = ctx.toolchains["//toolchain/lipo:toolchain_type"] + + if len(inputs) > 1 and lipo_toolchain: + lipo_tool = lipo_toolchain.info.lipo + + cmd = [ + "mkdir -p {} &&".format(shell.quote(output.dirname)), + lipo_tool.path, + "-create", + ] + cmd.extend([ + shell.quote(file.path) + for file in inputs + ]) + cmd.extend([ + "-output", + shell.quote(output.path), + ]) + + ctx.actions.run_shell( + command = " ".join(cmd), + mnemonic = "AppleLipo", + inputs = inputs + [lipo_tool], + outputs = [output], + ) + elif len(inputs) > 1: lipo.create( actions = ctx.actions, apple_fragment = ctx.fragments.apple, @@ -84,4 +109,7 @@ binary. executable = True, fragments = ["apple"], implementation = _universal_binary_impl, + toolchains = [ + config_common.toolchain_type("//toolchain/lipo:toolchain_type", mandatory = False), + ], ) diff --git a/toolchain/lipo/BUILD b/toolchain/lipo/BUILD new file mode 100644 index 0000000..c6d09a2 --- /dev/null +++ b/toolchain/lipo/BUILD @@ -0,0 +1,4 @@ +toolchain_type( + name = "toolchain_type", + visibility = ["//visibility:public"], +) diff --git a/toolchain/lipo/lipo_toolchain.bzl b/toolchain/lipo/lipo_toolchain.bzl new file mode 100644 index 0000000..ea93206 --- /dev/null +++ b/toolchain/lipo/lipo_toolchain.bzl @@ -0,0 +1,48 @@ +"""Toolchain definition to provide Lipo tool location. + +Usage: + + load("@build_bazel_apple_support//toolchain/lipo:lipo_toolchain.bzl", "lipo_toolchain") + + lipo_toolchain( + name = "_lipo_toolchain", + lipo = ":lipo", + ) + + toolchain( + name = "lipo_toolchain", + toolchain = ":_lipo_toolchain", + toolchain_type = "@build_bazel_apple_support//toolchain/lipo:toolchain_type", + exec_compatible_with = [ + "@platforms//os:macos", + ], + target_compatible_with = [ + "@platforms//os:macos", + ], + ) + +""" + +Info = provider( + fields = ["lipo"], + doc = "Tools info to locate xcode tools", +) + +def _lipo_toolchain_impl(ctx): + toolchain_info = platform_common.ToolchainInfo( + info = Info( + lipo = ctx.file.lipo, + ), + ) + return [toolchain_info] + +lipo_toolchain = rule( + doc = "Toolchain rule to provide Lipo tool location.", + implementation = _lipo_toolchain_impl, + attrs = { + "lipo": attr.label( + doc = "a label to lipo tool.", + allow_single_file = True, + ), + }, +)