Сборка openwrt на windows

OpenWRT – популярная альтернативная прошивка для маршрутизаторов, NAS серверов, а так же может выступать в качестве операционной системы для небольшого домашнего сервера на x86-платформе.

Сегодня я поведаю, как собрать прошивку самому “на коленке” из исходников. Поверьте, в этом нет ничего сложного, если вы хоть мало-мальски разбираетесь в Linux-системах.

Первым делом Вам понадобится, конечно же, компьютер подключенный к сети Интернет с установленной операционной системой семейства Linux.

Данная статья ориентирована на пользователей Ubuntu Linux, хотя в прочем без каких либо доработок подойдет и для Debian Linux.

Если же у Вас что-то иное, сложностей всё равно не должно возникнуть.
Итак, в путь.

Установка необходимых пакетов

Первым делом нам понадобятся пакеты для получения исходников как самой прошивки, так и дополнительных пакетов:

sudo apt-get install subversion git

А так же набор инструментов для компилятора:

sudo apt-get install g++ libncurses5-dev zlib1g-dev gawk libssl-dev unzip make

Если же чего то не хватит, то нам прямым текстом об этом скажет система чуть позже.

На данный момент можно получить исходники следующих версий:

  • Attitude Adjustment – проверенная стабильная версия, однако на фоне неумолимого прогресса в сфере информационных технологий актуальность её угасает:
    svn co svn://svn.openwrt.org/openwrt/branches/attitude_adjustment wrt
  • Barrier Breaker – версия, обещающая стать заменой предыдущей, на сегодня находится в стадии RC (release candidate). ставшая новым stable-релизом. если случаются обновления исходного кода, то только критические исправления, не замеченные в период тестирования.
    Пока имеет множество небольшое количество о умолчанию не доступных дополнительных пакетов, но если вы не планируете запускать на маршрутизаторе Web-сервер или еще какое нестандартное извращение, то проблем у Вас не возникнет.
    Хотя отдельно затем отпишусь, как вернуть для сборки эти пакеты.

    svn co svn://svn.openwrt.org/openwrt/branches/barrier_breaker wrt
  • Chaos Calmer – следующая версия OpenWRT, находится в стадии trunk. Обещается в будущем переход на версию kernel 3.14 и подхватывание всех современных тенденций. Версия для экспериментаторов. Временами возникают проблемы, но быстро лечатся. Если руки у Вас прямы, нервы крепки, готовы и морально и физически к трудностям, которые могут возникнут совершено случайно при очередной пересборке, то смотрите лучше на эту версию.
    svn co svn://svn.openwrt.org/openwrt/trunk wrt

Если возникает ошибка svn: E000111, то читаем мини-заметку: ошибка e000111

Итак выбрали, скачали исходники самой прошивки. Теперь скачаем исходники дополнительных пакетов.

cd ~/wrt
./scripts/feeds update -a
./scripts/feeds install -a

Сборка OpenWRT

Итак, исходные коды получили. Приступаем к сборке. Увы, это не так быстро, как хотелось бы. По этому я опишу сценарий в несколько этапов, чтобы иметь время переварить информацию, сходить покушать или провести время с любимой.

Проверка и подготовка среды компиляции OpenWRT

Достаточно громкое название пункта, не смог придумать что-то иное, описывающее суть. На самом деле всё тут просто.
Вводим команду

make prereq

Ждем менее минуты. И смотрим на результат. Если видим

~/wrt$ make prereq
Collecting package info: done

Или открывшийся псевдо-интерфейс о котором чуть ниже, или вообще ничего нам не вывела команда (от версии к версии иногда что-то меняется или сбивается, особенно в транке, результат непредсказуем), значит всё хорошо и идем дальше.
Если же вы увидели примерно следующее

~/wrt$ make prereq
Collecting package info: done
Checking 'working-make'... ok.
Checking 'case-sensitive-fs'... ok.
Checking 'getopt'... ok.
Checking 'fileutils'... ok.
Checking 'working-gcc'... ok.
Checking 'working-g++'... ok.
Checking 'ncurses'... ok.
Checking 'zlib'... ok.
Checking 'gawk'... ok.
Checking 'unzip'... failed.
Checking 'bzip2'... ok.
Checking 'perl'... ok.
Checking '/usr/bin/python2.7'... ok.
Checking 'wget'... ok.
Checking 'git'... ok.
Checking 'gnutar'... ok.
Checking 'svn'... ok.
Checking 'gnu-find'... ok.
Checking 'getopt-extended'... ok.
Checking 'non-root'... ok.

То ищем, у какого пакета статус failed, то есть про который вы забыли. Ну и доустанавливаем.

Выбор целевой платформы

Всё проверили, начнем первый заход в интерфейс настройки сборки прошивки.

make menuconfig

И через несколько мгновений попадаем в псевдографический интерфейс настройки сборки прошивки OpenWRT

Псевдографический интерфейс настройки сборки прошивки OpenWRT

Псевдографический интерфейс настройки сборки прошивки OpenWRT

Здесь нам необходимо указать тип процессора и устройство.
Для примера:

  • Dlink DIR-320 rev. A1/A2
    1. Target System – Broadcom BCM47xx/53xx (MIPS)
    2. Subtarget – Generic
    3. Target Profile – Broadcom SoC, b44 Ethernet, BCM43xx WiFi (b43, default)
  • Dlink DIR-320 rev. B1/B2 он же Dlink DIR-320NRU
    1. Target System – Ralink RT288x/RT3xxx
    2. Subtarget – RT3x5x/RT5350 based boards
    3. Target Profile – Default Profile
  • TP-Link TL-WR842ND v1/v2
    1. Target System – Atheros AR7xxx/AR9xxx
    2. Subtarget – Generic
    3. Target Profile – TP-LINK TL-WR842N/ND

Все устройства описать сложно, так что либо ищите готовый профиль, либо технические характеристики Вам помогут.
Выбрав профиль пока больше никуда не ползите, а выйдите из настроек, сохранив конфигурацию и переходите к следующему пункту.

Сборка кросскомпилятора

Данный пункт желателен, но не обязателен, если пропустите – при первой сборке прошивки всё итак соберется. Включили в статью по банальной причине – читатели, что обращаются лично, зачастую не могут объяснить что у них именно с ошибкой вывалилось – компиляция среды сборки или компиляция прошивки

Мы собираем систему не для обычного компьютера, а для устройства с MIPS-процессором (может быть кому то и ARM достался, но сам факт остается фактом).
Посему нам необходимо сначала позаботиться об компиляторе.

В исходниках прошивки OpenWRT есть и исходники кросскомпилятора, а так же сопутствующих программ, которые помогут нам эту прошивку упаковать. Предыдущий пункт нам и нужен был для указанию программе сборки, под что мы дальше будем собирать пакеты и прошивку в целом. Соберем все эти вкусности сейчас. Тем более данный этап понадобится нам лишь однажды, если мы не будем в каждый раз собирать для разных устройств.

make tools/install -j3 V=-1 && make toolchain/install -j3 V=-1

