Непрерывная кросс компиляция для Raspberry PI

в 17:18, , рубрики: docker, Drone, Raspberry Pi, системы сборки

Мне хотелось развернуть систему непрерывной интеграции, кросс компилирующую CMake проект написанный на c++ с OpenGL на Raspberry PI. Заодно я хотел посмотреть, не появились ли удобные серверы автоматической сборки, не содержащие в себе питона и не потребляющие сотни мегабайт ram в простое. Одна из целей написания статьи — узнать, не прошёл ли я мимо более хорошего или простого решения :)

TLDR: drone классный, позволяет добавить простенький файл в корень репозитория на github/bitbucket — и получить автоматические билды/тесты/деплой. Прямо как в Travis, но self-hosted.

Отправившись в гугл я узнал, что билд серверов удовлетворяющих моим нехитрым требованиям всего два:

  • drone.io
  • concourse.ci

Я остановился на drone.io. Выбирал по описанию, объективно сравнивать не могу.

У drone есть две версии, 0.4 и 0.5. 0.5 — это бета, выглядит немного симпатичней, но принципиально новых фичей я для себя не нашёл. Единственный баг в 0.4 исправленный в 0.5 на который я наткнулся — можно случайно через UI лишить себя флажка Administrator.

Документация по ссылке http://readme.drone.io/ — по версии 0.4. Для 0.5 — http://readme.drone.io/0.5/.

Из неочевидных нюансов — drone работает с одним из поставщиков репозиториев, таких как github, bitbucket, gogs. Причём один инстанс drone может работать только с одним источником. Это исправляется запуском нескольких независимых серверов drone, благо в простое они не тратят лишние ресурсы.
В моём случае — один drone смотрит в bitbucket, один — в gogs запущенный на том же сервере.

Я запускал drone через docker образ, выглядит это так:
Запуск:

docker run -d 
  -e REMOTE_DRIVER=bitbucket 
  -e "REMOTE_CONFIG=https://bitbucket.org?client_id=***&client_secret=***" 
  -e DRONE_DATABASE_DRIVER=sqlite3 
  -e DRONE_DATABASE_CONFIG=/var/lib/drone/drone.sqlite 
  -v /var/lib/drone_bitbucket:/var/lib/drone 
  -v /var/run/docker.sock:/var/run/docker.sock 
  -p 81:8000 
  --restart=always 
  --name=drone_bitbucket 
  drone/drone:0.4

И всё :)

Так выглядит drone после установки на сервер:
Login

По нажатию на кнопке drone отправиться за разрешениями в bitbucket, и при успехе покажет все репозитории доступные аккаунту:
repos

Изначально во вкладке Active будет пусто, все репозитории будут в Available.
Вот такая кнопка включения есть для каждого битбакет репозитория:
activate

Теперь самое интересное, сам процесс сборки :)

Процесс сборки в drone настраиваеться крайне просто.
В корне активного репозитория должен быть файл .drone.yml, описывающий как же именно собирать и деплоить содержимое репозитория.
Задаётся тэг докер образа, в котором будет происходить сборка и команды для сборки.
Весь .drone.yml для raspberry выглядит так:

build:
  image: notfl3/cross_raspberry_pi
  commands:
    - cmake -D CMAKE_BUILD_TYPE=Debug  -D CMAKE_TOOLCHAIN_FILE=/Toolchain-RaspberryPi.cmake .
    - make

publish:
  sftp:
    host: 
    port: 22
    username: ...
    password: ...
    destination_path: ...
    files:
      - ...

Самым сложным для меня местом было создание докер-образа, могущего в кросскомпиляцию для Raspberry.
В интернете есть много готовых, я же сделал свой (в основном что бы поглядеть, что это за докер вообще такой).
Выглядит он примерно так:

FROM debian:sid

RUN apt-get update
RUN apt-get install -y git
RUN apt-get install -y cmake

ENV CROSS_TRIPLE arm-linux-gnueabihf

RUN mkdir -p /rpi/tools && cd /rpi/tools && git init && git remote add -f origin https://github.com/raspberrypi/tools && 
    git config core.sparseCheckout true && echo "arm-bcm2708/gcc-linaro-${CROSS_TRIPLE}-raspbian-x64" >> .git/info/sparse-checkout && 
    git pull --depth=1 origin master

RUN mkdir -p /rpi/rootfs/opt

COPY lib/ /rpi/rootfs/lib/
COPY usr/ /rpi/rootfs/usr/
COPY opt/vc/ /rpi/rootfs/opt/vc/

COPY Toolchain-RaspberryPi.cmake /Toolchain-RaspberryPi.cmake

RUN mkdir -p /build
WORKDIR /build

Это содержимое моего Dockerfile, для того что бы создать полноценный образ, используемый для сборки — нужно положить его в одну директорию к /usr, /lib, /opt взятых с настоящего Raspbian'a и файлом Toolchain-RaspberryPi.cmake.
после команды docker build . -t notfl3/cross_raspberry_pi drone запущенный на том же сервере сможет воспользоваться этим образом и собирать наши билды.

Сама кросскомпиляция происходит согласно правилам CMake'а, единственный нюанс — я прописал свой Toolchain.cmake файл для gcc из raspberry-tools, выглядит он так:

SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)

# Where is the target environment
SET(CMAKE_FIND_ROOT_PATH /rpi/rootfs)

# Specify the cross compiler
SET(CMAKE_C_COMPILER /rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-gcc "--sysroot=${CMAKE_FIND_ROOT_PATH}")
SET(CMAKE_CXX_COMPILER /rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-g++ "--sysroot=${CMAKE_FIND_ROOT_PATH}")

# Search for programs only in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

# Search for libraries and headers only in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

INCLUDE_DIRECTORIES(${CMAKE_FIND_ROOT_PATH}/usr/include/arm-linux-gnueabihf)
INCLUDE_DIRECTORIES(${CMAKE_FIND_ROOT_PATH}/usr/include/)

С помощью этих нехитрых манипуляций я смог получить работающих билд с glfw окном для raspberry, быстро собирающийся на внешнем выделенным сервере.

Собирается, удивительно!
Res

Автор: FL3

Источник



https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js