Создайте новое рабочее пространство с фиктивным правилом cc_binary в нем.
mkdir /tmp/bar && cd /tmp/bar
touch WORKSPACE
echo "cc_binary(name='x',srcs=['x.cc'])" > BUILD
echo -e "#include <stdio.h>\nint main(void) { return 0; }" > x.cc
Создайте фиктивную цель.
bazel build //:x
Поскольку это правило cc_ *, Bazel инициализирует цепочку инструментов C ++.Это включает в себя автоматическую генерацию файла CROSSTOOL.Это текстовый файл, описывающий интерфейс компилятора, поэтому Bazel знает, как с ним общаться.
Создайте пакет для своего пользовательского кросс-инструмента, скопируйте туда автоматически сгенерированные файлы CROSSTOOL и BUILD.
mkdir /tmp/bar/my_toolchain
touch /tmp/bar/my_toolchain/WORKSPACE
cat $(bazel info output_base)/external/local_config_cc/CROSSTOOL > /tmp/bar/my_toolchain/CROSSTOOL
cat $(bazel info output_base)/external/local_config_cc/BUILD > /tmp/bar/my_toolchain/BUILD
Мы будем использовать автоматически созданные файлы в качестве шаблонов для запуска.
Добавить правило внешнего репозитория в файл WORKSPACE.
echo "local_repository(name='my_toolchain', path='/tmp/bar/my_toolchain')" >> WORKSPACE
Таким образом, вы можете ссылаться на свой пользовательский набор инструментов с помощью метки сборки Bazel.
Попробуйте использовать свой собственный кросс-инструмент.
bazel build --crosstool_top=@my_toolchain//:toolchain //:x
Поскольку он такой же, как и сгенерированный автоматическисборка должна завершиться успешно.
Редактировать пути системных заголовков из "локальной" цепочки инструментов в пользовательском CROSSTOOL.
Примечание : вам может понадобитьсяредактировать другую цепочку инструментов, если это то, что будет выбрано.См. Выбор набора инструментов здесь: https://docs.bazel.build/versions/master/crosstool-reference.html#toolchain-selection
В текстовом редакторе откройте /tmp/bar/my_toolchain/CROSSTOOL
, найдите запись "toolchain", у которой "toolchain_identifier" является "local", и закомментируйте ее записи "cxx_builtin_include_directory" (комментарийсимвол «#»).
Затем добавьте новый «cxx_builtin_include_directory» для вашего каталога инструментов:
cxx_builtin_include_directory: "/tmp/bar/my_toolchain"
Вы только что сказали Bazel, где находятся системные заголовки, поэтому, когда он проверяет заголовоквключения, он будет знать, что заголовки по этому пути являются системными заголовками и могут быть включены.
Добавить флаг компилятора для объявления расположения системных заголовков.
Ниже только что добавленной строки "cxx_builtin_include_directory" добавьте следующее:
compiler_flag: "-isystem=/tmp/bar/my_toolchain"
Вы только что сказали Bazel сообщить компилятору, откуда он должен искать системные заголовки.
Добавьте заголовки к стандартному набору входов действий компиляции.
В текстовом редакторе откройте /tmp/bar/my_toolchain/BUILD
, найдите файловую группу "compiler_deps" и отредактируйте ее "атрибут srcs, например, так:
srcs = glob(["**/*.h"]),
Вы только что сказали Bazel всегда включать эти файлы в действия компиляции C ++, чтобы сборка работала с песочницей и удаленным выполнением, а Bazel перестроил правила C ++если какой-либо из системных заголовков (те, которые вы только что добавили в srcs
) изменился.
Создайте макет stdc-predef.h
.
Это файл заголовкакомпилятор всегда хочет включить.К счастью, компилятор сначала посмотрит на ваше значение "-isystem", а затем вернется к своему собственному пути по умолчанию (который я не знаю, можете ли вы указать его для ingore), поэтому мы можем смоделировать этот файл следующим образом:
touch /tmp/bar/my_toolchain/std-predef.h
Попробуйте построить с помощью специального кросс-инструмента.
$ bazel build --crosstool_top=@my_toolchain//:toolchain //:x
INFO: Build options have changed, discarding analysis cache.
INFO: Analysed target //:x (0 packages loaded, 61 targets configured).
INFO: Found 1 target...
ERROR: /tmp/bar/BUILD:1:1: undeclared inclusion(s) in rule '//:x':
this rule is missing dependency declarations for the following files included by 'x.cc':
'/usr/include/stdio.h'
(...)
Target //:x failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 0.332s, Critical Path: 0.09s, Remote (0.00% of the time): [queue: 0.00%, setup: 0.00%, process: 0.00%]
INFO: 0 processes.
FAILED: Build did NOT complete successfully
Поскольку в нашем каталоге инструментов нет stdio.h
, а в собственных каталогах по умолчанию компилятора есть один, он найдет файл и пожалуется на отсутствующие заголовки.Вы можете создать макет stdio.h
, чтобы заставить это замолчать.
Вы можете создать фальшивку stdio.h
, чтобы заставить сборку работать, или вы можете удалить строку #include <stdio.h>
из x.cc
.
Создать поддельный системный заголовок в пользовательской цепочке инструментов.
Мы будем использовать его для проверки того, что Bazel выбирает файлы из настраиваемой цепочки инструментов.
echo 'int foo_func(int x) { return x*2; }' > /tmp/bar/my_toolchain/foo.h
Переписать исходный файл, включив в него пользовательский системный заголовок.
echo -e '#include <foo.h>\nint main(int argc, char**) { return foo_func(argc); }' > x.cc
Выполнить повторную сборку с помощью пользовательской цепочки инструментов.Теперь все должно работать.
bazel build --crosstool_top=@my_toolchain//:toolchain //:x
Попробуйте запустить встроенный двоичный файл с двумя аргументами (поэтому argc=3
):
bazel-bin/x hello world ; echo $?
6