Эм, crossdev на x86 это ведь обычная кросс-компиляция? Я не особо знаком с терминами и инструментами Gentoo. А QEMU это уже эмуляция/виртуализация. Поэтому за счёт издержек на неё сборка будет гораздо медленнее. При виртуализации будет незначительно медленнее, при эмуляции – значительнее. Во сколько и на сколько раз сильно зависит от твоей системы, начиная от скорости RAM или SSD и заканчивая версией QEMU и используемыми в этой программе фичами вроде KVM.
Я не знаю, что такое Crossdev, это что-то специфичное для мира Gentoo. Если это обычный кросс-компилятор, то он собирать будет с примерно такой же скоростью, как и обычный компилятор. Там нет никакой виртуализации или эмуляции.
Будет медленнее раз так в 5-10, в зависимости от сырцов, если там C++ с распоследними финтифлюшками, и ядро тоже под эмулятором, то может и в 20 раз меделеннее.
Есть пара вариантов, чтобы собирать в ARM окружении, но не потерять скорость:
1. qemu-user + chroot в директорию с ARM системой где компилятор и binutils заменены на статически собранные кросс-тулзы x86 для ARM. Окружение полностью ARM, а собираться будет нативным кросс-компилятором. Можно собрать кросс и как shared но тогда придётся пересобрать libc чтобы дать другое имя ld-linux и положить x86 библиотеки в отдельную /lib-x86, чтобы они не пересекались с ARM либами.
2. qemu-user + chroot в ARM или полный qemu-system ARM но настроить в этой ARM системе distcc который будет запускать нативный кросс-компилятор на этой же или даже на нескольких машинах. Если машин с distcc - серверами несколько, и сборка хорошо параллелится, то это будет даже быстрее чем прямая кросс-компиляция.
Ну если так посмотреть, то crossdev собирает бинарники для другой платформы нативными компиляторами. Буквально неделю назад я пытался собрать компилятор для windows, собрался только 64 битный. Он не мог компилировать бинарники для 32 битной windows.
А у qemu насколько я знаю нормальной производительности можно добиться только с kvm и паравиртуализированными драйверами для гостевой системы, для разных архитектур это вроде бы не работает?
Будет медленнее раз так в 5-10, в зависимости от сырцов, если там C++ с распоследними
Примерно так и получается в chroot на небольших пакетах, медленнооо.
1. qemu-user + chroot в директорию с ARM системой где компилятор и binutils заменены на статически собранные кросс-тулзы x86 для ARM.
Это для меня слишком сложно, в принципе можно конечно разобраться, но жалко тратить время на изучение.
qemu-user + chroot в ARM или полный qemu-system ARM
Использую chroot из хоста X86 после: cp /usr/bin/qemu-arm-static $ChrootDir/usr/bin/;
но настроить в этой ARM системе distcc
А вот это ОЧЕНЬ интересный вариант! и скорее всего несложный для обучения. Даже не предполагал, что внешний CROSS можно запускать из distcc .
Может быть, посоветуете хорошие примеры в интернет по chrooted qemu-arm-static -> distcc -> CROSS на другом относительно мощном хосте ? обычные маны по distcc ненадо.
и делаешь /etc/distcc/bin/gcc, g++, cc, c++ и т.д. линками на неё.
она будет запускать лежащие там же /etc/distcc/bin/arm-*-gcc, arm-*-g++ которые являются линками уже на сам distcc. Это нужно, чтобы на distcc-сервере запускался именно arm-*-gcc а не нативный gcc при запуске команды gcc в ARM эмуляторе, например.
В /etc/distcc/hosts пишешь 127.0.0.1 (ЕМНИП localhost оно будет пытаться локально запустить) и запускаешь на машине distcc сервер, разумеется разрешив ему запускать arm-*-gcc и пр.
Можно добавить в environment DISTCC_FALLBACK=0 чтобы компиляция всегда была «удалённой». Подробнее см. man который ты не хочешь читать.
Разумеется компилятор ARM в qemu и нативный кросс должны быть из одних исходников, чтобы не напороться на практически не отлавливаемые загадочные глюки, которые могут внезапно всплыть там, где не ожидаешь.
distcc по умолчанию использует локальный препроцессор, так что совсем избавится от ARM gcc не выйдет. Но у distcc есть pump-mode о котором можно прочитать подробнее в ненавистном мане. Для pump-mode надо будет побольше постараться и обеспечить для нативного кросса доступ к системным ARM headers используемым при компиляции.
Кстати, на самом деле, именно ядро собирать в эмуляторе нет смысла, потому что оно прекрасно собирается кроссом.
Эмулятор очень полезен, когда надо собирать пакеты в которых кривые конфигураторы сборки неспособные адекватно работать с кроссом (почему-то чаще всего это попадается в проектах с cmakе и всякими новомодными meson'ами) или используется много всяких либ или в процессе используются какие-то софтины. Ставишь целевую систему в армовый chroot и там всё собирается нормально, потому что конфигуратор думает что его нативно запустили и не выпендривается.
Собираю на компе ядра для Cubietruck, используя crossdev, через qemu очень медленно. Можно так же клепать бинарные пакеты для ARM, благо crossdev представляет обертку для emerge.
Когда создашь нужный тулчей в crossdev, появится обёртка, наподобие emerge-armv7a-unknown-linux-gnueabihf, она и будет работать с //usr/armv7a-unknown-linux-gnueabihf
Но нормальные эмуляторы медленее всего в 2 раза(типа эмулятор X86 для Arm от Microsoft или эмулятор arm BlueStacks)
Но они проприетарные, но это лишь значит что у qemu есть возможности для оптимизации...
версия ядра на хосте X86, откуда делается qemu chroot в ARM userspace?
должна быть новее?
чем то, для которого собирается ARM пакет.
как определить версию ядра, для которого собирается некий пакет? например, внутри user space ARM или еще где-то?
разве пакет не собирается под любую версию ядра?
ну в каких-то разумных пределах, наверно, зависит от libc и т.п.?
я плохо разбираюсь в совместимости собранных бинарников для разных версий ядер. наверно как минимум используемые вызовы должны обеспечиваться обоими версиями ядер,
но откуда в gentoo stage3 для ARM chroot взяться вызовам новее, чем мое
внешнее ядро X86: Linux workstation 4.19.36-gnu #1.0 SMP Tue Sep 27 12:35:59 EST 1983 x86_64 GNU/Linux
Это либре деблобированное ядро, может, поэтому ошибки?
и насколько такие syscall ошибки критичны для сборки полноценных пакетов? если собирать частично через cross distcc на удаленном X86 хосте с самым свежим ядром типа v5.3, ошибок будет меньше?
версия ядра на хосте X86, откуда делается qemu chroot в ARM userspace? должна быть новее?
Такая же, либо новее. Оно ж тебе пишет, что syscall какой-то найти не может.
как определить версию ядра, для которого собирается некий пакет?
Ну какое у тебя ядро на целевой системе? Наверно под него и собраны все libc, которые дёргают ядро.
но откуда в gentoo stage3 для ARM chroot взяться вызовам новее
Ну может там библиотеки какие... Или в ядре хоста не включены какие-то фичи, которые включены для ARM. Или ещё хуже - изговняканное ARM ядро от ведроида.
Ещё может быть qemu имеет смысл обновить.
Может быть что libc для ARM собрана под ядро в котором включены syscall которых для x86 вообще нет.
Ну неужто погуглить сложно? 383 - это __NR_seccomp для ARM. На x86 оно другой номер имеет и несовместимо с армовым. Соответственно, если используется qemu-user, то армовую система должна быть собрана без seccomp. Или использовать qemu-system с ARM ядром и ARM либами в котором армовый seccomp включен.
distcc же вообще наплевать на сисколлы и ядра. Кросс-компилятор на хосте просто получит от distcc сырец уже после препроцессинга, скомпилирует его и отдаст обратно.