В заметке рассказано как собрать и, главное, запустить и протестировать свой хелловорлд сразу под 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" ] && exitexport PATH=$PATH:`pwd`/xbps/usr/bin
arch=$1folder() {
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 \\
$ROOTecho -- 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
Тестирование хелловорлда под 17 платформ __ЛИНУКСЯТИНЫ__ одним скриптом
Даже страшно представить для какого заказчика нужно писать такой софт, который должен устойчиво великолепно везде работать. Надеюсь этот скрипт просто для забавы ради, а не от производственной необходимости.
Вот они, разработчики нового времени, которым "даже страшно представить", что их попросят писать код, работающий более чем на одной сборке одной и той же ОС..
Разработчики "старого времени" видимо до сих пор не понимают, что написание софта в 95% случаев это решение бизнес-задач, а бизнес не будет тратить свои ресурсы на поддержку ОС которыми пользуются 0.1% пользователей.
32bit, 64bit, BE, LE, остальное болото тащит только тот кто не понимает...
Можно глянуть код платформозависимого хелловорлда?
Вроде же очевидно, что хелловорлд здесь - лишь очевидный кусок кода, который будет заменен на конкретный проект, который вполне себе может быть платформозависимым.
Да бл ... Хоть одну строку напишите, которая различна на 17 платформах.
__asm__() ну или long x.
На musl и любых микро-библиотеках библиотечные strlen, strchr и т.п. могут оказаться медленными, как если написаны на чистом С, а значит - чаще смысл дублировать их, но с подгоном к контексту.
Почему бы не использовать Docker?
Вы хоть поняли о чем спросили ?
... aarch64, arm, i386, mipsel, mips, ppc64le, ppc64, ppc, x86_64 ...
Docker ? Ага chroot вам в помощь!
Не докер, а Gitlab + gitlabrunner'ы в виртуалках с разными архитектурами. Вы закоммитили, запушили код в репозиторий. Запускаются скрипты автосборки, и автотестирования. Запускаются они на раннерах с соответствующими тегами ("linux,gcc","linux,amd64","linux,arm7"). Потом можно так-же собрать .deb/.rpm и выложить куда надо.
Да это уже не хеллоуворлд, а какая-то защита диссертации. 20 гигов, серьезно???🤣
Но за труды спасибо, я хоть на С/С++ не программирую, но наверняка найдутся те, кому это понадобится. Вещь нужная.
Это вы так выкручиваетесь только чтобы на Яве не писать?
Ява мертва. По крайней мере нового на ней ничего не пишут, вакансий джунов тоже не видно даже в МСК.
Очень интересно и навороченно. А чтобы не тормозило и не убивало ССД, компилируй в рамдрайв. В /tmp хотя бы.