diff --git a/docs/expand_template_doc.md b/docs/expand_template_doc.md index d40649c6..e796da7e 100755 --- a/docs/expand_template_doc.md +++ b/docs/expand_template_doc.md @@ -27,7 +27,7 @@ explicitly add delimiters to the key strings, for example "{KEY}" or "@KEY@". | :------------- | :------------- | :------------- | :------------- | :------------- | | name | A unique name for this target. | Name | required | | | out | The destination of the expanded file. | Label; nonconfigurable | required | | -| substitutions | A dictionary mapping strings to their substitutions. | Dictionary: String -> String | required | | +| substitutions | A dictionary mapping strings to their substitutions. Values are subject to ["Make" variable expansion]. | Dictionary: String -> String | required | | | template | The template file to expand. | Label | required | | - +["Make" variable expansion]: https://bazel.build/reference/be/make-variables diff --git a/rules/expand_template.bzl b/rules/expand_template.bzl index f95507ec..a83294ae 100644 --- a/rules/expand_template.bzl +++ b/rules/expand_template.bzl @@ -16,10 +16,16 @@ """ def _expand_template_impl(ctx): + substitutions = {} + for key, value in ctx.attr.substitutions.items(): + # TODO: Replace `expand_make_variables` once a suitable replacement exists. + # https://github.com/bazelbuild/bazel/issues/5859 + substitutions[key] = ctx.expand_make_variables("substitutions", value, {}) + ctx.actions.expand_template( template = ctx.file.template, output = ctx.outputs.out, - substitutions = ctx.attr.substitutions, + substitutions = substitutions, ) expand_template = rule( diff --git a/tests/expand_template/BUILD b/tests/expand_template/BUILD index 772e710b..4f973c25 100644 --- a/tests/expand_template/BUILD +++ b/tests/expand_template/BUILD @@ -62,3 +62,26 @@ cc_test( ":version", ], ) + +expand_template( + name = "make_vars_expansion", + out = "make_vars.txt", + substitutions = { + "@bindir@": "$(BINDIR)", + "@gendir@": "$(GENDIR)", + "@target_cpu@": "$(TARGET_CPU)", + }, + template = "make_vars.tpl.txt", +) + +sh_test( + name = "make_vars_test", + srcs = ["make_vars_test.sh"], + data = [ + ":make_vars_expansion", + "//tests:unittest.bash", + ], + deps = [ + "@bazel_tools//tools/bash/runfiles", + ], +) diff --git a/tests/expand_template/make_vars.tpl.txt b/tests/expand_template/make_vars.tpl.txt new file mode 100644 index 00000000..0b4942a5 --- /dev/null +++ b/tests/expand_template/make_vars.tpl.txt @@ -0,0 +1,3 @@ +BINDIR: @bindir@ +GENDIR: @gendir@ +TARGET_CPU: @target_cpu@ diff --git a/tests/expand_template/make_vars_test.sh b/tests/expand_template/make_vars_test.sh new file mode 100755 index 00000000..8a26f741 --- /dev/null +++ b/tests/expand_template/make_vars_test.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash + +# Copyright 2022 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. + +# --- begin runfiles.bash initialization v2 --- +# Copy-pasted from the Bazel Bash runfiles library v2. +set -uo pipefail; f=bazel_tools/tools/bash/runfiles/runfiles.bash +source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \ + source "$0.runfiles/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e +# --- end runfiles.bash initialization v2 --- + +source "$(rlocation $TEST_WORKSPACE/tests/unittest.bash)" \ + || { echo "Could not source bazel_skylib/tests/unittest.bash" >&2; exit 1; } + +function test_make_vars_expansion() { + cat "$(rlocation $TEST_WORKSPACE/tests/expand_template/make_vars.txt)" >"$TEST_log" + + # Verify that make variables were expanded (not literal strings) + # The expanded values should contain actual paths, not the literal "$(BINDIR)" etc. + if grep -q '\$(' "$TEST_log"; then + echo "ERROR: Make variables were not expanded" >&2 + cat "$TEST_log" >&2 + fail "Make variables should be expanded, but found literal \$(...) in output" + fi + + # Verify that each line contains the expected prefix and some non-empty value. + expect_log '^BINDIR: ..*' + expect_log '^GENDIR: ..*' + expect_log '^TARGET_CPU: ..*' +} + +run_suite "make_vars_expansion test suite"