#bash #bazel
#bash #bazel
Вопрос:
У меня есть два сценария оболочки. Один (a) печатает "Hello"
, а другой (b) печатает "World"
. Я хочу иметь цель Bazel (c), которая вызывает оба сценария и выдает мне "Hello World"
.
Моя попытка:
mkdir BashScriptDemo
cd BashScriptDemo
touch WORKSPACE.bazel # empty WORKSPACE file
touch BUILD.bazel # empty BUILD file
mkdir my_package
cd my_package
echo '3.5.0' > .bazelversion # use Bazel 3.5.0
echo 'echo -n "Hello"' > a.sh # echo Hello
echo 'echo " World!"' > b.sh # echo World!
echo './a.shn./b.sh' > c.sh # script c that calls a and b
chmod x a.sh b.sh c.sh
echo 'sh_binary(name="a",srcs=["a.sh"])' > BUILD.bazel
echo 'sh_binary(name="b",srcs=["b.sh"])' >> BUILD.bazel
echo 'sh_binary(name="c",srcs=["c.sh"],data=[":a", ":b"])' >> BUILD.bazel
buildifier BUILD.bazel # optional in the case you have buildifier installed
bazel run //my_package:c # Bazel is an alias to bazelisk
Когда я пытаюсь запустить скрипт, я получаю эту ошибку:
/home/user/.cache/bazel/_bazel_user/2e3943447179c1e4f0f547d49ba1444f/execroot/__main__/bazel-out/k8-fastbuild/bin/my_package/c: line 1: ./a.sh: No such file or directory
/home/user/.cache/bazel/_bazel_user/2e3943447179c1e4f0f547d49ba1444f/execroot/__main__/bazel-out/k8-fastbuild/bin/my_package/c: line 2: ./b.sh: No such file or directory
Как мне нужно изменить BUILD.bazel
файл (или любой другой файл), чтобы получить желаемый результат?
Комментарии:
1. может быть, использовать абсолютный путь? или добавьте cd my_package в скрипт
2. Рабочий каталог скрипта (на который ссылается
./
в скрипте) не имеет ничего общего с расположением скрипта; он наследуется от того, что запускает скрипт. Смотрите BashFAQ # 28 для некоторых опций о том, как найти местоположение скрипта (и, следовательно, другие файлы в том же каталоге).3. Это хороший краткий пример того, как воссоздать вашу настройку. Я приветствую вас за ваши усилия и вопрос. Однако было бы легче читать, если бы он просто показывал различные файлы в контексте.
4. @GordonDavisson проблема не в скрипте. Проблема с bazel в том, что он не может найти bash-скрипт для запуска.
Ответ №1:
runfiles.bash — предпочтительный способ поиска путей к runfiles из сценария оболочки. Документация находится в комментариях в верхней части связанного файла.
Для вашего примера это должно сделать это:
# --- 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>amp;2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
# --- end runfiles.bash initialization v2 ---
"$(rlocation my_workspace/a)"
"$(rlocation my_workspace/b)"
Вам также необходимо добавить зависимость от сценария оболочки, заменив строку в вашем BUILD.bazel
на:
sh_binary(
name = "c",
srcs = ["c.sh"],
data = [
":a",
":b",
]),
deps = ["@bazel_tools//tools/bash/runfiles"],
)
И назовите свое рабочее пространство, добавив это в свой WORKSPACE
:
workspace(name = "my_workspace")