Обратите внимание, что
-j3 – во сколько потоков будет собираться. Выбирайте количество ядер процессора плюс один поток.
V=-1 – не выводить дополнительную информацию. В этом случае компилятор будет лишь выводить о текущем этапе сборки.

Процедура достаточно долгая. Позвоните девушке, позовите в кафе.
Если процессор у вас медленный, а девушки нет – пора бы найти пассию.
А если серьезно, то при средней скорости интернета и производительности компьютера – примерно час времени это займет.

Выбор компонентов OpenWRT

Итак, всё необходимое для сборки самой прошивки мы собрали, теперь перейдем к выбору составляющих.
В прочем их доустановить можно будет и уже на установленную прошику, но ведь хотелось бы иметь всё из коробки, не так ли?
Ну и в силу технических особенностей, пакеты, включенные в прошивку, занимают значительно меньше места, чем доустановленные позже.
Возвращаемся в тот самый интерфейс.

make menuconfig

Web-интерфейс LuCI

Управлять прошивкой из командной строки – дело благородное, но не всегда удобное.
Посему я всем рекомендую использовать Web-интерфейс.
Для этого выбираем следующие пункты

LuCI  --->
   1. Collections  --->
      <*> luci
   5. Translations  --->
      <*> luci-i18n-english
      <*> luci-i18n-russian

Впрочем, набор языков можете выбрать иной.

Протоколы подключений к Интернет

Зачем нам маршрутизатор, который не умеет подключаться к интернету?
Выберем необходимые протоколы:

Network  --->
   <*> ppp
      <*> ppp-mod-pppoe
      <*> ppp-mod-pppol2tp
      <*> ppp-mod-pptp

Вам необходимо выбрать лишь то, в чем действительно нуждаетесь. Названия пунктов говорят сами за себя.

Подключение USB-устройств

Наиболее популярной задачей, с которой сталкиваются пользователи OpenWRT – подключение внешних накопителей.
Подключение USB-модемов и принтеров рассматривать в этой статье не будем, так как её размер увеличится до бесконечности.

Для подключения USB дисков нам первым делом понадобится пакет block-mount, который в прочем не обязателен, но поможет нам подключать диски через Web-интерфейс, а так же автоматически их монтировать после перезагрузки устройства. Иначе придется всё ручками прописывать.

Base system   --->
   <*> block-mount

А так же модули ядра, отвечающие за поддержку шины USB, а так же подключаемых через неё устройств, в частности – внешних накопителей.

Kernel modules  --->
   USB Support  --->
      <*> kmod-usb-core
      <*> kmod-usb-ohci
      <*> kmod-usb-storage
      <*> kmod-usb-usb2

Ну и конечно же модули файловых систем. Я использую только Ext2/Ext3/Ext4, чего и Вам советую NTFS и FAT32 – это хорошо там, где Windows.

Kernel modules  --->
   Filesystems  --->
      <*> kmod-fs-ext4

Модуль ядра Ext4 совместим с более старыми версиями – Ext2 и Ext3. Полностью их поддерживает, так что об совместимости особо не беспокойтесь.

Подключаем zram-swap

Если Вы планируете выжимать из Вашего устройства всё, на что оно способно, то zRam и в OpenWRT вам поможет. Если не в курсе, что этого такое и для чего необходимо – читайте в статье Linux и zRam — экономим оперативную память

Base system   --->
   <*> zram-swap

Выбираем оптимизацию – скорость или размер

Если для Вашей конфигурации памяти в устройстве точно хватит, то есть смысл поменять оптимизацию по умолчанию для меньшего размера на оптимизацию для лучшей производительности.

[*] Advanced configuration options (for developers)  --->
   [*] Target Options  --->
      Target Optimizations

В этом параметре мы видим параметры компиляции исходного кода.
Например для TP-Link TL-WR842ND v1/v2 среда сборки предлагает следующие параметры

-Os -pipe -mno-branch-likely -mips32r2 -mtune=34kc

Здесь первый параметр -Os – и есть флаг оптимизации размера. Поменяем его на -O2. Таким образом размер занимаемой прошивки вырастет процентов на 5-10, как и скорость работы. В принципе не очень и вырост в производительности, но в случае с такими медленными по современным меркам процессорами – уже приятно.
Так же, если Вы точно знаете модель процессора и его спецификации, то можете поменять параметры компиляции.
Например во второй TP-Link TL-WR842ND используется уже процессор не 34kc, а уже более современный 74kc с поддержкой инструкций dsp2.
Если у Вас маршрутизатор TP-Link TL-WR842ND v2, то имеет смысл привести строку к виду

-O2 -pipe -mno-branch-likely -mips32r2 -mtune=74kc -mdspr2

Внимание! Данные параметры превратят маршрутизатор данной модели первой ревизии в кирпич, если не уверены – то ограничьте себя заменой -Os на -O2.

Редактор Nano

Если место Вы экономить не планируете, а с редактором vi, идущем по умолчанию в OpenWRT у вас созревают конфликты, ибо не самое удобное творение человечества, то есть смысл так же добавить в состав прошивки редактор Nano. Хотя он и не очень то и много места займет в Вашем устройстве.

Utilities  --->
   [*] Editors  --->
      <*> nano

Компиляция и сборка OpenWRT

Выбрали всё, что Вам необходимо и теперь приступаем к сборке.

make -j3 V=-1

Вот так вот всё просто.
Ждем минут двадцать и в каталоге

~/wrt/bin/тип процессора/

созерцаем готовые прошивки, ищем под своё устройство и прошиваем.

Сделай приятное автору — поделись статьей в социальной сети.

Ну а если хотите простимулировать мою работоспособность или выявить признательность, до не откажусь от кружечки кофе:

Время на прочтение7 мин

Количество просмотров7.5K

Добрый день друзья. Как-то мне захотелось установить Qbittorrent на мой роутер который оснащен OpenWRT. Конечно создатели OpenWRT уже предусмотрели возможность сборки кастомных пакетов об этом можно почитать вот тут: https://habr.com/ru/company/ruvds/blog/530984/ . Но данный способ очень долгий, приходится скачивать исходники OpenWRT, компилировать тулчейн и прочее. И я подумал, а почему-бы просто не скачать тулчейн и собрать проект обычным образом. Под катом мой опыт.

Тулчейны что это такое

Итак, для людей которые недавно познакомились с Linux (как впрочем и я) поясняю тулчейн это набор пакетов необходимый для сборки приложения. В него входят компилятор, линкер и т. д, программой которая вызывает всю цепочку пакетов называется gcc. Для Linux существует множество тулчейнов которые позволяют собирать программы как под другие операционные системы (Windows и т. д) так и под другие платформы (Arm и т. д). Например тулчейн для Windows называется MinGW. При помощи него можно компилировать программы для Windows прямо из под Linux звучит как магия.

Подготовка

Что нам нужно? Нам нужен Linux все опыты проводились в Linux Mint. На него нужно установить следующие пакеты:

