Jak mogę wykryć, że kompiluję dla Raspberry Pi?

24

Ponieważ Raspberry Pi potrzebuje trochę specjalnego kodu (o którym mówię C/C++), aby uzyskać dostęp do niektórych funkcji sprzętowych (np. Połączenia z bcm_host_init()). Szukam niezawodnego i eleganckiego sposobu na automatyczne wykrycie tego. Nie sądzę, aby istniał jakiś kompilator #defines, _WIN32który mógłby nadużywać, więc wykrycie go CMake(które może wykonywać skrypty powłoki) byłoby wystarczające. Chciałbym również, aby ta metoda działała w większości, jeśli nie we wszystkich dystrybucjach.

Jednym ze sposobów, mogę myśleć, że mogę spojrzeć na przykład /opt/vc/include/bcm_host.hpliku (co nie jest trudne), a także upewnić się, że architektura ARM (który jest łatwy w czasie kompilacji, ponieważ istnieją #definemakra, które, na przykład __arm__z __ARMEL__). Ta dodatkowa kontrola łuku ma zapobiec fałszywie dodatnim wynikom, gdy masz środowisko kompilacji krzyżowej na innym komputerze, ale nie jest to kompilacja krzyżowa. Czy istnieje inny, lepszy sposób niż ten?

Tapio
źródło

Odpowiedzi:

20

Sprawdzanie w czasie konfiguracji / kompilacji funkcji, od których zależy Twój kod, jest właściwą drogą. Sprawdzanie konkretnych urządzeń jest problematyczne, ponieważ unikanie fałszywych alarmów jest praktycznie niemożliwe (ktoś mógłby celowo okłamać cię nawet przy niewielkim wysiłku), a celem takich kontroli jest odpowiedź na pytanie: „czy mogę tu zbudować? Jeśli tak, jaką ścieżkę kodu należy Używam? ” , nie „czy to jest urządzenie, które podoba mi się nazwa?”


Zgodnie z tym odniesieniem (ogólnie doskonałym źródłem informacji o predefiniowanych makrach) możesz użyć makra:

__arm__

Aby wykryć kombinację GCC / Arm.

Sprawdziłem to na moim:

#include <stdio.h>

int main() {
  #ifdef __arm__
  printf("Why yes it is, thank you\n");
  #endif
  return 0;
}

Które rzeczywiście wydrukowały wiadomość.

Zauważ, że spowoduje to również złapanie wszystkich urządzeń uzbrojenia, więc zalecam użycie części twojego narzędzia do budowania (np. cmake/autoconf), Aby sprawdzić również obecność /opt/vc/include/bcm_host.h.

Na przykład z

AC_CHECK_HEADERS
w autoconf:

AC_CHECK_HEADERS(/opt/vc/include/bcm_host.h)

powoduje:

HAVE__OPT_VC_INCLUDE_BCM_HOST_H

do zdefiniowania w config.h

Lub dla CMake:

include(CheckIncludeFile)
CHECK_INCLUDE_FILE(/opt/vc/include/bcm_host.h BCMHOST)

Nie sądzę, że istnieje lepszy sposób na wykrycie tego naprawdę - możesz skonfigurować / CMake szukać rzeczy specyficznych dla sprzętu, ale będą inne platformy z tym samym SoC, więc nawet to nie jest tak naprawdę niezawodne i na czym ci zależy istnieje plik nagłówkowy, ponieważ informuje o tym, jak zbudować dla danego celu. Nawet jeśli możesz udowodnić, że jest to Raspberry Pi, ale nie możesz znaleźć odpowiedniego pliku nagłówka, nadal utkniesz, a wczesny błąd jest lepszy niż brak kompilacji.

Jeśli naprawdę chcesz sprawdzić, czy jest to Pi (lub wystarczająco podobny), możesz zastosować coś prostego:

grep -o BCM2708 /proc/cpuinfo

lub (dla raspberrypi 2 i 3):

grep -o BCM2709 /proc/cpuinfo

w czasie konfiguracji, który będzie pasował do SoC, na którym opiera się Raspberry Pi.

Możesz rzucić jeszcze kilka testów (np. USB pomoże ci to rozgryźć nieco więcej, a nawet podpowie, jeśli jest to urządzenie typu A lub B), ale nic nie jest wystarczające, aby powiedzieć na pewno.

Możesz sprawdzić skróty plików w katalogu / boot ze znaną listą, ale wtedy nie będziesz w stanie zbudować, jeśli istnieje aktualizacja oprogramowania układowego lub nieoficjalna, o której nie wiedziałeś. (Lub inne podobne urządzenia inne niż Pi z taką samą konfiguracją rozruchową)

Flexo
źródło
Być może opis mojego pomysłu nie był wystarczająco jasny, ale __ARMEL__sposób definiowania jest dokładnie taki jak twój __arm__. Po prostu nie zadałem sobie trudu, aby znaleźć najlepsze makro.
Tapio
Zmodyfikowałem opis pomysłu, aby wyjaśnić, że również szukanie pliku nie stanowi problemu - szukam innych, lepszych sposobów na zrobienie tego, a nie sposobu wdrożenia przedstawionego pomysłu.
Tapio
@ Tapio - nie sądzę, żeby to był właściwy problem - nawet jeśli udowodnisz, że to Pi, że informacje są bezużyteczne bez plików nagłówkowych, musisz zbudować swój kod Pi. Nawet jeśli znajdziesz urządzenie BCM nie-Pi, kod, który piszesz dla Pi, będzie prawdopodobnie działał dobrze, jeśli jest oparty na tym samym SoC.
Flexo,
Masz rację. Ta myśl przyszła mi do głowy, ale nie myślałem o tym wystarczająco. W każdym razie Twoje zmiany sprawiają, że jest to doskonała odpowiedź, którą warto zaakceptować.
Tapio
2
Sprawdzenie /opt/vc/include/bcm_host.h- jak to działa w przypadku kompilacji krzyżowej, ponieważ plik prawdopodobnie nie znajduje się w tym miejscu na (kompilującej) maszynie hosta? Podobnie grep -o BCM2grep -o BCM2708 /proc/cpuinfo708 /proc/cpuinfowykrywa host kompilacji, a nie cel ...?
SlySven