V poslednej dobe sa začali dosť rozširovať malé domáce routre, na ktorých je možné sprevádzkovať OpenWRT Linux. Tento článok nieje o inštalácii tohto systému. Tento článok je skôr o tom, ako na C/C++ programy pre zariadenia s týmto systémom.
Čo s tým ma dočinenia programovanie pre naše zariadenie? Totižto, vývoj programu budeme musieť realizovať na našom desktope, následne náš program prevedieme na balíček, a ten nainštalujeme na našom zariadení s OpenWRT. Nato, aby sme mohli na našom desktope vytvoriť balíček pre OpenWRT systém, je potrebne si stiahnuť OpenWRT SDK, ktoré nájdeme na www.openwrt.org. OpenWRT SDK si rozbalíme do domovského adresára. V domovskom adresári by po rozbalení mal vzniknúť adresár OpenWrt-SDK-Linux-i686-1.
Hello World
Asi ako prvé, si skúsime klasicky C program „Hello World“, na ktorom si vysvetlíme, ako program skompilovať a dostať do zariadenia. Pre náš program si vytvoríme adresár hello v OpenWrt-SDK-Linux-i686-1/packages. V tomto adresári si vytvoríme main.c z nasledujúcim, dobre známym, obsahom.main.c:
#include <stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}
Najpodstatnejšia časť príde teraz. Totižto, pre program je potrebne vytvoriť balíček. OpenWRT SDK prechádza všetky adresáre v package adresári a pre každý balíček volá súbor Makefile. V tomto súbore sa nachádzajúcu pravidla ako kompilovať, čo kompilovať, čo a kam inštalovať, popis programu atď. Pre náš program si vytvoríme v tom istom adresári, ako je main.c nasledujúci Makefile. Makefile:
include $(TOPDIR)/rules.mk
PKG_NAME:=hello
PKG_VERSION:=1.0
PKG_RELEASE:=1
PKG_BUILD_DIR:=$(BUILD_DIR)/hello
include $(INCLUDE_DIR)/package.mk
define Package/hello
TITLE:=Hello World
DESCRIPTION:=\
A simple HELLO WORLD program
endef
define Build/Compile
$(TARGET_CC) $(TARGET_CFLAGS) -o $(PKG_BUILD_DIR)/hello main.c
endef
define Package/hello/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/hello.out $(1)/usr/bin/
endef
$(eval $(call BuildPackage,hello))
Makefile je písaný podľa určitej šablóny, ktorej OpenWRT SDK rozumie. Teraz si prejdeme najdôležitejšie riadky. Do prvej trojice premenných PKG_NAME, PKG_VERSION, PKG_REVISION zapíšeme základne informácie o baličku, jeho meno, verziu a revízne číslo. Na základe týchto údajov, sa vygeneruje výsledný *.ipk súbor. Do premennej PKG_BUILD_DIR zapíšeme cestu, kde sa naša aplikácia bude kompilovať. Ide o adresár package/hello. Ďalej nasleduje sekcia define Package/hello. V tejto časti sa zadávajú informácie o baličku ako jeho popis, závislosti, kategória a sekcia programu. V našom prípade, sa jedna len o meno a popis programu. Ďalšia sekcia je define Build/Compile. Do tejto časti vložíme skript, ktorý skompilujte náš program. Je potrebne si uvedomiť, že pre kompiláciu sa nepoužíva klasicky kompilátor GCC ale upravený kompilátor. Jeho meno je v premennej $(TARGET_CC). Posledná časť je Package/hello/install. Do tejto časti, sa umiestňuje čo sa ma kde kopírovať, keď dáme náš balíček inštalovať. Je čas zahájiť kompiláciu a build nášho balička. K tomu nieje potrebne nič viac, ako spustiť nasledujúci sled príkazov v adresári OpenWrt-SDK-Linux-i686-1.
sn3d@sn3d-laptop:~/OpenWrt-SDK-Linux-i686-1$ make clean
sn3d@sn3d-laptop:~/OpenWrt-SDK-Linux-i686-1$ make world
V prípade, že kompilácia zlyhala z nejakého dôvodu, je možne zapnúť kompletný výpis, pomocou make world V=99. Ak naopak všetko prebehlo v poriadku, v adresári ~/OpenWrt-SDK-Linux-i686-1/bin/packages nájdeme náš skompilovaný balíček hello_1.0-1_mipsel.ipk. Náš novovytvorený balíček, teraz prenesieme na zariadenie s OpenWRT do adresára /tmp. To môžeme uskutočniť rôznym spôsobom, buď cez FTP. No, v prípade, že na našom zariadení nebeží FTP, tak použijeme SCP.
sn3d@sn3d-laptop:~/OpenWrt-SDK-Linux-i686-1/bin/packages$ scp hello_1.0-1_mipsel.ipk root@192.168.1.1:/tmp/
Teraz sa nalogujeme na naše zariadenie s OpenWRT. V adresári /tmp, by sme mali mať náš balíček. Na inštaláciu balička použijeme ipkg, a to nasledovným spôsobom:
root@OpenWrt:~# ipkg install hello_1.0-1_mipsel.ipk
Inštalácia balíčka, by mala prebehnúť bez problémov. Náš program, by sa mal momentálne nachádzať v /usr/bin. Ako posledné si náš program spustíme a mali by sme dostať nasledujúci text:
root@OpenWrt:~# hello
Hello World
Závislosti na knižniciach a C++
Teraz si ukážeme ako na C++ program, a taktiež si demonštrujeme, ako sa vytvára závislosť nášho programu na určitej knižnici. V adresári package si teraz vytvoríme adresár hello2, kam uložíme main.cc z nasledujúcim obsahom.main.cc:
#include
using namespace std;
int main()
{
cout << "Hello World++" << endl;
return 0;
}
Ide o najjednoduchší C++ program. Takmer každý C++ program pre svoju funkčnosť potrebuje knižnicu stdlib++. V OpenWRT existuje takto knižnica ako uclibc++. Ak použijete Makefile z prvého príkladu, pri kompilácii z V=99 sa na vás vyvalí množstvo chýb. Poďme si teda upraviť Makefile, tak aby kompilácia prebehla. Makefile:
include $(TOPDIR)/rules.mk
PKG_NAME:=hello2
PKG_VERSION:=1.0
PKG_RELEASE:=1
PKG_BUILD_DIR:=$(BUILD_DIR)/hello2
include $(INCLUDE_DIR)/package.mk
define Package/hello2
TITLE:=Hello World for C++
DESCRIPTION:=\
A simple HELLO WORLD program for C++
DEPENDS:=uclibc++
endef
define Build/Compile
$(TARGET_CC) $(TARGET_CFLAGS) -luClibc++ -o $(PKG_BUILD_DIR)/hello2 main.cc
endef
define Package/hello2/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/zvrp $(1)/usr/bin/
endef
$(eval $(call BuildPackage,hello2))
Nastali tu dve základne zmeny. Do sekcie define Package/hello2 pribudol riadok z DEPENDS. Do tejto premennej sa vkladajú mena všetkých knižníc, na ktorých je balíček závislý. Ipkg pri inštalácii, tento zoznam prejde a keď zisti, že v systéme sa potrebná knižnica nenachádza, vypíše nám chybu. V tomto prípade je potrebná uclibc++ knižnica. Ďalšiu dôležitú vec sme pridali do sekcie Build/Compile. Ide o prepínač -luClibc++, ktorý hovorí kompilátoru, aby prilinkoval knižnicu uclibc++. V ostatných prípadoch sa zmenilo len meno balička z hello na hello2. Teraz už môžeme prejsť ku kompilácii pomocou make world. Po úspešnej kompilácii, by sme mali mat opäť v adresári bin/packages/ súbor hello2_1.0-1_mipsel.ipk, ktorý prenesieme opäť do /tmp adresára na našom zariadení, a to pomocou SCP.
sn3d@sn3d-laptop:~/OpenWrt-SDK-Linux-i686-1/bin/packages$ scp hello2_1.0-1_mipsel.ipk root@192.168.1.1:/tmp/
Prihlásime sa na naše zariadenie a pokúsime sa nainštalovať balíček. Pravdepodobne, keď inštalujete na čerstvo flashnuty OpenWRT, dostanete nasledujúcu chybu:
root@OpenWrt:~# ipkg install hello2_1.0-1_mipsel.ipk
Installing hello2 (1.0-1) to root...
Nothing to be done
An error ocurred, return value: 1.
Collected errors:
ERROR: Cannot satisfy the following dependencies for hello2:
uclibc++
Dôvod je nám hneď jasný. Totižto v systéme neexistuje uclibc++, na ktorej je závislí náš program hello2. Z toho dôvodu ipkg nenainštaluje náš program. Najprv si teda budeme musieť zaobstarať balíček chýbajúcej knižnice. Balíčky sa nachádzajú na downloads.openwrt.org, alebo necháme ipkg, aby balíček našiel a stiahol sám, ako to robí apt v Ubuntu.
root@OpenWrt:~# ipkg update
root@OpenWrt:~# ipkg install uclibc++
Po úspešnej inštalácii knižnice, je teraz už možné náš balíček nainštalovať. Po úspešnej inštalácii, už môžeme náš program spustiť. Mali by sme dostať nasledujúci výstup:
root@OpenWrt:~# hello2
Hello World++