sudo apt update
sudo apt install build-essential curl pkg-config automake libtool \
git perl python3 python3-dev python3-numpy \
unzip cmake ninja

Также нам нужен тулчейн. Какие бывают тулчейны? Ну во первых они отличаются архитектурой под которую они собирают пакеты. Также они могут иметь разные стандартные библиотеки языка C. Наиболее распространённая библиотека это glibc, но нам она не подойдет, поскольку OpenWRT использует библиотеку musl. Поэтому заходим по ссылке https://musl.cc/#binaries и качаем нужный тулчейн. Поскольку мой роутер использует процессор с архитектурой aarch64, то я выберу aarch64-linux-musl-cross и скачаю его. Распаковываем его в папку, путь к которой далее я буду называть crosshost_dir для краткости.

Также нам необходимы исходники не только Qbittorrent, но и исходники всех библиотек которые используются в Qbittorrent.

  1. zlib https://github.com/madler/zlib

  2. openssl https://github.com/openssl/openssl Нужна версия с l (OpenSSL_1_1_1l)

  3. boost https://boostorg.jfrog.io/ui/native/main/release/1.77.0/source

  4. libtorrent https://github.com/arvidn/libtorrent Версию 2 поддерживает только qbittorrent 4.4

  5. qt-everywhere https://download.qt.io/archive/qt/5.15/5.15.2/single/

  6. qbittorrent https://github.com/qbittorrent/qBittorrent

Также нужно создать папку в которой мы будем работать и распаковать в неё все эти архивы. Эту папку я далее буду называть Install_dir. В ней нужно создать папку Build в которую будут складываться результаты наших трудов.

Теория

Во первых хочется предупредить об одной вещи. Если внутри параметра который вы передаёте в консоль присутствует пробел, то этот параметр обязательно должен быть помещен в кавычки. Иначе система посчитает что вы передаете ей два параметра.

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

К сожалению если мы применим динамическое связывание наша программа не запустится. Система будет жаловаться на неопределённые символы. Поэтому мы применим статическое. Одним из плюсов данного подхода будет то, что у нас будет самая актуальная версия библиотек. А это очень важно например в случае с Libtorrent эта библиотека очень быстро обновляется и сильно влияет на работу Qbittorrent. Но отрицательной стороной данного подхода является сильно разросшийся размер программы. Например у меня получился Qbittorrent размером 22 МБ . Кажется это немного, но нужно помнить что ещё недавно у роутеров было 4 МБ флэш памяти и 4 МБ оперативной памяти.

Сборка любого проекта состоит из 3-х этапов

  1. Конфигурирование

  2. Сборка

  3. Инсталляция пакета. То есть перенос его в нужную директорию.

В Linux существует две системы сборки проектов это Autotools и Сmake. Autotools это устаревшая система но некоторые проекты до сих пор используют её. Поэтому мы будем использовать и ту и другую.

Сборка

Перед началом сборки нужно добавить несколько переменных окружения которые скажут системе где расположен наш проект и наш тулчейн, а также под какую платформу мы будем компилировать. Для тех кто не знает, все значения переменных окружения хранятся лишь до тех пор пока вы не закрыли терминал. То есть закрыли открыли терминал вводите переменные заново.

PATH=crosshost_dir/bin:$PATH
PATH=Install_dir/Build/bin:$PATH

CHOST=aarch64-linux-musl
CC=aarch64-linux-musl-gcc
AR=aarch64-linux-musl-ar
CXX=aarch64-linux-musl-g++
PKG_CONFIG_PATH="Install_dir/Build/lib/pkgconfig"
LD_LIBRARY_PATH=-L"Install_dir/Build/lib"

BOOST_ROOT="Install_dir/Build/boost"
BOOST_INCLUDEDIR="Install_dir/Build/boost"
BOOST_BUILD_PATH="Install_dir/Build/boost"

aarch64-linux-musl надо заменить на тот тулчейн который вы скачали.

Zlib

./configure --prefix=Install_dir/Build --static 
make -j8 CC=aarch64-linux-musl-gcc AR=aarch64-linux-musl-ar \
CXX=aarch64-linux-musl-g++ \
CXXFLAGS="-std=c++17 -static -w -s -IInstall_dir/Build/include" \
CPPFLAGS="-static -w -s -IInstall_dir/Build/include" \
LDFLAGS="-static -Wl,--no-as-needed -LInstall_dir/Build/lib -lpthread -pthread"
make install

После -j нужно поставить количество ядер вашего процессора у меня их 8. Zlib упорно не хотел воспринимать переменные среды поэтому пришлось передать их вместе с командой make.

OpenSSl

./Configure "linux-aarch64" --prefix=Install_dir/Build \
--openssldir="/etc/ssl" threads no-shared no-dso no-comp
make -j8 CC=aarch64-linux-musl-gcc AR=aarch64-linux-musl-ar \
CXX=aarch64-linux-musl-g++ \
CXXFLAGS="-std=c++17 -static -w -s -IInstall_dir/Build/include" \
CPPFLAGS="-static -w -s -IInstall_dir/Build/include" \
LDFLAGS="-static -Wl,--no-as-needed -LInstall_dir/Build/lib -lpthread -pthread"
make install_sw

Тут все похоже на прошлый.

Boost

Boost устанавливать не надо. Нужно просто переместить его в папку Install_dir/Build. И переименовать его папку просто в boost. А проекты которые от него зависят сами возьмут из этой папки что им надо.

Libtorrent

mkdir -p Install_dir/Build/graphs/libtorrent-rasterbar
patch -p1 < patch-libtorrent
cmake -Wno-dev -Wno-deprecated \
--graphviz=Install_dir/Build/graphs/libtorrent-rasterbar/dep-graph.dot \
-G Ninja -B build -DCMAKE_CXX_COMPILER=aarch64-linux-musl-g++ \
-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=17 \
-DCMAKE_PREFIX_PATH="Install_dir/Build;Install_dir/Build/boost" \
-DBoost_NO_BOOST_CMAKE=TRUE \
-DCMAKE_CXX_FLAGS="-std=c++17 -static -w -s -IInstall_dir/Build/include" \
-DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX="Install_dir/Build"
cmake --build build
cmake --install build

Для того чтобы собрать Libtorrent нужно применить патч . Здесь уже используется cmake.

Qt

Надо отметить что Qbittorrent до сих пор не поддерживает Qt 6-й версии поэтому нужно брать пятую. Перед сборкой нужно зайти в файл qt-everywhere_dir/qtbase/mkspecs/linux-aarch64-gnu-g++/qmake.conf и заменить aarch64-linux-gnu на aarch64-linux-musl или на вашу архитектуру если у вас другой тулчейн.

