| #!/bin/bash |
| # |
| # Copyright 2019 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 --- |
| # Copy-pasted from Bazel's Bash runfiles library (tools/bash/runfiles/runfiles.bash). |
| set -euo pipefail |
| if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then |
| if [[ -f "$0.runfiles_manifest" ]]; then |
| export RUNFILES_MANIFEST_FILE="$0.runfiles_manifest" |
| elif [[ -f "$0.runfiles/MANIFEST" ]]; then |
| export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST" |
| elif [[ -f "$0.runfiles/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then |
| export RUNFILES_DIR="$0.runfiles" |
| fi |
| fi |
| if [[ -f "${RUNFILES_DIR:-/dev/null}/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then |
| source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.bash" |
| elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then |
| source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.bash " \ |
| "$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)" |
| else |
| echo >&2 "ERROR: cannot find @bazel_tools//tools/bash/runfiles:runfiles.bash" |
| exit 1 |
| fi |
| # --- end runfiles.bash initialization --- |
| |
| source "$(rlocation "io_bazel/src/test/shell/integration_test_setup.sh")" \ |
| || { echo "integration_test_setup.sh not found!" >&2; exit 1; } |
| |
| case "$(uname -s | tr [:upper:] [:lower:])" in |
| msys*) |
| declare -r is_windows=true |
| ;; |
| *) |
| declare -r is_windows=false |
| ;; |
| esac |
| |
| if "$is_windows"; then |
| # Disable MSYS path conversion that converts path-looking command arguments to |
| # Windows paths (even if they arguments are not in fact paths). |
| export MSYS_NO_PATHCONV=1 |
| export MSYS2_ARG_CONV_EXCL="*" |
| fi |
| |
| function _create_pkg() { |
| # Define dummy CPU and OS constraints (cpu1 and cpu2, and os1 and os2). |
| # Also define platforms for each combination. |
| mkdir "platforms" |
| cat > "platforms/BUILD" <<'eof' |
| package(default_visibility = ["//visibility:public"]) |
| |
| [constraint_value( |
| name = "cpu%d" % i, |
| constraint_setting = "@platforms//cpu", |
| ) for i in [1, 2]] |
| |
| [constraint_value( |
| name = "os%d" % i, |
| constraint_setting = "@platforms//os", |
| ) for i in [1, 2]] |
| |
| [platform( |
| name = "cpu%d_os%d" % (i, j), |
| constraint_values = [":cpu%d" % i, ":os%d" % j], |
| ) for i in [1, 2] for j in [1, 2]] |
| eof |
| |
| # Define a windows_resource_compiler_toolchain with our dummy CPUs and OSs. |
| mkdir "toolchains" |
| cat > "toolchains/BUILD" <<eof |
| package(default_visibility = ["//visibility:public"]) |
| |
| load( |
| "@io_bazel//src/main/res:winsdk_toolchain.bzl", |
| "windows_resource_compiler_toolchain", |
| "WINDOWS_RESOURCE_COMPILER_TOOLCHAIN_TYPE", |
| ) |
| |
| windows_resource_compiler_toolchain( |
| name = "tc_def", |
| rc_exe = ":rc-gen", |
| ) |
| |
| # Need a genrule because of https://github.com/bazelbuild/bazel/issues/9023 |
| genrule( |
| name = "rc-gen", |
| outs = ["rc-gen.bat"], |
| srcs = ["rc-src.bat"], |
| executable = True, |
| cmd = "cp $< \$@", |
| ) |
| |
| toolchain( |
| name = "tc", |
| exec_compatible_with = ["//platforms:cpu1", "//platforms:os1"], |
| target_compatible_with = ["//platforms:cpu2"], |
| toolchain = ":tc_def", |
| toolchain_type = WINDOWS_RESOURCE_COMPILER_TOOLCHAIN_TYPE, |
| visibility = ["//visibility:public"], |
| ) |
| eof |
| |
| # On Windows, we write a Batch script. On other platforms, a shell script. |
| # File extension must be .bat on Windows, and it doesn't matter on other |
| # platforms. |
| if "$is_windows"; then |
| cat > "toolchains/rc-src.bat" <<'eof' |
| @echo off |
| setlocal enabledelayedexpansion |
| |
| for %%i in (%*) do ( |
| set j=%%i |
| if "!j:~0,3!" == "/fo" (set out=!j:~3!) |
| if "!j:~-2!" == "rc" (set src=!j!) |
| ) |
| set out=%out:/=\% |
| echo out=%out% |
| |
| echo src=%src:/=\%>%out% |
| echo out=%out%>>%out% |
| dir /s /b /o:n *.dat>>%out% |
| eof |
| else |
| cat > "toolchains/rc-src.bat" <<'eof' |
| #!/bin/bash |
| for a in $*; do |
| if [[ "$a" =~ /fo.* ]]; then |
| out="${a#/fo}" |
| elif [[ "$a" =~ .*rc$ ]]; then |
| src="$a" |
| fi |
| done |
| |
| cat > "$out" <<EOF |
| src=$src |
| out=$out |
| $(find . -name '*.dat' | sort) |
| EOF |
| eof |
| fi |
| chmod +x "toolchains/rc-src.bat" |
| |
| # Define a windows_resources rule we'll try to build with various exec and |
| # target platform combinations. |
| cat > "BUILD" <<'eof' |
| load("@io_bazel//src/main/res:win_res.bzl", "windows_resources") |
| |
| windows_resources( |
| name = "res", |
| rc_files = ["foo.rc", "bar.rc"], |
| resources = ["res1.dat", "res2.dat"], |
| ) |
| eof |
| |
| touch foo.rc bar.rc res1.dat res2.dat |
| } |
| |
| function _symlink_res_toolchain_files() { |
| mkdir -p "src/main/res" |
| for f in BUILD win_res.bzl winsdk_configure.bzl winsdk_toolchain.bzl; do |
| real="$(rlocation io_bazel/src/main/res/$f)" |
| ln -sf "$real" "src/main/res/$f" |
| done |
| } |
| |
| function _assert_outputs() { |
| [[ -e bazel-bin/foo.res ]] || fail "missing output" |
| grep -q "src=foo.rc" "bazel-bin/foo.res" || fail "bad output" |
| grep -q "out=.*\bfoo.res" "bazel-bin/foo.res" || fail "bad output" |
| grep -q ".*\bres1.dat" "bazel-bin/foo.res" || fail "bad output" |
| grep -q ".*\bres2.dat" "bazel-bin/foo.res" || fail "bad output" |
| |
| [[ -e bazel-bin/bar.res ]] || fail "missing output" |
| grep -q "src=bar.rc" "bazel-bin/bar.res" || fail "bad output" |
| grep -q "out=.*\bbar.res" "bazel-bin/bar.res" || fail "bad output" |
| grep -q ".*\bres1.dat" "bazel-bin/bar.res" || fail "bad output" |
| grep -q ".*\bres2.dat" "bazel-bin/bar.res" || fail "bad output" |
| } |
| |
| function _assert_no_outputs() { |
| [[ -e bazel-bin/foo.res ]] && fail "unexpected output" || true |
| [[ -e bazel-bin/bar.res ]] && fail "unexpected output" || true |
| } |
| |
| function test_toolchain_selection() { |
| echo 'workspace(name = "io_bazel")' > WORKSPACE |
| _symlink_res_toolchain_files |
| _create_pkg |
| |
| # (1) Expect success: host platform matches toolchain. |
| bazel build //:res --host_platform=//platforms:cpu1_os1 \ |
| --platforms=//platforms:cpu2_os1 --extra_toolchains=//toolchains:tc \ |
| || fail "expected success" |
| _assert_outputs |
| |
| # (2) Expect failure: same as (1) but without a registered toolchain. |
| bazel clean |
| bazel build //:res --host_platform=//platforms:cpu1_os1 \ |
| --platforms=//platforms:cpu2_os1 \ |
| && fail "expected failure" || true |
| _assert_no_outputs |
| |
| # (3) Expect failure: same as (1) but host platform does not match toolchain |
| bazel build //:res --host_platform=//platforms:cpu2_os1 \ |
| --platforms=//platforms:cpu2_os1 --extra_toolchains=//toolchains:tc \ |
| && fail "expected failure" || true |
| _assert_no_outputs |
| |
| # (4) Expect failure: same as (3) with an extra execution platform, but the |
| # toolchain doesn't match. |
| bazel build //:res --host_platform=//platforms:cpu2_os1 \ |
| --platforms=//platforms:cpu2_os1 --extra_toolchains=//toolchains:tc \ |
| --extra_execution_platforms=//platforms:cpu2_os2 \ |
| && fail "expected failure" || true |
| _assert_no_outputs |
| |
| # (5) Expect success: same as (4) with a matching extra execution platform. |
| bazel build //:res --host_platform=//platforms:cpu2_os1 \ |
| --platforms=//platforms:cpu2_os1 --extra_toolchains=//toolchains:tc \ |
| --extra_execution_platforms=//platforms:cpu2_os2,//platforms:cpu1_os1 \ |
| || fail "expected success" |
| _assert_outputs |
| } |
| |
| run_suite "Tests for windows_resources() rule and toolchain selection" |