Сбой компоновщика в песочнице при запуске через Bazel, но работает, когда команда из песочницы выполняется из командной строки - PullRequest
0 голосов
/ 18 сентября 2018

Я пытаюсь заставить нашу кросс-цепочку (стандартную цепочку инструментов Yocto) работать с Bazel.Я следовал инструкциям на https://github.com/bazelbuild/bazel/wiki/Building-with-a-custom-toolchain, но компоновщик не работает каждый раз, когда я пытаюсь создать простую тестовую программу.Там написано

external/toolchain_e6500/sysroots/x86_64-fslsdk-linux/usr/bin/powerpc64-fsl-linux/../../libexec/powerpc64-fsl-linux/gcc/powerpc64-fsl-linux/4.9.2/real-ld: cannot find /lib64/libc.so.6
external/toolchain_e6500/sysroots/x86_64-fslsdk-linux/usr/bin/powerpc64-fsl-linux/../../libexec/powerpc64-fsl-linux/gcc/powerpc64-fsl-linux/4.9.2/real-ld: cannot find /usr/lib64/libc_nonshared.a
external/toolchain_e6500/sysroots/x86_64-fslsdk-linux/usr/bin/powerpc64-fsl-linux/../../libexec/powerpc64-fsl-linux/gcc/powerpc64-fsl-linux/4.9.2/real-ld: cannot find /lib64/ld64.so.1

sysroot настроен правильно.При запуске команды компоновщика вне песочницы (например, с --spawn_strategy=standalone или просто вручную) она работает всегда.Странно то, что когда я использую --debug_sandbox и запускаю команду emitted из командной строки, она тоже работает.

Я уже два дня отлаживаю эту проблему, включая strace.Bazel daemon и сравнение ввода real-ld, но я не нашел ничего подозрительного.

Должна быть разница между средами исполнения, но сейчас у меня нет идей.Вот ошибочная команда, напечатанная --debug_sandbox:

(cd /home/sick/.cache/bazel/_bazel_sick/2a7ae5e27644389520091aa03d045c73/execroot/__main__ && \
  exec env - \
    PATH=/home/sick/bin:/home/sick/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/sick/bin \
    PWD=/proc/self/cwd \
    TMPDIR=/tmp \
  /home/sick/.cache/bazel/_bazel_sick/2a7ae5e27644389520091aa03d045c73/execroot/__main__/_bin/linux-sandbox -t 15 -w /home/sick/.cache/bazel/_bazel_sick/2a7ae5e27644389520091aa03d045c73/sandbox/linux-sandbox/2/execroot/__main__ -w /tmp -w /dev/shm -D -- tools/compiler_e6500/e6500_gcc/powerpc64-fsl-linux-gcc -o bazel-out/e6500-fastbuild/bin/test '--sysroot=external/toolchain_e6500/sysroots/ppc64e6500-fsl-linux' -no-canonical-prefixes -pie -Wl,-z,relro,-z,now -Wl,-S -Wl,@bazel-out/e6500-fastbuild/bin/test-2.params)

Вы можете взглянуть на рабочее пространство здесь https://github.com/jasal82/bazel-cross-eval

Я могу предоставить цепочку инструментов, если это необходимо.


ОБНОВЛЕНИЕ 2018-09-25

Я провел еще несколько исследований после прочтения ответа относительно сценария компоновщика ниже.Раздел 4.4.2 в этого руководства гласит, что

В случае, если настроен префикс sysroot и имя файла начинается с символа /, а обрабатываемый скрипт расположен внутриПрефикс sysroot, имя файла будет найдено в префиксе sysroot.В противном случае компоновщик попытается открыть файл в текущем каталоге.

Очевидно, что сценарий не считается расположенным внутри префикса sysroot с помощью ld и, таким образом, используется буквально (то есть разрешается относительнок текущему каталогу, вероятно, к корню песочницы).Это объясняет наблюдаемое поведение.Однако я до сих пор не понимаю, почему этого не происходит, когда я запускаю команду вручную, то есть не через демон Bazel.

Может ли это быть связано с относительным путем sysroot, используемым в файле CROSSTOOL?Насколько я понял, вы не можете указать абсолютный путь к системному корню из-за песочницы.Каков рекомендуемый способ справиться с этим в Базеле?Я хотел бы избежать необходимости исправления набора инструментов.

1 Ответ

0 голосов
/ 24 сентября 2018

Посмотрите на lib.so в вашем системном корне.Вероятно, это выглядит примерно так:

/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( /lib/x86_64-linux-gnu/libc.so.6 /usr/lib/x86_64-linux-gnu/libc_nonshared.a  AS_NEEDED ( /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 )

Измените пути в нем относительно каталога, в котором находится libc.so. Вам придется выполнить аналогичную операцию на libm.so и libpthread.so.

Компоновщики GNU разрешают символические ссылки, прежде чем оценивать, находится ли скрипт в sysroot.Текущая реализация песочницы Bazel Linux создает ферму символических ссылок для всех входных данных действия.Таким образом, сценарий компоновщика libc.so.6 определяется как находящийся в системном корне вне песочницы, но не внутри песочницы.

...