Temat: Poradnik: Kompilacja skrośna dla OpenWrt (i inne) za pomocą Dockcross
Witajcie!
Jeśli kiedykolwiek próbowaliście skompilować własne programy C/C++ na komputerze PC, by uruchomić je na urządzeniu z architekturą ARM (np. Raspberry Pi, router OpenWrt), z pewnością spotkaliście się z problemem konfiguracji środowiska.
Dockcross to genialne rozwiązanie, które używa Dockera do tworzenia gotowych i czystych środowisk do cross-kompilacji (kompilacji skrośnej).
---
1. Czym jest i jak działa Dockcross?
Dockcross udostępnia wstępnie skonfigurowane obrazy Docker z kompletnym łańcuchem narzędziowym (toolchain) dla różnych architektur (ARM, MIPS, x86, itd.).
Zamiast instalować na swoim komputerze (HOSCIE) wszystkie kompilatory i biblioteki dla docelowej architektury (TARGET), po prostu uruchamiasz kontener, który ma już to wszystko w środku.
Podstawowy proces:
1. Wybierasz obraz Dockcross dla swojego urządzenia docelowego (np. OpenWrt AArch64).
2. Dockcross uruchamia kontener, mapując Twój katalog z kodem źródłowym do wnętrza kontenera.
3. Wewnątrz kontenera wykonujesz standardowe polecenia kompilacji (np. CMake, Make).
4. Skompilowana binarka pojawia się w Twoim lokalnym katalogu, gotowa do wgrania na urządzenie docelowe.
---
2. Kluczowy Krok: Wybór Właściwego Obrazu (OpenWrt/Musl)
To jest najczęstsze źródło błędów! Jeśli kompilujesz dla minimalistycznego Linuksa (jak większość dystrybucji OpenWrt, które używają biblioteki Musl C Library), musisz użyć obrazu Dockcross, który również jest zbudowany w oparciu o Musl, a nie standardowe GLIBC.
Aby sprawdzić architekturę docelową (np. na routerze OpenWrt), użyj:
uname -m
Wybór obrazu dla OpenWrt (przykład AArch64):
* Zły wybór: dockcross/linux-arm64 (Używa GLIBC, co spowoduje błąd "not found" na OpenWrt).
* Właściwy wybór: dockcross/linux-arm64-musl
---
3. Poradnik Krok po Kroku (z CMake)
Zakładamy, że masz zainstalowany Docker i pliki CMakeLists.txt oraz main.cpp w katalogu projektu (np. /moj_projekt).
Krok 1: Wygenerowanie Skryptu Pomocniczego
Używamy obrazu dockcross/linux-arm64-musl do stworzenia lokalnego, wykonywalnego skryptu o nazwie ./dockcross.
Polecenia:
docker run --rm dockcross/linux-arm64-musl > ./dockcross
chmod +x ./dockcross
Krok 2: Uruchomienie Procesu Kompilacji (z użyciem skryptu)
Całe polecenie kompilacji jest przekazywane do skryptu ./dockcross, który wykonuje je wewnątrz kontenera.
Polecenie:
./dockcross bash -c "mkdir -p build && cd build && cmake .. && make -j$(nproc)"
(Polecenie bash -c "..." wykonuje standardowe kroki CMake: tworzy katalog 'build', konfiguruje projekt i kompiluje.)
Krok 3: Unikanie Problemów z Linkerem (Kompilacja Statyczna)
Jeśli po wgraniu program nadal nie działa z błędem "not found" lub brakuje bibliotek dynamicznych, spróbuj wymusić konsolidację statyczną. Zmień swój plik CMakeLists.txt tak, by dodać te flagi linkera:
Flagi w CMakeLists.txt:
target_link_libraries(twoj_program PRIVATE -static-libstdc++ -static-libgcc)
To wbuduje standardowe biblioteki bezpośrednio w Twoją binarkę, czyniąc ją samowystarczalną.
---
4. Diagnoza Błędów Uruchomienia (ldd)
Jeśli skompilowany plik twoj_program nadal nie działa na OpenWrt, użyj narzędzia ldd bezpośrednio na urządzeniu docelowym, aby sprawdzić, których bibliotek dynamicznych mu brakuje:
Polecenie na OpenWrt:
ldd ./twoj_program
Jeśli ldd wskaże na brak podstawowych bibliotek (libc.so.6 lub ld-linux-aarch64.so.1 nie są znalezione), to na 99% oznacza, że używasz niewłaściwej wersji Dockcross (np. GLIBC zamiast MUSL).
---
Mam nadzieję, że ten poradnik ułatwi Wam pracę z cross-kompilacją! Pytania mile widziane!
https://github.com/dockcross/dockcross
P.S. Większość obrazów Dockcross znajdziecie w oficjalnym repozytorium na Docker Hub, szukając dockcross/[architektura].