Wie kann ich feststellen, dass ich für Raspberry Pi kompiliere?

24

Da Raspberry Pi einen speziellen Code benötigt (ich spreche C/C++), um auf einige Hardwarefunktionen zuzugreifen (z. B. einen Anruf an bcm_host_init()). Ich suche nach einer zuverlässigen und eleganten Möglichkeit, dies automatisch zu erkennen. Ich glaube nicht, dass es einen Compiler gibt #defines, den _WIN32ich missbrauchen könnte. Es CMakewürde also ausreichen , ihn zu entdecken (der Shell-Skripte ausführen kann). Ich möchte auch, dass die Methode in den meisten, wenn nicht allen Distributionen funktioniert.

Ich kann mir zum Beispiel /opt/vc/include/bcm_host.hvorstellen, dass ich nach einer Datei suchen könnte (was nicht schwierig ist) und auch prüfen könnte, ob die Architektur ARM ist (was zur Kompilierungszeit einfach ist, da es #defineMakros dafür gibt, zum Beispiel __arm__von __ARMEL__). Diese zusätzliche Arch-Prüfung dient dazu, Fehlalarme zu vermeiden, wenn Sie auf einem anderen Computer über eine Cross-Compiler-Umgebung verfügen, diese jedoch derzeit nicht überqueren. Gibt es einen anderen, besseren Weg als diesen?

Tapio
quelle

Antworten:

20

Überprüfen Sie zum Zeitpunkt der Konfiguration / Kompilierung, von welchen Funktionen Ihr Code abhängt. Das Überprüfen auf bestimmte Geräte ist problematisch, da das Vermeiden von Fehlalarmen praktisch unmöglich ist (jemand könnte Sie auch mit geringem Aufwand absichtlich anlügen) und das Ziel solcher Überprüfungen darin besteht, die Frage zu beantworten: "Kann ich hier bauen? Wenn ja, welcher Codepfad soll Ich benutze? " , nicht "Ist dies ein Gerät, dessen Namen mir gefällt?"


Entsprechend dieser Referenz (eine großartige Informationsquelle zu vordefinierten Makros im Allgemeinen) können Sie das Makro verwenden:

__arm__

Zum Erkennen der GCC / Arm-Kombination.

Ich überprüfte dies auf meinem mit:

#include <stdio.h>

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

Welche hat in der Tat die Nachricht gedruckt.

Beachten Sie, dass dies auch alle Arm-Geräte erfasst. Daher empfehle ich, einen Teil Ihres Build-Tools zu verwenden (z. B. cmake/autoconf), um zu prüfen, ob auch Arm-Geräte vorhanden sind /opt/vc/include/bcm_host.h.

Zum Beispiel mit

AC_CHECK_HEADERS
in autoconf:

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

Ursachen:

HAVE__OPT_VC_INCLUDE_BCM_HOST_H

zu definieren in config.h

Oder für CMake:

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

Ich glaube nicht, dass es einen besseren Weg gibt, dies wirklich zu erkennen - Sie könnten konfigurieren / CMake nach hardwarespezifischen Dingen suchen lassen, aber es wird andere Plattformen mit demselben SoC geben, auch wenn dies nicht wirklich zuverlässig ist und was Sie wirklich interessiert ist das Vorhandensein dieser Header-Datei, da diese Sie darüber informiert, wie Sie für das angegebene Ziel erstellen. Auch wenn Sie nachweisen können, dass es sich um einen Raspberry Pi handelt, Sie aber nicht die richtige Header-Datei finden können, stecken Sie immer noch fest, und ein früher Fehler ist besser als eine Fehlkonstruktion.

Wenn Sie wirklich überprüfen möchten, ob es sich um einen Pi (oder einen ausreichend ähnlichen) handelt, können Sie auf Folgendes zurückgreifen:

grep -o BCM2708 /proc/cpuinfo

oder (für raspberrypi 2 und 3):

grep -o BCM2709 /proc/cpuinfo

zum Zeitpunkt der Konfiguration, die mit dem SoC übereinstimmt, auf dem der Raspberry Pi basiert.

Sie könnten ein paar weitere Tests durchführen (z. B. USB hilft Ihnen dabei, es ein bisschen besser zu verstehen und gibt sogar einen Hinweis darauf, ob es sich um ein Gerät des Modells A oder B handelt), aber nichts ist ausreichend, um es mit Sicherheit zu sagen.

Sie könnten die Hashes von Dateien in / boot anhand einer bekannten Liste überprüfen, aber dann können Sie keine Dateien erstellen, wenn es ein Firmware-Update oder ein inoffizielles gibt, von dem Sie nichts wissen. (Oder andere ähnliche Nicht-Pi-Geräte mit demselben Start-Setup)

Flexo
quelle
Vielleicht war die Beschreibung meiner Idee nicht klar genug, aber der __ARMEL__definierte Weg ist genau wie bei Ihnen __arm__. Ich habe mich einfach nicht darum gekümmert, das beste Makro zu finden.
Tapio
Ich habe meine Ideenbeschreibung geändert, um zu verdeutlichen, dass auch das Suchen nach der Datei nicht das Problem ist. Ich suche nach verschiedenen, besseren Möglichkeiten, dies zu tun, und nicht nach Möglichkeiten, die von mir vorgestellte Idee umzusetzen.
Tapio
@ Tapio - Ich glaube nicht, dass das das richtige Problem ist - auch wenn Sie beweisen, dass es sich um einen Pi handelt, sind Informationen ohne die Header-Dateien, die Sie zum Erstellen Ihres Pi-spezifischen Codes benötigen, nutzlos. Selbst wenn Sie ein BCM-Gerät finden, das kein Pi ist, läuft der Code, den Sie für den Pi schreiben, wahrscheinlich einwandfrei, wenn er auf demselben SoC basiert.
Flexo
Du hast recht. Dieser Gedanke kam mir in den Sinn, aber ich habe nicht genug darüber nachgedacht. Aufgrund Ihrer Änderungen ist dies eine hervorragende Antwort, die es sich zu akzeptieren lohnt.
Tapio
2
Die Prüfung auf /opt/vc/include/bcm_host.h- wie funktioniert das bei der Cross-Kompilierung, da die Datei wahrscheinlich nicht an dieser Stelle auf dem (kompilierenden) Hostcomputer gespeichert ist? Ebenso grep -o BCM2grep -o BCM2708 /proc/cpuinfo708 /proc/cpuinfowird der Compilation-Host nicht das Ziel erkennen ...?
SlySven