blob: 425a203b3676d6b745731fb19e556c5d2379d830 [file] [log] [blame]
# Copyright 2015 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.
"""Self-extracting binary.
Generate a binary suitable for self-extraction:
self_extract_binary(
name = "install.sh",
launcher = "launcher.sh",
resources = ["path1/file1", "path2/file2"],
flatten_ressources = ["path3/file3"],
)
will generate a file 'install.sh' with a header (launcher.sh)
and a ZIP footer with the following entries:
path1/
path1/file1
path2/
path2/file2
file3
"""
def _self_extract_binary(ctx):
"""Implementation for the self_extract_binary rule."""
# This is a bit complex for stripping out timestamps
zip_artifact = ctx.new_file(ctx.label.name + ".zip")
touch_empty_files = [
"mkdir -p $(dirname ${tmpdir}/%s); touch ${tmpdir}/%s" % (f, f)
for f in ctx.attr.empty_files
]
cp_resources = [
("mkdir -p $(dirname ${tmpdir}/%s)\n" % r.short_path +
"cp %s ${tmpdir}/%s" % (r.path, r.short_path))
for r in ctx.files.resources
]
cp_flatten_resources = [
"cp %s ${tmpdir}/%s" % (r.path, r.basename)
for r in ctx.files.flatten_resources
]
ctx.action(
inputs = ctx.files.resources + ctx.files.flatten_resources,
outputs = [zip_artifact],
command = "\n".join([
"tmpdir=$(mktemp -d ${TMPDIR:-/tmp}/tmp.XXXXXXXX)",
"trap \"rm -fr ${tmpdir}\" EXIT"
] + touch_empty_files + cp_resources + cp_flatten_resources + [
"find ${tmpdir} -exec touch -t 198001010000.00 '{}' ';'",
"(d=${PWD}; cd ${tmpdir}; zip -rq ${d}/%s *)" % zip_artifact.path,
]),
mnemonic = "ZipBin",
)
ctx.action(
inputs = [ctx.file.launcher, zip_artifact],
outputs = [ctx.outputs.executable],
command = "\n".join([
"cat %s %s > %s" % (ctx.file.launcher.path,
zip_artifact.path,
ctx.outputs.executable.path),
"zip -qA %s" % ctx.outputs.executable.path
]),
mnemonic = "BuildSelfExtractable",
)
self_extract_binary = rule(
_self_extract_binary,
executable = True,
attrs = {
"launcher": attr.label(
mandatory=True,
allow_files=True,
single_file=True),
"empty_files": attr.string_list(default=[]),
"resources": attr.label_list(
default=[],
allow_files=True),
"flatten_resources": attr.label_list(
default=[],
allow_files=True),
},
)