# Copyright 2016 The Bazel Authors. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. load(":shared.bzl", "apple_action", "DARWIN_EXECUTION_REQUIREMENTS", "APPLE_FRAGMENTS") def _compute_make_variables(resolved_srcs, files_to_build): variables = {"SRCS": cmd_helper.join_paths(" ", resolved_srcs), "OUTS": cmd_helper.join_paths(" ", files_to_build)} if len(resolved_srcs) == 1: variables["<"] = list(resolved_srcs)[0].path if len(files_to_build) == 1: variables["@"] = list(files_to_build)[0].path return variables def _apple_genrule(ctx): resolved_srcs = set() if not ctx.outputs.outs: fail("apple_genrule must have one or more outputs", attr="outs") files_to_build = set(ctx.outputs.outs) if ctx.attr.executable and len(files_to_build) > 1: fail("if genrules produce executables, they are allowed only one output. " + "If you need the executable=1 argument, then you should split this " + "genrule into genrules producing single outputs", attr="executable") label_dict = {} for dep in ctx.attr.srcs: resolved_srcs += dep.files label_dict[dep.label] = dep.files resolved_inputs, argv, runfiles_manifests = ctx.resolve_command( command=ctx.attr.cmd, attribute="cmd", expand_locations=True, make_variables=_compute_make_variables(set(resolved_srcs), files_to_build), tools=ctx.attr.tools, label_dict=label_dict, execution_requirements=DARWIN_EXECUTION_REQUIREMENTS) message = ctx.attr.message or "Executing apple_genrule" env = ctx.configuration.default_shell_env env += ctx.fragments.apple.apple_host_system_env() apple_action(ctx, inputs=list(resolved_srcs) + resolved_inputs, outputs=list(files_to_build), env=env, command=argv, progress_message="%s %s" % (message, ctx), mnemonic="Genrule", input_manifests=runfiles_manifests) return struct(files=files_to_build, data_runfiles=ctx.runfiles(transitive_files=files_to_build)) _apple_genrule_inner = rule( implementation=_apple_genrule, attrs={ "srcs": attr.label_list(allow_files=True), "tools": attr.label_list(cfg="host", allow_files=True), "outs": attr.output_list(mandatory=True), "cmd": attr.string(mandatory=True), "message": attr.string(), "output_licenses": attr.license(), "executable": attr.bool(default=False), }, output_to_genfiles = True, fragments=APPLE_FRAGMENTS) """Genrule which provides Apple specific environment and make variables. This mirrors the native genrule except that it provides a different set of make variables. This rule will only run on a Mac. Example of use: load("//tools/build_defs/apple/apple_genrule.bzl", "apple_genrule") apple_genrule( name = "world", outs = ["hi"], cmd = "touch $(@)", ) This rule also does location expansion, much like the native genrule. For example, $(location hi) may be used to refer to the output in the above example. The set of make variables that are supported for this rule: OUTS: The outs list. If you have only one output file, you can also use $@. SRCS: The srcs list (or more precisely, the pathnames of the files corresponding to labels in the srcs list). If you have only one source file, you can also use $<. <: srcs, if it's a single file. @: outs, if it's a single file. The following environment variables are added to the rule action: DEVELOPER_DIR: The base developer directory as defined on Apple architectures, most commonly used in invoking Apple tools such as xcrun. """ def apple_genrule( name, cmd, executable = False, outs = [], **kwargs): if executable: if len(outs) != 1: fail("apple_genrule, if executable, must have exactly one output") intermediate_out = outs[0] + "_nonexecutable" _apple_genrule_inner( name = name + "_nonexecutable", outs = [intermediate_out], cmd = cmd, **kwargs) native.genrule( name = name, outs = outs, srcs = [intermediate_out], cmd = "cp $< $@", executable = True, ) else: _apple_genrule_inner( name = name, outs = outs, cmd = cmd, **kwargs)