./configure -xplatform "linux-aarch64-gnu-g++" -prefix "Install_dir/Build" \
-no-icu -no-iconv  -opensource -confirm-license -release  -static -c++std "c++17" \
-qt-pcre -no-feature-glib -no-feature-opengl -no-feature-dbus -no-feature-gui \
-no-feature-widgets -no-feature-testlib -no-compile-examples -nomake examples \
-nomake tests -no-opengl -skip 3d -skip activeqt -skip androidextras \
-skip datavis3d -skip doc -skip macextras -skip quick3d -skip quickcontrols \
-skip quicktimeline -skip translations -skip wayland -skip webengine \
-skip webglplugin -skip winextras -skip x11extras  -I"Install_dir/Build/include" \
-L"Install_dir/Build/lib" \
QMAKE_LFLAGS="-static -Wl,--no-as-needed -LInstall_dir/Build/lib -lpthread -pthread"
make -j8
make install

Qbittorrent

mkdir -p Install_dir/Build/graphs/qBittorrent-release-4.4.0beta3
cmake -Wno-dev -Wno-deprecated \
--graphviz="Install_dir/Build/graphs/qBittorrent-release-4.4.0beta3/dep-graph.dot" \
-G Ninja -B build -DCMAKE_CXX_COMPILER="aarch64-linux-musl-g++" \
-DCMAKE_BUILD_TYPE="release" -DCMAKE_CXX_STANDARD="17" \
-DCMAKE_PREFIX_PATH="Install_dir/Build;Install_dir/Build/boost" \
-DBoost_NO_BOOST_CMAKE=TRUE \
-DCMAKE_CXX_FLAGS="-std=c++17 -static -w -s -I"Install_dir/Build/include"" \
-DSTACKTRACE=OFF -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON -DGUI=OFF \
-DCMAKE_INSTALL_PREFIX="Install_dir/Build"
cmake --build build
cmake --install build

Настройка и запуск Qbittorrent

Первым делом нужно переместить файл qbittorrent-nox в директорию \usr\bin вашего роутера. Теперь можно попробовать его запустить с опцией -d чтобы он запустился в режиме демона, иначе он выключится как только вы закроете окно putty. Но во первых делать это каждый раз неудобно да и qbittorrent запускается с правами root а это небезопасно. Поэтому сначала добавляем пользователя qbittorrent:

echo qbittorrent:x:227:227:qbittorrent:/home/qbittorrent:/bin/false >> /etc/passwd
echo qbittorrent:x:227:qbittorrent >> /etc/group
echo qbittorrent:x:0:0:99999:7::: >> /etc/shadow

После этого создаете файл /etc/init.d/qbittorrent

#! /bin/sh /etc/rc.common
USE_PROCD=1

START=98
STOP=01

DAEMON="/usr/bin/qbittorrent-nox"
USER="qbittorrent"
GROUP="qbittorrent"
home_dir="/home/qbittorrent"

start_service() {

	[ -d "$home_dir" ] || {
		mkdir -p "$home_dir"
		chmod 0755 "$home_dir"
		chown "$USER:$GROUP" "$home_dir"
	}

	procd_open_instance
	procd_set_param command "$DAEMON"
	procd_set_param user $USER
	procd_set_param group $GROUP
	procd_set_param env HOME="$home_dir"
	procd_close_instance
}

И разрешаете выполнение:

chmod 755 /etc/init.d/qbittorrent

Теперь qbittorrent’ом можно управлять как и другими демонами из веб интерфейса.

Где можно взять Qbittorrent если не хочется компилировать?

Конечно-же все это я взял не с потолка. На github я нашел репозитарий https://github.com/userdocs/qbittorrent-nox-static там есть скрипт который все вышесказанное сделает за вас. Но кроме того в разделе релизов уже лежат скомпилированные Qbittorrent’ы нужно только выбрать подходящую архитектуру процессора.

В данной статье процесс компиляции и создания пакетов для 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_URLURL загрузки оригинальных исходников
PKG_MD5SUM – MD5 – checksum для проверки загрузки
PKG_CAT – Чем распаковывать исходники (zcat, bzcat, unzip)

Как видно не все из этих переменных обязательны.
Наиболее важными секциями являются секции define Package/_name_ и define Package/_name_/install:

Секция описывает пакет для menuconfig и ipkg/opkg.

SECTION – Тип пакета (на текущий момент не используется)
CATEGORY – В каком меню должно находится приложение в menuconfig
TITLE – Короткое описание пакета
DESCRIPTION – Длинное описание пакета
URLURL исходного приложения
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

Собственно все, приложение скомпилировано и работает.

Writing and Compiling A Simple Program For OpenWrt

Writing and Compiling A Simple Program For OpenWrt

Written by Eric Bishop <ericpaulbishop-at-gmail.com>

Part I added 8/23/2007
Part II added 10/10/2007

Introduction

