| # 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), |
| }, |
| ) |