blob: d39e792abd79207121b33486093383f1ebdc9cab [file] [log] [blame]
# Copyright 2018 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.
"""MIG related actions."""
load(
"//third_party/bazel_rules/apple_support/lib:apple_support.bzl",
"apple_support",
)
load(
"//third_party/bazel_skylib/lib:dicts.bzl",
"dicts",
)
load(
"//third_party/bazel_skylib/lib:paths.bzl",
"paths",
)
load("//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
_mig_suffixes = {
"user": "User.c",
"server": "Server.c",
"header": ".h",
"sheader": "Server.h",
}
_migfix_order = ["user", "server", "header", "sheader"]
_migfix_fixed_parameters = {
"user": "--fixed_user_c",
"server": "--fixed_server_c",
"header": "--fixed_user_h",
"sheader": "--fixed_server_h",
}
def _mig_generate(ctx, defs_file, defs_path = None):
if (defs_file and defs_path) or (defs_file == None and defs_path == None):
fail("_mig_generate accepts exactly one of |defs_file| and |defs_path|; " +
"%s and %s were provided." % (defs_file, defs_path))
if defs_path == None:
defs_path = defs_file.path
basename = defs_file.basename
else:
basename = paths.basename(defs_path)
raw_interface = {}
target_interface = {}
args = ["mig"]
arch = None
cpu = find_cpp_toolchain(ctx).cpu
if cpu.endswith("_arm64"):
arch = "arm64"
elif cpu.endswith("_armv7"):
arch = "armv7"
elif cpu.endswith("_x86_64"):
arch = "x86_64"
else:
fail("Could not identify CPU architecture: " + cpu)
args.extend(["-arch", arch])
defs_name = paths.split_extension(basename)[0]
for target, suffix in _mig_suffixes.items():
filename = defs_name + suffix
raw_interface[target] = ctx.actions.declare_file("raw_" + filename)
if ctx.attr.output_dir:
filename = paths.join(ctx.attr.output_dir, filename)
target_interface[target] = ctx.actions.declare_file(filename)
args.extend(["-" + target, raw_interface[target].path])
args.extend(["-isysroot", apple_common.apple_toolchain().sdk_dir()])
args.extend(["-I" + ctx.expand_location(include, ctx.attr.deps) for include in ctx.attr.include_dirs])
args.extend(["-Ithird_party/crashpad/crashpad"])
args.append(defs_path)
if defs_file:
inputs = [defs_file]
else:
inputs = []
apple_support.run(
ctx,
inputs = inputs + ctx.files.included_srcs,
outputs = raw_interface.values(),
executable = "xcrun",
arguments = args,
xcode_path_resolve_level = apple_support.xcode_path_resolve_level.args,
mnemonic = "GenerateMachInterface",
progress_message = "Generating Mach interface: %s" % basename,
execution_requirements = {"no-sandbox": "1"},
)
args = [ctx.executable._migfix.path]
for target in _migfix_order:
args.append(raw_interface[target].path)
for target, parameter in _migfix_fixed_parameters.items():
args.extend([parameter, target_interface[target].path])
ctx.actions.run_shell(
inputs = raw_interface.values(),
outputs = target_interface.values(),
progress_message = "Fixing generated interface: %s" % basename,
command = " ".join(args),
tools = [ctx.executable._migfix],
)
return target_interface
def _mig_impl(ctx):
output_files = []
src_files = []
hdr_files = []
client_files = []
server_files = []
defs_files = depset(transitive = [src.files for src in ctx.attr.srcs])
for defs_file in defs_files.to_list():
result_files = _mig_generate(ctx, defs_file)
output_files.extend(result_files.values())
for target, result_file in result_files.items():
if target.endswith("header"):
hdr_files.append(result_file)
else:
src_files.append(result_file)
if target.startswith("s"):
server_files.append(result_file)
else:
client_files.append(result_file)
for sdk_defs in ctx.attr.sdk_srcs:
defs_path = paths.join(
apple_common.apple_toolchain().sdk_dir(),
sdk_defs,
)
result_files = _mig_generate(ctx, None, defs_path)
output_files.extend(result_files.values())
for target, result_file in result_files.items():
if target.endswith("header"):
hdr_files.append(result_file)
else:
src_files.append(result_file)
if target.startswith("s"):
server_files.append(result_file)
else:
client_files.append(result_file)
return [
DefaultInfo(
files = depset(output_files),
),
OutputGroupInfo(
src_files = depset(src_files),
hdr_files = depset(hdr_files),
client_files = depset(client_files),
server_files = depset(server_files),
),
]
mig = rule(
attrs = dicts.add(apple_support.action_required_attrs(), {
"srcs": attr.label_list(
allow_files = True,
mandatory = True,
),
"included_srcs": attr.label_list(
allow_files = True,
mandatory = False,
),
"include_dirs": attr.string_list(mandatory = False),
"output_dir": attr.string(default = ""),
"deps": attr.label_list(mandatory = False),
"sdk_srcs": attr.string_list(mandatory = False),
"_cc_toolchain": attr.label(
default = Label(
"//tools/cpp:current_cc_toolchain",
),
),
"_migfix": attr.label(
cfg = "host",
executable = True,
default = Label("//third_party/crashpad/crashpad/util:mig_fix"),
),
}),
fragments = ["apple", "cpp"],
implementation = _mig_impl,
output_to_genfiles = True,
toolchains = [
"//tools/cpp:toolchain_type",
],
)