В заметке рассказано как собрать и, главное, запустить и протестировать свой хелловорлд сразу под 17 платформ (29 вариантов сборки, так как почти каждая платформа идёт в двух вариантах: libc и musl) не создавая зоопарк виртуалок. Все желаемое осуществляется с помощью сборочного инструментарий void-linux, за что им огромное спасибо - работа проделана огромная.Итак, что нам надо:
*** Linux, любой (я использую Mint),
*** Git (им будем ставить инструментарий для сборки исходных текстов),
*** 20+ ГБ на диске (у меня выделенный SSD, хотя все равно долго получается).
*** fuse-overlayfs
*** proot
*** qemu-static
Все остальное автоматически доставится в процессе.
++ Шаг 1: настройка основной среды.
Этот шаг полностью описан в совете "Сборка и тестирование хелловорлда под 17 платформ одним скриптом" по ссылке https://www.opennet.dev/tips/3193_build_compile_test_arm_mips...
Там же описана сборка. Следующие шаги предполагают, что шаг 1 проделан и все функционирует без ошибок.
++ Шаг 2: установка fuse-overlayfs и proot
В Linux Mint это производится с помощью "sudo apt install fuse-overlayfs proot".
fuse-overlayfs нам нужен для того, чтобы не захламлять сборочный инструментарий. Мы будем "накладывать" ваш собранный хелловорлд (и все что с ним, вы же не только один бинарный файл будете собирать?) поверх рабочей файловой системы.
proot нам нужен для создания рута (/), в котором и будет работать наша эмуляция всяких arm и mips.
++ Шаг 3: qemu.
Ставим qemu, причём нам нужны статически скомпонованные исполняемые файлы, так как мы их будем запускать в отдельном руте, не имеющем доступа к любым библиотекам хоста.
Для тестирования всех платформ нам нужны будут вот эти: qemu-aarch64-static, qemu-arm-static, qemu-i386-static, qemu-mipsel-static, qemu-mips-static, qemu-ppc64le-static, qemu-ppc64-static, qemu-ppc-static, qemu-x86_64-static.
В Linux Mint они ставятся с помощью "sudo apt install qemu-user-static".
++ Шаг 4: пути.
Создаём каталог "testing" прямо в нашем рабочем окружении (куда вы клонировали void-packages, у меня этот каталог так и называется - "void-packages"). Не будем выносить сор из избы. В этом каталоге заводим временные подкаталоги для fuse-overlayfs. Я их назвал по платформам (aarch64, armv5tel, armv7hf-musl, и т.д.)
Полный список не даю - мы их будем автоматически создавать в скрипте.
++ Шаг 5: скрипт.
Создаём вот такой, немного увесистый скрипт (ну уж извините - платформ много, под каждую надо кое-что захардкодить) в том же рабочем каталоге ("void-packages"). Я назвал его "script.sh".
Пара комментариев к скрипту (они же есть и в коде скрипта):
*** 1. Очистка обязательна. Некоторые платформы между собой конфликтуют и без очистки у вас вполне возможно бинарник не запустится.
*** 2. В скрипте считается, что ваша поделка инсталлируется как /usr/bin/helloworld. Если это не так - поправьте скрипт под себя.
*** 3. Обязательно обратите внимание на то, что версия нашего хелловорлда - "1.0". Это вписано в предыдущем совете. Если версия у вас уже другая - поменяйте путь в скрипте (найдёте его поиском).
Запускать скрипт как: "$ script.sh armv7l"
#!/bin/bash
[ -z "$1" ] && exit
export PATH=$PATH:`pwd`/xbps/usr/bin
arch=$1
folder() {
case $1 in
aarch64-musl)
echo aarch64-linux-musl;;
aarch64)
echo aarch64-linux-gnu;;
armv5tel-musl)
echo arm-linux-musleabi;;
armv5tel)
echo arm-linux-gnueabi;;
armv5te-musl)
echo arm-linux-musleabi;;
armv5te)
echo arm-linux-gnueabi;;
armv6hf-musl)
echo arm-linux-musleabihf;;
armv6hf)
echo arm-linux-gnueabihf;;
armv6l-musl)
echo arm-linux-musleabihf;;
armv6l)
echo arm-linux-gnueabihf;;
armv7hf-musl)
echo armv7l-linux-musleabihf;;
armv7hf)
echo armv7l-linux-gnueabihf;;
armv7l-musl)
echo armv7l-linux-musleabihf;;
armv7l)
echo armv7l-linux-gnueabihf;;
i686-musl)
echo i686-linux-musl;;
i686)
echo i686-pc-linux-gnu;;
mipselhf-musl)
echo mipsel-linux-muslhf;;
mipsel-musl)
echo mipsel-linux-musl;;
mipshf-musl)
echo mips-linux-muslhf;;
mips-musl)
echo mips-linux-musl;;
ppc64le-musl)
echo powerpc64le-linux-musl;;
ppc64le)
echo powerpc64le-linux-gnu;;
ppc64-musl)
echo powerpc64-linux-musl;;
ppc64)
echo powerpc64-linux-gnu;;
ppcle-musl)
echo powerpcle-linux-musl;;
ppcle)
echo powerpcle-linux-gnu;;
ppc-musl)
echo powerpc-linux-musl;;
ppc)
echo powerpc-linux-gnu;;
x86_64-musl)
echo x86_64-linux-musl;;
esac
}
qemu() {
case $1 in
aarch64-musl)
echo qemu-aarch64-static;;
aarch64)
echo qemu-aarch64-static;;
armv5tel-musl)
echo qemu-arm-static;;
armv5tel)
echo qemu-arm-static;;
armv5te-musl)
echo qemu-arm-static;;
armv5te)
echo qemu-arm-static;;
armv6hf-musl)
echo qemu-arm-static;;
armv6hf)
echo qemu-arm-static;;
armv6l-musl)
echo qemu-arm-static;;
armv6l)
echo qemu-arm-static;;
armv7hf-musl)
echo qemu-arm-static;;
armv7hf)aarch64-linux-musl
echo qemu-arm-static;;
armv7l-musl)
echo qemu-arm-static;;
armv7l)
echo qemu-arm-static;;
i686-musl)
echo qemu-i386-static;;
i686)
echo qemu-i386-static;;
mipselhf-musl)
echo qemu-mipsel-static;;
mipsel-musl)
echo qemu-mipsel-static;;
mipshf-musl)
echo qemu-mips-static;;
mips-musl)
echo qemu-mips-static;;
ppc64le-musl)
echo qemu-ppc64le-static;;
ppc64le)
echo qemu-ppc64le-static;;
ppc64-musl)
echo qemu-ppc64-static;;
ppc64)
echo qemu-ppc64-static;;
ppcle-musl)
echo qemu-ppc-static;;
ppcle)
echo qemu-ppc64le-static;;
ppc-musl)
echo qemu-ppc-static;;
ppc)
echo qemu-ppc-static;;
x86_64-musl)
echo qemu-x86_64-static;;
esac
}
ROOT=`pwd`/testing/$arch
# qemu.
# на этом шаге мы копируем бинарник qemu в наш будущий рут, чтобы fuse-overlayfs могла его не только найти, но и спокойно запустить
[ -s `pwd`/masterdir/usr/$(folder $arch)/$(qemu $arch) ] || cp `which $(qemu $arch)` `pwd`/masterdir/usr/$(folder $arch)
echo -----------------------------------------------------------------------------------------------------
echo $arch
# обязательно почистим сборку
./xbps-src -a $arch clean helloworld
# собираем. детали в прошлом совете
./xbps-src -a $arch -C pkg helloworld || exit $?
echo -- package built, lets install them -----------------------------------------------------------------
# создаём временный каталог для fuse-overlayfs
[ -d "$ROOT" ] || mkdir "$ROOT"
# накладываем собранный (и заинсталлированный тулчейном во внутренний каталог) хелловорлд на новый рут тестируемой платформы
# 1.0 - версия сборки вашего пакета. детали в предыдущем совете.
sleep 1
fuse-overlayfs \\
-o lowerdir=`pwd`/masterdir/usr/$(folder $arch) \\
-o upperdir=`pwd`/masterdir/destdir/$(folder $arch)/helloworld-1.0 \\
-o workdir=$ROOT \\
$ROOT
echo -- testing ------------------------------------------------------------------------------------------
# а вот и само тестирование - тут ваш хелловорлд для проверки может, например, сделать `system("uname -a");`
# /usr/bin/helloworld - путь, куда инсталлируется по умолчанию ваша поделка
sleep 1
proot -R $ROOT /$(qemu $arch) /usr/bin/helloworld
# вот мой вывод, например: "Linux ___ 5.4.0-99-generic #112-Ubuntu SMP Thu Feb 3 13:50:55 UTC 2022 armv7l"
echo -- done ---------------------------------------------------------------------------------------------
# и, конечно же, надо прибрать за собой.
sleep 1
fusermount -u $ROOT
++ Шаг 6: последний - автоматизация.
Делаем ещё один, финальный скрипт. Его же и дёргаем когда хотим проверить не сломали ли мы что-то в очередной раз своим новым кoдoм.
for arch in x86_64-musl \
aarch64-musl aarch64 \
armv5tel-musl armv5tel armv5te-musl armv5te armv6hf-musl armv6hf armv6l-musl armv6l armv7hf-musl armv7hf armv7l-musl armv7l \
i686-musl i686 \
mipselhf-musl mipsel-musl mipshf-musl mips-musl \
ppc64le-musl ppc64le ppc64-musl ppc64 \
ppcle-musl ppcle \
ppc-musl ppc
do
./script.sh $arch
done
++ Все.
Надеюсь, эта вполне несложная автоматизация поможет вам овладеть действительно мультиплатформенным кодингом.
URL:
Обсуждается: http://www.opennet.dev/tips/info/3201.shtml