I’m writing this document because I found the documentation available on the OpenWrt wiki (http://wiki.openwrt.org) difficult to follow. I found myself in the position of wanting to compile a very simple program that I could run on my OpenWrt router. I ended up spending hours wading through the frustratingly incomplete documentation on the wiki, going through dozens of forum posts, and conducting extensive trial-and-error before my code would compile. I especially appreciated the examples on the wiki that contain the warning: “Note this Makefile is provided as an example only; it will not compile.” If something doesn’t work, it isn’t a very good example, is it? Here, then, is a (hopefully) more straightforward guide to building a program for OpenWrt. I found that existing documentation focuses more on porting existing, complicated programs to OpenWrt. My intention is to focus on getting a small, very simple, home-grown application running on OpenWrt. My goal is to explain this in as simple and complete a manner as possible, explaining each and every step necessary to write and compile a program that will run on OpenWrt. The process is actually very simple and straightforward — provided you know what you’re doing. For the purposes of this tutorial I’m going to assume you have a development box running linux and a router running OpenWrt. I will also assume you are at least somewhat familiar with C/C++ and standard Unix Makefiles.

The code for the examples in this tutorial can be downloaded from here. The example from the first part of the tutorial is in the openwrt-programming-examples/c directory and the example from the second part is in the openwrt-programming-examples/c++ directory.

Part I: A Simple Program in C

First, we’re going to need to write the code for the program itself and get it compiling on our local linux machine. Let’s write a simple “hello world” program that we want to run on the router:

~/helloworld/src/helloworld.c:

/****************
* Helloworld.c
* The most simplistic C program ever written.
* An epileptic monkey on crack could write this code.
*****************/
#include <stdio.h>

int main(void)
{
	printf("Hell! O' world, why won't my code compile?\n\n");
	return 0;
}

Alright, we have our code. Note the location of this file. Make a helloworld directory and then a src subdirectory. Place the code in the src subdirectory. Now, let’s write a standard Unix Makefile to compile this code for us:

~/helloworld/src/Makefile:

# build helloworld executable when user executes "make"
helloworld: helloworld.o
	$(CC) $(LDFLAGS) helloworld.o -o helloworld
helloworld.o: helloworld.c
	$(CC) $(CFLAGS) -c helloworld.c

# remove object files and executable when user executes "make clean"
clean:
	rm *.o helloworld

Notice that instead of hard-coding “gcc” in the makefile to compile the program, we use a variable that holds the C compiler, $(CC). If you’re compiling a c++ program you would use $(CXX) instead of $(CC) and $(CXXFLAGS) instead of $(CFLAGS). The use of the compiler variable is not necessary to compile the code locally, but in order to compile the code for OpenWRT it is critical because we won’t be using the standard gcc compiler. Place the makefile in the same src directory our code is in. We can now go to the src directory, type “make” and the program should compile. You can run it by typing “./helloworld”

mockingbird@linuxbox:~/helloworld/src$ make
cc -c helloworld.c
cc helloworld.o -o helloworld
mockingbird@linuxbox:~/helloworld/src$ ./helloworld
Hell! O' world, why won't my code compile?

mockingbird@linuxbox:~/helloworld/src$ make clean
rm *.o helloworld
mockingbird@linuxbox:~/helloworld/src$

So far this should be a review on how to write simple C programs and how to use Makefiles. Now comes the tricky part, compiling the code so that it will run on our router. The router uses a distinctly different architecture than our linux development box. Because there isn’t enough memory/disk space on the router to install a compiler and compile the code natively, we need to “cross-compile” the code on our development box for use on the router. To do this we need a special compiler and development environment called the OpenWRT SDK. You can download the SDK from http://downloads.openwrt.org The SDK varies depending on the architecture of your development box, the architecture of your router and the version/release of OpenWrt your router is running. I currently have whiterussian v0.9 installed on my Linksys WRT54G router, and my development box is an i686, so the SDK I use is this one. Extract the SDK files from the downloaded archive, and enter the SDK directory, which should have the same name as the tar.bz2 file (in my case OpenWrt-SDK-Linux-i686-1).

mockingbird@linuxbox:~$ tar xfj OpenWrt-SDK-Linux-i686-1.tar.bz2
mockingbird@linuxbox:~$ cd OpenWrt-SDK-Linux-i686-1
mockingbird@linuxbox:~/OpenWrt-SDK-Linux-i686-1$ ls
dl  docs  examples  include  Makefile  package  README.SDK  rules.mk  scripts  staging_dir_mipsel
mockingbird@linuxbox:~/OpenWrt-SDK-Linux-i686-1$

Our goal is to build a package for OpenWrt using the source we already have. When you execute the “make” command in the SDK directory, the SDK will compile all properly configured packages in the package subdirectory under the SDK directory. The next step (and the trickiest) is to properly configure our code so that the SDK will build it. First, copy the helloworld directory we made earlier into the package subdirectory of the SDK:

mockingbird@linuxbox:~/OpenWrt-SDK-Linux-i686-1$ cp -r ~/helloworld package
mockingbird@linuxbox:~/OpenWrt-SDK-Linux-i686-1$

In order to tell the OpenWrt SDK how to build our program we need to create a special Makefile in the helloworld directory, above the src directory which contains our conventional makefile. Writing this file is 90% of the work involved in compiling our program for OpenWrt. Below is an OpenWrt makefile for building the helloworld program. Each section is heavily commented so that it should be fairly clear what is going on:

~/OpenWrt-SDK-Linux-i686-1/package/helloworld/Makefile:

##############################################
# OpenWrt Makefile for helloworld program
#
#
# Most of the variables used here are defined in
# the include directives below. We just need to
# specify a basic description of the package,
# where to build our program, where to find
# the source files, and where to install the
# compiled program on the router.
#
# Be very careful of spacing in this file.
# Indents should be tabs, not spaces, and
# there should be no trailing whitespace in
# lines that are not commented.
#
##############################################

include $(TOPDIR)/rules.mk

# Name and release number of this package
PKG_NAME:=helloworld
PKG_RELEASE:=1

# This specifies the directory where we're going to build the program.
# The root build directory, $(BUILD_DIR), is by default the build_mipsel
# directory in your OpenWrt SDK directory
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)

include $(INCLUDE_DIR)/package.mk

# Specify package information for this program.
# The variables defined here should be self explanatory.
define Package/helloworld
	SECTION:=utils
	CATEGORY:=Utilities
	TITLE:=Helloworld -- prints a snarky message
	DESCRIPTION:=\
	If you can't figure out what this program does, \\\
	you're probably brain-dead and need immediate \\\
	medical attention.
endef

