73 lines
2.8 KiB
Python
73 lines
2.8 KiB
Python
|
# Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
|
||
|
# reserved. Use of this source code is governed by a BSD-style license that
|
||
|
# can be found in the LICENSE file.
|
||
|
|
||
|
load("//bazel/win:cc_env.bzl", "collect_compilation_env", "use_cpp_toolchain")
|
||
|
|
||
|
# Copy exe and pdb file without tracking the destination as an output.
|
||
|
# Based on https://github.com/bazelbuild/bazel-skylib/blob/main/rules/private/copy_file_private.bzl
|
||
|
def _write_copy_cmd(ctx, src, dst):
|
||
|
# Most Windows binaries built with MSVC use a certain argument quoting
|
||
|
# scheme. Bazel uses that scheme too to quote arguments. However,
|
||
|
# cmd.exe uses different semantics, so Bazel's quoting is wrong here.
|
||
|
# To fix that we write the command to a .bat file so no command line
|
||
|
# quoting or escaping is required.
|
||
|
bat = ctx.actions.declare_file(ctx.label.name + "-cmd.bat")
|
||
|
src_path = src.path.replace("/", "\\")
|
||
|
dst_path = dst.path.replace("/", "\\")
|
||
|
ctx.actions.write(
|
||
|
output = bat,
|
||
|
# Do not use lib/shell.bzl's shell.quote() method, because that uses
|
||
|
# Bash quoting syntax, which is different from cmd.exe's syntax.
|
||
|
content = "@copy /Y \"%s\" \"%s\" >NUL\n@copy /Y \"%s\" \"%s\" >NUL" % (
|
||
|
src_path,
|
||
|
dst_path,
|
||
|
src_path.replace(".exe", ".pdb"),
|
||
|
dst_path.replace(".exe", ".pdb"),
|
||
|
),
|
||
|
is_executable = True,
|
||
|
)
|
||
|
return bat
|
||
|
|
||
|
def _add_mt_impl(ctx):
|
||
|
mt_files = ctx.files.mt_files
|
||
|
input = ctx.attr.in_binary[DebugPackageInfo].unstripped_file
|
||
|
output = ctx.outputs.out_binary
|
||
|
bat = _write_copy_cmd(ctx, input, output)
|
||
|
|
||
|
inputs = mt_files + [input, bat]
|
||
|
|
||
|
# Bring over 'data' dependencies from the input.
|
||
|
deps_inputs = ctx.runfiles(files = inputs)
|
||
|
deps_inputs = deps_inputs.merge_all([ctx.attr.in_binary[DefaultInfo].default_runfiles])
|
||
|
|
||
|
ctx.actions.run(
|
||
|
executable = ctx.executable._tool,
|
||
|
inputs = deps_inputs.files,
|
||
|
outputs = [output],
|
||
|
env = collect_compilation_env(ctx),
|
||
|
# The bat file will be executed before the tool command.
|
||
|
arguments = [bat.path, "-nologo", "-manifest"] + [f.path for f in mt_files] +
|
||
|
["-outputresource:{}".format(output.path)],
|
||
|
mnemonic = "AddMT"
|
||
|
)
|
||
|
|
||
|
return DefaultInfo(files = depset([output]))
|
||
|
|
||
|
add_manifest = rule(
|
||
|
implementation = _add_mt_impl,
|
||
|
attrs = {
|
||
|
"mt_files": attr.label_list(allow_files = [".manifest"]),
|
||
|
"in_binary": attr.label(providers = [CcInfo], allow_single_file = True),
|
||
|
"out_binary": attr.output(),
|
||
|
"_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")),
|
||
|
"_tool": attr.label(
|
||
|
default = "@winsdk//:mt_pybin",
|
||
|
executable = True,
|
||
|
cfg = "exec"
|
||
|
)
|
||
|
},
|
||
|
fragments = ["cpp"],
|
||
|
toolchains = use_cpp_toolchain(),
|
||
|
)
|