Wprowadzenie do systemu budowania CMake

post-thumb

CMake to narzędzie open-source przeznaczone do automatyzacji procesu budowania oprogramowania. Z mojego doświadczenia mogę stwierdzić, że narzędzie to stało się de facto standardem wykorzystywanym w branży embedded. By uzmysłowić sobie, dlaczego właściwie potrzebujemy narzędzia do budowania, warto prześledzić przykład projektu.

Przykład projektu kamery bezpieczeństwa do domu

Kamera bezpieczeństwa będzie przetwarzać obraz, aby wykrywać ruch i identyfikować obiekty. Może posiadać dodatkowe czujniki do aktywacji lub informowania o zdarzeniach, umożliwiać komunikację z telefonem i wysyłanie danych do chmury. Na poziomie sprzętowym (HW), może to wymagać dwóch układów SoC (System on Chip):

  • Pierwszy SoC do przetwarzania obrazu i wysyłania danych do chmury z zainstalowanym systemem embedded Linux.
  • Drugi Soc z systemem czasu rzeczywistego FreeRTOS do obsługi danych z pozostałych czujników i zarządzania energią.

Projekt ten wykorzystuje również wiele zewnętrznych bibliotek np.

  • mbedTLS (dla bezpieczeństwa komunikacji),
  • NimBLE (Bluetooth stack),
  • libwebsockets (serwer/klient HTTP),
  • GStreamer (strumieniowanie/przetwarzanie wideo).

Głównymi językami używanymi w projekcie są C/C++, a dokumentacja jest tworzona przy użyciu Doxygen. Wykorzystujemy Continuous Integration (CI), co umożliwia nam automatyczne budowanie i testowanie oprogramowania na serwerze.

Nasz zespół składa się z 12 programistów, z których część pracuje na Ubuntu Linux, a część na MacOS. Dodatkowo, każdy ma swoje preferencje dotyczące środowiska IDE, takie jak Visual Studio Code, CLion, Vim, czy Emacs.

Mapa myśli przedstawiająca złożoność projektu

Cechy CMake

Z powyższego opisu projektu wynika wiele wymagań, które musi spełnić system budowania. Jak możesz się spodziewać, CMake je spełnia, oferując:

  • niezależność od platformy i kompilatorów: CMake umożliwia tworzenie projektów, które mogą być kompilowane na różnych systemach operacyjnych (takich jak Linux, Windows, macOS) bez zmian w plikach konfiguracyjnych.
  • niezależność od architektury: CMake ułatwia cross-compilation, czyli kompilację oprogramowania na inną architekturę (np. ARM, RISC-V) niż ta, na której budujemy (np. x86). Pozwala na łatwy wybór konkretnego zestawu narzędzi(toolchain) dla poszczególnych układów.
  • zarządzanie różnymi konfiguracjami budowania: np. Debug (większa ilość logów, funkcjonalności przydatnych podczas rozwoju oprogramowania) oraz Release (oprogramowanie produkcyjne).
  • zarządzanie zależnościami projektowymi, w tym zewnętrznymi bibliotekami.
  • łatwa integracja z systemem generowania dokumentacji (Doxygen).
  • łatwość integracji z IDE: np. Visual Studio, Eclipse, CLion, Vim, Emacs.
  • automatyzacja testów przy użyciu CTest, który umożliwia organizację testów w grupy, dostarcza szczegółowych wyników i może być zintegrowany z systemami CI.

Ważne, żeby zrozumieć, że CMake działa na wyższym poziomie abstrakcji niż takie narzędzia jak Make i Ninja. Cmake tak naprawdę służy do generowania plików systemu budowania w tym Makefile i build.ninja.

Porównanie z innymi systemami budowania

  • Make jest klasycznym narzędziem do budowania oprogramowania, szczególnie w środowiskach Unixowych. Pozwala na precyzyjne kontrolowanie procesu budowania i jest często wykorzystywany w systemach embedded. Jednak przygotowanie ręczne plików Makefile może być czasochłonne i skomplikowane dla dużych projektów.

  • Ninja to narzędzie zaprojektowane do szybkiego przetwarzania dużych projektów, minimalizując niepotrzebne ponowne kompilacje. Chociaż można przygotować samodzielnie pliki konfiguracyjne, to Ninja najczęściej używany jest z innymi systemami generującymi, takimi jak CMake i Meson. W ten sam sposób następuję też integracja tego build systemu z IDE.

  • Meson to nowoczesny system budowania, charakteryzujący się łatwością użycia i wydajnością. Podobnie jak CMake, jest przeznaczony do generowania plików konfiguracyjnych i może używać Ninja/Make jako backend. Przez to, że CMake powstał wcześniej, wiele bibliotek z niego korzysta, deweloperzy są z nim zaznajomieni i problemy budowania złożonych projektów zostały w nim rozwiązane to zdecydowanie częściej spotkasz się z tym narzędziem w embedded.

KryteriumCMakeMesonMakeNinja
Łatwość użyciaśredniawysokaśredniawysoka
Przenośnośćwysokawysokaśredniawysoka
Wydajnośćwysokawysokaśredniawysoka
Automatyczne zarządzanie zależnościamiwysokawysokaniskaniska
Integracja z IDEwysokawysokaśredniawysoka
Częstość wykorzystywania w embeddedwysokaśredniawysokaśrednia

Podsumowanie

Mam nadzieję, że teraz już wiesz dlaczego potrzebujemy efektywnego systemu budowania i dlaczego właśnie CMake powinien znaleźć się w Twoim arsenale. W kolejnych artykułach zapoznasz się ze specyfiką tego narzędzia.

comments powered by Disqus