В данной статье процесс компиляции и создания пакетов для OpenWRT. Он немного устарел (описан процесс для OpenWRT Backfire), но вцелом все должно быть актуально и для новых версий.
Получение исходников OpenWrt
Поскольку для сборки мы будем использовать OpenWrt Build System то первое что необходимо сделать это получить исходный код OpenWRT. Если он у вас уже есть можно переходить к следующему пункту. Я использую OpenWrt 10.03, codename Backfire.
svn co svn://svn.openwrt.org/openwrt/branches/backfire openwrt
Должен появится каталог openwrt. Перейдем в него:
cd openwrt
В этом каталоге есть 3 ключевые директории: - toolchain - target - package
Вкратце по этим директориям:
toolchain – В этой директории содержится компилятор, библиотеки а также основные утилиты необходимые для построения и сборки образа прошивки. После выполнения команды make toolchain/install появляется директория staging_dir которая и содержит скомпилированный и установленный toolchain.
target – имеет отношение к “встроенной” embedded платформе. Содержит файлы и патчи относящиеся к различным embedded платформам. Например каталог target/linux содержит патчи и конфиги ядра специфичные для каждой платформы, а в каталоге target/image описано как именно собирать образ прошивки для той или иной платформы.
package – каталог в котором содержатся исходники, патчи и конфиги всех пакетов которые можно собрать для OpenWRT. Собственно этот каталог и нужен нам для сборки собственных приложений.
Также стоит отметить что все необходимые исходники и дополнительные файлы в процессе сборки OpenWRT загружаемые из интернета и ложатся в каталог dl, а каталог build_dir это временный каталог для сборки.
Для дальнейших шагов необходимо выполнить:
Получим исходники всех необходимях для сборки пакетов
./scripts/feeds update -a && ./scripts/feeds install -a
Соберем tools и toolchain
make prereq && make tools/install && make toolchain/install
Кросскомпиляция позволяет получить из исходников исполняемый файл под нужную платформу.
Для того чтобы исходник компилировался под нужную нам платформу достаточно вставить в Makefile директивы с указанием правильно компилятора. Мануал Openwrt предписывает нам скомпилировать среду для разработки, затем в директории ./staging_dir/toolchain-…../bin/ найти компилятор под нужную платформу и указать на него в Makefile директивами CC и LD. Это можно сделать так:
PATH=$PATH:/home/mike/backfire/staging_dir/toolchain-mipsel_gcc-4.3.3+cs_uClibc-0.9.30.1/bin/ export PATH STAGING_DIR=/home/mike/backfire/staging_dir export STAGING_DIR
А в Makefile указать компилятор. Если export работает нормально, то указывать можно и без полных путей. У меня export тупил и я написал с полными путями:
CC = /home/mike/backfire/staging_dir/toolchain-mipsel_gcc-4.3.3+cs_uClibc-0.9.30.1/bin/mipsel-openwrt-linux-uclibc-gcc LD = /home/mike/backfire/staging_dir/toolchain-mipsel_gcc-4.3.3+cs_uClibc-0.9.30.1/bin/mipsel-openwrt-linux-uclibc-ld all: autosys %.o: %.c $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -I. -Iinclude -o $@ $^ autosys: main.o $(CC) -o $@ $^ -L. clean: rm -f *.o autosys
А дальше просто make и все…
Итак нам нужен каталог package
cd package
Создадим в нем директорию simple и simple/src
mkdir simple mkdir simple/src cd simple/src
Добавление исходников
В каталог simple/src положим исходник нашего приложения. Создадим файл main.c в simple/src директории с текстом:
#include int main(void) { int i=0; while (i < 100) { printf(" Hello world %d \n",i); i++; } return 0; }
Далее подготовим Makefile для компиляции main.c в каталоге simple/srс с таким содержимым (отступы делать табуляцией)
# build executable on typing make all: simple %.o: %.c $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -I. -Iinclude -o $@ $^ simple: main.o $(CC) -o $@ $^ -L. clean: rm -f *.o simple
Все исходник готов. Можно проверить как он собирается и выполняется на локальной машине (обратите внимание это пока не кросс компиляция):
$ make cc -c -I. -Iinclude -o main.o main.c cc -o simple main.o -L. $ ./simple Hello world 0 Hello world 1 ... Hello world 99
Исходник собрался под host платформу без проблем, перейдем к сборке под embedded платформу. Для этого вначале почистим исходники:
make clean
Поднимемся в директорию package/simple:
cd ..
Создадим следующий Makefile:
# # Top level makefile for simple application # include $(TOPDIR)/rules.mk PKG_NAME:=simple PKG_VERSION:=1.0.0 PKG_RELEASE:=1 include $(INCLUDE_DIR)/package.mk define Package/simple SECTION:=utils CATEGORY:=Utilities TITLE:=simple -- prints simple 1 to 99 endef define Build/Prepare mkdir -p $(PKG_BUILD_DIR) $(CP) ./src/* $(PKG_BUILD_DIR) endef define Build/Configure endef TARGET_CFLAGS += $(FPIC) define Package/simple/install $(INSTALL_DIR) $(1)/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/simple $(1)/bin/ endef $(eval $(call BuildPackage,simple))
Как видно этот файл не очень сложный но необходимо знать значения следующих переменных:
PKG_NAME – Имя пакета, которое будет видно в menuconfig и ipkg/opkg PKG_VERSION – Версия пакета PKG_RELEASE – Версия Makefile этого пакета PKG_BUILD_DIR – Директория для компилирования пакета PKG_SOURCE – Имя файла оригинальных исходников
PKG_SOURCE_URL – URL загрузки оригинальных исходников PKG_MD5SUM – MD5 – checksum для проверки загрузки PKG_CAT – Чем распаковывать исходники (zcat, bzcat, unzip)
Как видно не все из этих переменных обязательны. Наиболее важными секциями являются секции define Package/_name_ и define Package/_name_/install:
Секция описывает пакет для menuconfig и ipkg/opkg.
SECTION – Тип пакета (на текущий момент не используется) CATEGORY – В каком меню должно находится приложение в menuconfig TITLE – Короткое описание пакета DESCRIPTION – Длинное описание пакета URL – URL исходного приложения MAINTAINER – (не обязательно) Контактные данные дева DEPENDS – (не обязательно) Какие пакеты должны быть установлены до этого пакета.
В этой секции должен быть описан список команд для копирования собранных исходников в пакет (пакет представлен в виде $(1) директории) Компилирование
Поднимемся в корневую директорию OpenWRT и запустим конфигуратор:
$ cd .. $ make menuconfig
В конфигураторе ищем свое приложение и отмечаем его как <M> (не забывайте также в конфигураторе сделать базовые настройки, как например выбор платформы) :
Utilities ---> <M> simple
Здесь следует отметить как происходит выбор компонент в конфигураторе:
<*> (по клавише y) этот пакет будет включен в образ прошивки
<M> (по клавише m) этот пакет будет собран в виде отдельного пакета но не включен в образ прошивки (для последующей установки пакета вручную)
< > (по клавише n) этот пакет не будет собран
Для кругового select также можно использовать пробел.
Собственно компилирование:
make V=99
После компилирования все прошивки и пакеты будут находится в каталоге bin. Т.к. я собирал OpenWRT под свой D-Link DIR-320 то пакеты у меня находятся в каталоге bin/brcm47xx/package. В этом каталоге содержится ваш собственный репозиторий. Установка пакета
Достаточно открыть этот каталог по http, и в конфигурационном файле ipkg/opkg вашей embedded системы прописать url к http серверу.
Обновляем список пакетов и устанавливаем пакет simple:
root@OpenWrt:~# opkg update Downloading http://192.168.120.2/pkg/Packages.gz. Inflating http://192.168.120.2/pkg/Packages.gz. Updated list of available packages in /var/opkg-lists/packages. root@OpenWrt:~# opkg install simple Installing simple (1.0.0-1) to root... Downloading http://192.168.120.2/pkg/simple_1.0.0-1_brcm47xx.ipk. Configuring simple.
Проверим работу:
root@OpenWrt:~# simple Hello world 0 Hello world 1 Hello world 2 Hello world 3 Hello world 4 ... Hello world 98 Hello world 99
Собственно все, приложение скомпилировано и работает.