Kompilacja całego systemu lub pakietów
Ostatnia zmiana: 2020-11-23 07:01
Ten poradnik nie jest przeznaczony dla zupełnie początkujących - jeżeli nie wiesz co to
make, jak nakłada się łatki czy jak wygląda praca z repozytorium - najpierw zgromadź tą wiedzę u wujka Google.
Założenie - w poradniku będzie opisana kompilacja wersji stabilnej OpenWrt, źródła będą znajdować się w katalogu domowym, w podkatalogu
openwrt. Kompilację wykonuje się na zwykłym komputerze, więc do kompilacji potrzebny jest system *unix (np. Linux) lub MacOS/OS X. System powinien zawierać podstawowy zestaw programów przeznaczonych do kompilacji, czyli np. dla debianopochodznych należy zainstalować odpowiednie pakiety poleceniem:
$ sudo apt install build-essential binutils bzip2 gawk gettext git libncurses5-dev patch unzip zlib1g-dev subversion flex python3-distutils
W zależności od tego co kompilujemy mogą być potrzebne też inne pakiety - jeżeli tak będzie to podczas procesu zostanie wyświetlona odpowiednia informacja.
Do kompilacji można używać systemu na maszynie wirtualnej.
OpenWrt nie powinno się kompilować jako użytkownik root. Najlepiej zrobić jako jako "zwykły" użytkownik.
Kompilacja działa prawidłowo dla Debiana i pochodnych (Ubuntu/Mint), dla x86 i x86_64. W tym przykładzie kompilowany będzie system dla architektury
ar71xx - w przypadku innej platformy należy po prostu dostosować polecenia czy opcje. W zależności od wybranych opcji potrzebne jest 10GB - 40GB wolnej przestrzeni dyskowej i dostęp online do internetu (do ściągania źródeł).
Kompilacja OpenWrt
Pobieranie źródeł
$ cd ~
$ git clone https://github.com/openwrt/openwrt.git
$ cd openwrt
$ git fetch --tags
$ git checkout v19.07.4
Te polecenia pobierają sam podstawowy system, aktualną stabilną wersję wydania OpenWrt (numer wersji może się zmienić, więc należy pobrać tą wersję która ma być kompilowana). Listę wszystkich dostępnych wersji można uzyskać poleceniem:
Dostępne są jeszcze dodatkowe pakiety, które uzupełniają całość (tzw.
feeds), które też warto pobrać.
Jeżeli chcemy skompilować aktualną gałąź wydania stabilnego OpenWrt 19.07 (tzw. "branch" openwrt-19.07) to robimy:
$ git checkout openwrt-19.07
Wszystkie poniższe operacje wykonuje już się będąc w katalogu ze źródłami, czyli wg założeń w
~/openwrt.
Branch i tags to nie jest to samo!
Aktualizacja
Wydanie stabilne w określonej wersji (
tag) nie zmienia się. Jeżeli zaś wybraliśmy całą gałąź wersji stabilnej to są tam wprowadzane poprawki dopóki jest ona utrzymywana (to z niej właśnie kiedyś może powstać następna wersja stabilna oznaczona określonym numerem). Aktualizację tej gałęzi można wykonać poleceniami (będąc w katalogu ze źródłami):
$ git pull
$ make package/symlinks
$ make defconfig
O ile byliśmy przełączeni na
branch openwrt-19.07 (można to sprawdzić poleceniem
git branch). Zawartość repozytorium gałęzi wydania stabilnego zmienia się co jakiś czas (a jeszcze rzadziej wydawane są oficjalne wydania obrazów przez zespół OpenWrt), więc jeżeli budujemy obrazy to warto mieść aktualne źródła.
Konfiguracja
Tu należy wybrać żądną platformę i pakiety. Na samym początku wystarczy zostawić wartości domyślne, wybieramy tylko
Target System np. Atheros AR71XX oraz
Target Profile jako TP-Link TL-WR1043ND jeżeli chcemy kompilować dla tego urządzenia.
Znaczek <*> oznacza że z tego pakietu będzie z tego zrobiona paczka ipk i zostanie wkompilowany w wynikowy obraz, <M> - zostanie tylko skompilowany jako paczka. <--> oznacza że pakiet jest domyślnie wybrany, bo od niego zależy inny pakiet i nie da się go odznaczyć. Jeżeli wiemy że jakiś pakiet będzie używany i niezbyt często aktualizowany (np. moduły do USB, serwer ftp czy transmission) warto takie pakiety wkompilować w obraz - będą zajmowały znacznie mniej miejsca niż ich późniejsza instalacja w systemie.
Kompilacja środowiska
Podczas kompilacji wymagane jest połączenie do internetu, ponieważ ściągane są źródła pakietów (można ściągnąć najpierw wszystkie wymagane źródła poleceniem
make download). Początkowa kompilacja (kroskompilator, kernel, pakiety) w zależności od ilości wybranych pakietów może trwać nawet kilka godzin! Przy kolejnych kompilacjach, np. dodaniu kolejnego pakietu, kompilacja będzie już krótsza, bo kompilowane są tylko zmiany.
Jeżeli mamy kilka rdzeni w CPU to przy późniejszych operacjach możemy uruchomić kompilację "równoległą" poleceniem
o ile mamy procesor 4 rdzeniowy. Dla innej liczny rdzeni należy podać ilość rdzeni + 1.
(nie należy używać tej opcji jeżeli wyskoczą błędy podczas kompilacji i chcemy się dowiedzieć w jakich pakietach się one pojawiły).
Jeżeli chcemy uzyskać więcej informacji podczas kompilacji należy posłużyć się odpowiednim przełącznikiem
Obrazy wynikowe i pakiety zostaną umieszczone w podkatalogu
bin/. Jeżeli zaznaczymy za dużo pakietów i przekroczy to dopuszczalny rozmiar obrazów (np. 8MB dla TL-WR1043ND v1) to obraz po prostu nie zostanie wygenerowany.
Czasami (w bardzo rzadkich przypadkach) może przydać się zmiana opcji kompilacji kernela. Można to zrobić poleceniem (po uprzedniej kompilacji systemu!)
zaznaczyć niezbędne opcje, zapisać a potem jeszcze raz skompilować cały system poleceniem
make.
Czyszczenie kompilacji
Przy zmianie czegoś w kernelu może okazać się konieczna ponowna rekompilacja jądra i pakietów z modułami, przed kompilacją należy więc je wyczyścić:
$ make target/linux/clean
Czasami wykonane zostało więcej zmian i nie da się skompilować ponownie obrazu. W takich przypadkach pomaga wyczyszczenie całego środowiska z plików kompilacji:
Dodanie własnych plików do obrazu
Niekiedy istnieje potrzeba dodania do obrazów własnych plików konfiguracyjnych, ustawień lub skryptów. OpenWrt posiada do tego specjalny mechanizm, pozwalający łatwo wprowadzać zmiany do obrazu. Tworzymy folder o nazwie
files w głównym katalogu z naszymi źródłami:
$ cd ~
$ cd openwrt
$ mkdir -p files
A następnie umieszczamy w nim pliki lub katalogi które mają znaleźć się w docelowym obrazie. Cała struktura katalogów zostanie przeniesiona w identyczny sposób, więc np. jeżeli chcemy podmienić plik
/etc/banner w obrazie wynikowym na swój, to w katalogu
files robimy podkatalog
etc a w nim umieszczamy plik
banner z własną zawartością:
$ mkdir -p files/etc
$ echo ">>>> to dziala!!! <<<<" > files/etc/banner
Jeżeli chcemy dodać skrypt który wykonuje się
jeden raz przy uruchomieniu routera (np. wprowadza jakiś ustawienia) to należy to zrobić w katalogu
etc/uci-defaults, np:
$ mkdir -p files/etc/uci-defaults
$ echo "#!/bin/sh" > files/etc/uci-defaults/01-mojskrypt.sh
$ echo "uci del wireless.@wifi-device[0].disabled" >> files/etc/uci-defaults/01-mojskrypt.sh
$ echo "uci commit" >> files/etc/uci-defaults/01-mojskrypt.sh
$ chmod 755 files/etc/uci-defaults/01-mojskrypt.sh
Kompilacja pojedynczego pakietu
$ make package/nazwa_katalogu_z_pakietem/compile
Gdzie
nazwa_katalogu_z_pakietem to nazwa katalogu w którym znajduje się pakiet (to trzeba niestety wiedzieć). Czyli jeżeli chcemy skompilować np. pakiet
libffmpeg, a znajduje się on w katalogu
ffmpeg, to kompilacja wygląda następująco: "make package/ffmpeg/compile", a nie "make package/libffmpeg/compile"! Żeby pakiet dało się skompilować musi być także wcześniej zaznaczony w konfiguracji (w
make menuconfig - trzeba go wybrać przez <M> lub <*>).
Dostępna jest opcja czyszczenia kompilacji pakietu, czyli
$ make package/nazwa_katalogu_z_pakietem/clean
Co może być pomocne w przypadku dużych aktualizacji pakietów czy samodzielnego tworzenia łatek.
Aby móc skompilować jeden pakiet wcześniej musi być skompilowane całe środowisko dla danej platformy!
Kompilacja programu z kodu źródłowego
Ogólnie - należy zrobić odpowiedni plik
Makefile który pozwoli na przygotowanie pakietu ze skompilowanym programem. W niektórych przypadkach chcemy tylko skompilować prosty program i można to zrobić "ręcznie".
Kroskompilator i resztę wymaganych plików (nagłówki, biblioteki) można znaleźć w katalogu
staging_dir/toolchain-XXX (dla ar71xx i openwrt-19.07 jest to np.
staging_dir/toolchain-mips_24kc_gcc-7.5.0_musl). Kroskompilator znajduje się w podkatalogu
bin (
mips-openwrt-linux-musl-gcc), biblioteki są w
staging_dir/target_*/usr/lib, pliki nagłówkowe w
staging_dir/target_*/usr/include (w zależności od wersji mogą to być katalogi odpowiednio
usr/bin,
usr/lib i
usr/include). Kompilacja przykładowego programu może więc wyglądać następująco:
$ export STAGING_DIR=~/openwrt/staging_dir/toolchain-mips_24kc_gcc-7.5.0_musl
$ cd ${STAGING_DIR}
$ bin/mips-openwrt-linux-musl-gcc -o program plik1.c plik2.c ... -I${STAGING_DIR}/../target-mips_24kc_musl/usr/include -L${STAGING_DIR}/../target-mips_24kc_musl/usr/lib -ljakas_biblioteka
Oczywiście należy podać wszystkie opcje kompilacji i linkowania niezbędne do stworzenia danego programu (zamiast
plik*.c i
jakas_biblioteka). Powyższy przykład sprawdzi się dla prostych programów, dla bardziej zaawansowanych projektów prościej jest napisać odpowiedni
Makefile podobnie jak to jest zrobione dla innych pakietów w katalogach
package lub
feeds. Budowa takiego Makefile opisana jest na wiki openwrt (po angielsku):
http://wiki.openwrt.org/doc/devel/packagesPrzykładowy program
helloworld z odpowiednim
Makefile dostępny jest tutaj:
http://dl.eko.one.pl/projekty/helloworld.tar.gzAby móc skompilować własny pakiet wcześniej musi być skompilowane całe środowisko dla danej platformy i niezbędne biblioteki!
Kompilacja Gargoyle
Generalnie kompilacja wygląda w podobny sposób jak normalnego OpenWrt z tą różnicą, że Gargoyle zawiera własne skrypty służące do nakładania łatek i budowania całości.
Pobieranie źródeł
$ git clone https://github.com/ericpaulbishop/gargoyle.git
$ cd gargoyle
Kompilacja
lub po prostu
lub można skompilować określoną platformę np,
Gargoyle samodzielnie pobiera źródła OpenWrt, nakłada swoje łatki i kompiluje środowisko. Po wykonaniu w/w operacji powstaje katalog o nazwie np. ar71xx-src który zawiera wszystkie źródła wraz nałożonymi już łatkami. Jeżeli potrzebujemy minimalnej zmiany typu dodanie pakietu czy coś podobnego to nie ma sensu ponownie kompilować całego środowiska - należy po prostu wejść do tego katalogu i wykonać polecenia
make menuconfig && make