# Specify what needs to be done to prepare for building the package.
# In our case, we need to copy the source files to the build directory.
# This is NOT the default.  The default uses the PKG_SOURCE_URL and the
# PKG_SOURCE which is not defined here to download the source from the web.
# In order to just build a simple program that we have just written, it is
# much easier to do it this way.
define Build/Prepare
	mkdir -p $(PKG_BUILD_DIR)
	$(CP) ./src/* $(PKG_BUILD_DIR)/
endef

# We do not need to define Build/Configure or Build/Compile directives
# The defaults are appropriate for compiling a simple program such as this one

# Specify where and how to install the program. Since we only have one file,
# the helloworld executable, install it by copying it to the /bin directory on
# the router. The $(1) variable represents the root directory on the router running
# OpenWrt. The $(INSTALL_DIR) variable contains a command to prepare the install
# directory if it does not already exist.  Likewise $(INSTALL_BIN) contains the
# command to copy the binary file from its current location (in our case the build
# directory) to the install directory.
define Package/helloworld/install
	$(INSTALL_DIR) $(1)/bin
	$(INSTALL_BIN) $(PKG_BUILD_DIR)/helloworld $(1)/bin/
endef

# This line executes the necessary commands to compile our program.
# The above define directives specify all the information needed, but this
# line calls BuildPackage which in turn actually uses this information to
# build a package.
$(eval $(call BuildPackage,helloworld))

As indicated, most OpenWrt make files specify how to download the source of an application from a URL, and most documentation assumes that you want to do this. However, if you’re building your own application from scratch it doesn’t make sense to download from a URL. It’s much simpler to have the source locally and use the Build/Prepare section to copy the source to the build directory, as shown above. Also, be very careful of spacing in the Makefile. The indentation under the define sections should be tabs, not spaces and there should be no whitespace at the end of lines that are not comments. The trailing whitespace can be a problem when variables are being defined, as the compiler may think there is a space at the end of a directory name. If we’re copying something to dir_with_trailing_space/subdir the copy command may be executed as “cp my.file dir_with_trailing_space /subdir”. Not only don’t you want anything in /subdir, you probably dont have permission to create it and write to it.

Now we’re all set to compile the helloworld package. Go to the root SDK directory (if you’re not already there) and type “make V=99″ The “V=99″ option is optional, but it is useful for debugging as it instructs the compiler to be “verbose” and output all the details of what it is doing.

mockingbird@linuxbox:~/OpenWrt-SDK-Linux-i686-1$ make V=99
make package/compile
make[1]: Entering directory `/home/mockingbird/OpenWrt-SDK-Linux-i686-1'
Collecting package info...
make -C package compile SDK=1
make[2]: Entering directory `/home/mockingbird/OpenWrt-SDK-Linux-i686-1/package'
make[2]: Leaving directory `/home/mockingbird/OpenWrt-SDK-Linux-i686-1/package'
make[2]: Entering directory `/home/mockingbird/OpenWrt-SDK-Linux-i686-1/package'
make -j1 compile-targets
make[3]: Entering directory `/home/mockingbird/OpenWrt-SDK-Linux-i686-1/package'
make -C helloworld compile
make[4]: Entering directory `/home/mockingbird/OpenWrt-SDK-Linux-i686-1/package/helloworld'
CFLAGS="-Os -pipe -mips32 -mtune=mips32 -funit-at-a-time -I/home/mockingbird/OpenWrt-SDK-Linux-i686-1/staging_dir_mipsel/usr/include -I/home/mockingbird/OpenWrt-SDK-Linux-i686-1/staging_dir_mipsel/include " LDFLAGS="-L/home/mockingbird/OpenWrt-SDK-Linux-i686-1/staging_dir_mipsel/usr/lib -L/home/mockingbird/OpenWrt-SDK-Linux-i686-1/staging_dir_mipsel/lib " make -C /home/mockingbird/OpenWrt-SDK-Linux-i686-1/build_mipsel/helloworld AR=mipsel-linux-uclibc-ar AS="mipsel-linux-uclibc-gcc -c -Os -pipe -mips32 -mtune=mips32 -funit-at-a-time" LD=mipsel-linux-uclibc-ld NM=mipsel-linux-uclibc-nm CC="mipsel-linux-uclibc-gcc" GCC="mipsel-linux-uclibc-gcc" CXX=mipsel-linux-uclibc-g++ RANLIB=mipsel-linux-uclibc-ranlib STRIP=mipsel-linux-uclibc-strip OBJCOPY=mipsel-linux-uclibc-objcopy CROSS="mipsel-linux-uclibc-" CXXFLAGS="-Os -pipe -mips32 -mtune=mips32 -funit-at-a-time -I/home/mockingbird/OpenWrt-SDK-Linux-i686-1/staging_dir_mipsel/usr/include -I/home/mockingbird/OpenWrt-SDK-Linux-i686-1/staging_dir_mipsel/include " ARCH="mipsel" ;
make[5]: Entering directory `/home/mockingbird/OpenWrt-SDK-Linux-i686-1/build_mipsel/helloworld'
make[5]: `helloworld' is up to date.
make[5]: Leaving directory `/home/mockingbird/OpenWrt-SDK-Linux-i686-1/build_mipsel/helloworld'
touch /home/mockingbird/OpenWrt-SDK-Linux-i686-1/build_mipsel/helloworld/.built
install -d -m0755 /home/mockingbird/OpenWrt-SDK-Linux-i686-1/build_mipsel/helloworld/ipkg/helloworld/bin
install -m0755 /home/mockingbird/OpenWrt-SDK-Linux-i686-1/build_mipsel/helloworld/helloworld /home/mockingbird/OpenWrt-SDK-Linux-i686-1/build_mipsel/helloworld/ipkg/helloworld/bin/
mkdir -p /home/mockingbird/OpenWrt-SDK-Linux-i686-1/bin/packages
find /home/mockingbird/OpenWrt-SDK-Linux-i686-1/build_mipsel/helloworld/ipkg/helloworld -name CVS | xargs rm -rf
find /home/mockingbird/OpenWrt-SDK-Linux-i686-1/build_mipsel/helloworld/ipkg/helloworld -name .svn | xargs rm -rf
find /home/mockingbird/OpenWrt-SDK-Linux-i686-1/build_mipsel/helloworld/ipkg/helloworld -name '.#*' | xargs rm -f
STRIP="/home/mockingbird/OpenWrt-SDK-Linux-i686-1/staging_dir_mipsel/bin/sstrip" STRIP_KMOD="mipsel-linux-uclibc-strip --strip-unneeded --remove-section=.comment" /home/mockingbird/OpenWrt-SDK-Linux-i686-1/scripts/rstrip.sh /home/mockingbird/OpenWrt-SDK-Linux-i686-1/build_mipsel/helloworld/ipkg/helloworld
rstrip.sh: /home/mockingbird/OpenWrt-SDK-Linux-i686-1/build_mipsel/helloworld/ipkg/helloworld/bin/helloworld:executable
ipkg-build -c -o 0 -g 0 /home/mockingbird/OpenWrt-SDK-Linux-i686-1/build_mipsel/helloworld/ipkg/helloworld /home/mockingbird/OpenWrt-SDK-Linux-i686-1/bin/packages
Packaged contents of /home/mockingbird/OpenWrt-SDK-Linux-i686-1/build_mipsel/helloworld/ipkg/helloworld into /home/mockingbird/OpenWrt-SDK-Linux-i686-1/bin/packages/helloworld_1_mipsel.ipk
make[4]: Leaving directory `/home/mockingbird/OpenWrt-SDK-Linux-i686-1/package/helloworld'
make[3]: Leaving directory `/home/mockingbird/OpenWrt-SDK-Linux-i686-1/package'
make[2]: Leaving directory `/home/mockingbird/OpenWrt-SDK-Linux-i686-1/package'
make[1]: Leaving directory `/home/mockingbird/OpenWrt-SDK-Linux-i686-1'
( \
        cd package; \
        find . -maxdepth 2 -name Config.in | \
                sed -e 's,/Config.in,,g' | \
                xargs -r -n1 make compile -C; \
)
mockingbird@linuxbox:~/OpenWrt-SDK-Linux-i686-1$

It compiled! The new package, helloworld_1_mipsel.ipk, is now located in the bin/packages subdirectory of the root SDK directory.

mockingbird@linuxbox:~/OpenWrt-SDK-Linux-i686-1$ cd bin/packages
mockingbird@linuxbox:~/OpenWrt-SDK-Linux-i686-1/bin/packages$ ls
helloworld_1_mipsel.ipk
mockingbird@linuxbox:~OpenWrt-SDK-Linux-i686-1/bin/packages$

This file is a ipk file which is used by the ipkg (itsy package management) system. Ipkg is a package management system for embedded devices, where space is an issue. Let’s copy this package onto the router, which is located at 192.168.1.1 on my network.

mockingbird@linuxbox:~/OpenWrt-SDK-Linux-i686-1/bin/packages$ scp helloworld_1_mipsel.ipk root@192.168.1.1:
root@192.168.1.1's password:
helloworld_1_mipsel.ipk                                                            100% 1875     1.8KB/s   00:00
mockingbird@linuxbox:~/OpenWrt-SDK-Linux-i686-1/bin/packages$

Now, ssh into the router. We just copied the package to root’s home directory so we are finally ready to install our program. In root’s home directory, (where we end up immediately after connecting to the router via ssh) type “ipkg install helloworld_1_mipsel.ipk” and the ipkg system will do the rest.

mockingbird@linuxbox:~/OpenWrt-SDK-Linux-i686-1/bin/packages$ ssh root@192.168.1.1
root@192.168.1.1's password: 

BusyBox v1.00 (2007.01.30-11:42+0000) Built-in shell (ash)
Enter 'help' for a list of built-in commands.

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 WHITE RUSSIAN (0.9) -------------------------------
  * 2 oz Vodka   Mix the Vodka and Kahlua together
  * 1 oz Kahlua  over ice, then float the cream or
  * 1/2oz cream  milk on the top.
 ---------------------------------------------------
root@OpenWrt:~# ls
TZ                       ip-up                    resolv.conf              spool
dhcp.leases              log                      resolv.conf.auto         usr
helloworld_1_mipsel.ipk  net                      run
root@OpenWrt:~# ipkg install helloworld_1_mipsel.ipk
Installing helloworld (1) to root...
Configuring helloworld
Successfully terminated.
root@OpenWrt:~#

The executable has now been installed into the /bin directory on the router, per our instructions in the OpenWrt Makefile listed above. So, all we have to do to run the program is type “helloworld” at the prompt. Note that because the executable has been installed to the /bin directory you should be able to execute the program no matter what directory you are in on the router.

root@OpenWrt:~# helloworld
Hell! O' world, why won't my code compile?

root@OpenWrt:~#

It works! Great success!

Now that you have a simple program compiling, you can start expanding on it to do whatever you want. If you run into problems I suggest you browse existing package Makefiles to see if someone else has done something similar to what you are trying to do. You can browse the files for these packages here. If you still have problems, browse the posts on the developer forum to see if anyone else has had a similar problem. If not, post your problem to the forum with a detailed explanation of what you’re trying to do, your OpenWrt Makefile and the errors you’re getting. Hopefully, some experienced developer will be kind enough to help out. Please do not email me personally if you have a problem with your code. If, however, you believe there is an error or serious omission in this tutorial, please let me know. I am relatively new to working with OpenWrt and it is certainly possible that I’ve made a mistake somewhere in this document. I have, however, personally tested all code included here on my own setup, and made every effort to be as accurate as possible.

Good luck with your programming!

———————————————————————-

Note 1:

you have to erase this part of the code in the makefile:

DESCRIPTION:=\
If you can’t figure out what this program does, \\\
you’re probably brain-dead and need immediate \\\
medical attention.

inside the “define Package/helloworld”

Instead of you have to type:

define Package/helloworld/description
(tab)
endef

Note 2:

use opkg instead of ipkg, in order to install the program on openwrt

————————————————————————-

http://www.frontiernet.net/~beakmyn/CrossCompile.htm#Buildroot

  1. Install Git to download the source code, and your distro’s default build tools metapackage to do the cross-compilation process.

  2. You may also need to install Subversion (SVN) or Mercurial to fetch the source-code for some feeds which are not available over Git.

  3. Install other prerequisite packages, as indicated in the table and examples below.

  4. Unset environment variables like SED and GREP_OPTIONS and aliases/functions like which.

This table contains the package name for each build prerequisite in different GNU/Linux and Unix like distributions.

Prerequisite Debian SUSE Red Hat macOS (via MacPorts) Fedora Arch Gentoo
asciidoc asciidoc asciidoc asciidoc asciidoc asciidoc asciidoc app-text/asciidoc
GNU Bash bash bash bash bash bash bash app-shells/bash
GNU Binutils binutils binutils binutils binutils binutils binutils sys-devel/binutils
bzip2 bzip2 bzip2 bzip2 bzip2 bzip2 bzip2 app-arch/bzip2
flex flex flex flex flex flex flex sys-devel/flex
git git git-core git git-core git-core git dev-vcs/git
GNU C++ Compiler g++ gcc-c++ gcc-c++ ? gcc-c++ gcc sys-devel/gcc
GNU C Compiler gcc gcc gcc ? gcc gcc sys-devel/gcc
GNU Time time time ? gtime ? time sys-process/time
getopt util-linux util-linux util-linux getopt util-linux util-linux sys-apps/util-linux
GNU awk gawk gawk gawk gawk gawk gawk sys-apps/gawk
gzip gzip gzip gzip gzip gzip gzip app-arch/gzip
help2man help2man help2man ? help2man help2man help2man sys-apps/help2man
intltool-update intltool intltool intltool intltool intltool intltool dev-util/intltool
libelf-dev libelf-dev libelf-devel ? libelf elfutils-libelf-devel libelf virtual/libelf
libz, libz-dev zlib1g-dev zlib-devel zlib-devel zlib, libzip, libzzip zlib-devel zlib sys-libs/zlib
GNU make make make make gmake make make sys-devel/make
ncurses libncurses-dev ncurses-devel ncurses-devel ncurses ncurses-devel ncurses sys-libs/ncurses
openssl/ssl.h libssl-dev libopenssl-devel openssl-devel openssl openssl-devel openssl dev-libs/openssl
patch patch patch patch patchutils patch patch sys-devel/patch
perl-ExtUtils-MakeMaker perl-modules perl-ExtUtils-MakeMaker perl-ExtUtils-MakeMaker p5-extutils-makemaker perl-ExtUtils-MakeMaker perl-extutils-makemaker virtual/perl-ExtUtils-MakeMaker
perl-FindBin perl-FindBin
perl-IPC-Cmd perl-IPC-Cmd
perl-Thread-Queue libthread-queue-any-perl ? ? ? perl-Thread-Queue ? virtual/perl-Thread-Queue
perl-Time-Piece perl-Time-Piece
python2-dev python2-dev python-devel ? python27 ? python2 dev-lang/python:2
? python3-dev ? ? python310 ? ? ?
rsync rsync
SWIG swig swig swig swig swig swig dev-lang/swig
tar tar
unzip unzip unzip unzip unzip unzip unzip app-arch/unzip
GNU Wget wget wget wget wget wget wget net-misc/wget
which which
xgettext gettext gettext-tools gettext gettext gettext gettext sys-devel/gettext
xsltproc xsltproc libxslt-tools ? libxslt libxslt libxslt dev-libs/libxslt
zlib, zlib-static zlib1g-dev zlib-devel-static zlib-devel zlib zlib-devel,zlib-static zlib sys-libs/zlib (USE=static-libs)

Note that the advice above may be somewhat outdated. E.g. python3 is currently the default in OpenWrt master, 22.03 and 21.02, while python2.7 has been removed due its end-of-life.

Unfortunately not all dependencies are checked by make config, especially for packages.
You may encounter compile errors because you need a specific library in your system, and the only way is to search the missing library from the compiler error log and see what package contains it in your own distro.

The following table is a partial list of such dependencies:

Package Prerequisite Debian SUSE Red Hat macOS (via MacPorts) Fedora Arch Gentoo
boost bjam / boost-jam libboost-dev boost-devel boost-jam boost-build boost-jam boost dev-util/boost-build
intltool [Perl] XML::Parser libxml-parser-perl perl-XML-Parser perl-XML-Parser p5.28-xml-parser p5.30-xml-parser perl-XML-Parser intltool dev-perl/XML-Parser
libftdi (aka: libftdi0) libusb-config libusb-dev libusb-1_0-devel libusb libusb-devel libusb dev-libs/libusb-compat
lilo as86,ld86 bin86 bin86 (https://software.opensuse.org/package/bin86) binutils dev86 bin86 sys-devel/bin86
lilo bcc1 bcc dev86 (https://software.opensuse.org/package/dev86) dev86 aur/bcc sys-devel/dev86
lilo uudecode sharutils sharutils sharutils sharutils sharutils app-arch/sharutils
luajit,xdp-tools x86 g++ libs on amd64 hosts gcc-multilib
classpath (aka: gnu-classpath) 1 javac, gcj openjdk-7-jdk-headless java-1_8_0-openjdk-devel openjdk7-zulu java-1.8.0-openjdk-devel jdk7-openjdk dev-java/oracle-jdk-bin, sys-devel/gcc[gcj], and one (or both) of dev-java/icedtea-bin:7 and dev-java/icedtea:7
mac80211 b43-fwcutter1 (Broadcom/BCM) b43-fwcutter b43-fwcutter b43-fwcutter b43-fwcutter net-wireless/b43-fwcutter
jamvm1 zip zip zip zip zip app-arch/zip

Distribution-specific instructions.

Please note that OpenWrt master, 22.03 and 21.02 branches do not need python2.7 any more. Python3 should be your default.

apk add argp-standalone asciidoc bash bc binutils bzip2 cdrkit coreutils \
  diffutils elfutils-dev findutils flex musl-fts-dev g++ gawk gcc gettext git \
  grep gzip intltool libxslt linux-headers make musl-libintl musl-obstack-dev \
  ncurses-dev openssl-dev patch perl python3-dev rsync tar \
  unzip util-linux wget zlib-dev
 
# python2-dev required for OpenWrt 19.07 and earlier is not available on Alpine Linux 3.16 and newer 
 
# missing dependency workaround (libtinfo is not installable by any APK package,
# but can be simulated via libncurses (see: https://stackoverflow.com/a/41517423 )
# w/o this - ERROR: package/boot/uboot-mvebu failed to build (build variant: clearfog)
ln -s /usr/lib/libncurses.so /usr/lib/libtinfo.so 

Arch users may install the openwrt-devel meta-package from the AUR or alternatively, manually install the build dependencies as follows:

# Essential prerequisites
pacman -S --needed base-devel autoconf automake bash binutils bison \
bzip2 fakeroot file findutils flex gawk gcc gettext git grep groff \
gzip libelf libtool libxslt m4 make ncurses openssl patch pkgconf \
python python-distutils-extra rsync sed texinfo time unzip util-linux wget which zlib
 
# Optional prerequisites, depend on the package selection
pacman -S --needed asciidoc help2man intltool perl-extutils-makemaker swig
sudo dnf --setopt install_weak_deps=False --skip-broken install \
bash-completion bzip2 file gcc gcc-c++ git-core make ncurses-devel patch \
rsync tar unzip wget which diffutils python3 perl-base \
perl-Data-Dumper perl-File-Compare perl-File-Copy perl-FindBin \
perl-IPC-Cmd perl-JSON-PP perl-lib perl-Thread-Queue perl-Time-Piece

Modernized set for Ubuntu 24.04 that has Python 3.12 without python3-distutils:
(OpenWrt main/master in Apr 2024)

sudo apt update
sudo apt install build-essential clang flex bison g++ gawk \
gcc-multilib g++-multilib gettext git libncurses5-dev libssl-dev \
python3-setuptools rsync swig unzip zlib1g-dev file wget

set for Ubuntu 22.04 (that has older Python 3.xx):

sudo apt update
sudo apt install build-essential clang flex bison g++ gawk \
gcc-multilib g++-multilib gettext git libncurses-dev libssl-dev \
python3-distutils python3-setuptools rsync swig unzip zlib1g-dev file wget

Older advice (for 19.07 and earlier that need python2.7):

sudo apt update
sudo apt install build-essential ccache ecj fastjar file g++ gawk \
gettext git java-propose-classpath libelf-dev libncurses5-dev \
libncursesw5-dev libssl-dev python python2.7-dev python3 unzip wget \
python3-distutils python3-setuptools python3-dev rsync subversion \
swig time xsltproc zlib1g-dev 
echo \
app-arch/{bzip2,sharutils,unzip,zip} sys-process/time \
app-text/asciidoc \
dev-libs/{libusb-compat,libxslt,openssl} dev-util/intltool \
dev-vcs/{git,mercurial} net-misc/{rsync,wget} \
sys-apps/util-linux sys-devel/{bc,bin86,dev86} \
sys-libs/{ncurses,zlib} virtual/perl-ExtUtils-MakeMaker \
| sed "s/\s/\n/g" \
| sort \
| sudo tee /etc/portage/sets/openwrt-prerequisites \
&& sudo emerge -DuvNa "@openwrt-prerequisites"
sudo zypper install --no-recommends asciidoc bash bc binutils bzip2 \
fastjar flex gawk gcc gcc-c++ gettext-tools git git-core intltool \
libopenssl-devel libxslt-tools make mercurial ncurses-devel patch \
perl-ExtUtils-MakeMaker python-devel rsync sdcc unzip util-linux \
wget zlib-devel
sudo xbps-install -Su asciidoc bash bc binutils bzip2 cdrtools \
coreutils diffutils findutils flex gawk gcc gettext git grep intltool \
libxslt linux-headers make ncurses-devel openssl-devel patch perl \
pkg-config python3-devel rsync tar unzip util-linux wget \
zlib-devel time libelf perl-ExtUtils-MakeMaker-CPANfile \
help2man swig
 
# for musl version, also install: argp-standalone musl-fts-devel musl-obstack-devel

macOS distribution-specific instructions. macOS uses Darwin unix as its core. Xcode/CLT toolchain, & 3rd-party package-manager tool allows to load various common build tools.

More info: buildroot.exigence.macosx.

sudo port install libiconv gettext-runtime coreutils findutils gwhich \
gawk zlib pcre bzip2 ncurses grep getopt gettext-tools-libs gettext \
diffutils sharutils util-linux libxslt libxml2 help2man readline gtime \
gnutar unzip zip lzma xz libelf fastjar libusb libftdi0 expat sqlite3 \
openssl3 openssl kerberos5 dbus lz4 libunistring nettle icu gnutls \
p11-kit wget quilt subversion gmake pkgconfig libzip cdrtools ccache \
curl xxhashlib rsync libidn perl5 p5.28-xml-parser p5.30-xml-parser \
p5-extutils-makemaker p5-data-dumper boost-jam boost boost-build bash \
bash-completion binutils m4 flex intltool patchutils swig git-extras \
git openjdk17 openjdk7-zulu luajit libtool glib2 file python27 \
python310 libzzip mercurial asciidoc sdcc gnu-classpath

Distribution-specific instructions.

Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Генеалогическая линия развития операционной системы windows
  • Как сделать видео экрана на ноутбуке windows 10
  • Палитра цветов adobe или windows
  • Как установить neverhood на windows 10
  • Код ошибки 0хс004с003 при активации windows 10