Как я могу определить, что я компилирую для Raspberry Pi?

24

Поскольку Raspberry Pi требуется немного специального кода (о котором я говорю C/C++) для доступа к некоторым аппаратным функциям (например, к вызову bcm_host_init()). Я ищу надежный и элегантный способ обнаружить это автоматически. Я не думаю, что есть какой-либо компилятор #defines, который _WIN32я мог бы использовать неправильно, поэтому его обнаружения CMake(который может выполнять сценарии оболочки) было бы достаточно. Я также хотел бы, чтобы метод работал в большинстве, если не во всех дистрибутивах.

Один из способов я могу думать о том , что я мог бы найти , например , /opt/vc/include/bcm_host.hфайл (который не трудно), а также проверить , что архитектура ARM (что легко во время компиляции есть #defineмакросы для этого, например , __arm__в __ARMEL__). Эта дополнительная проверка дуги предназначена для предотвращения ложных срабатываний, когда у вас есть среда кросс-компиляции на другом компьютере, но в настоящее время кросс-компиляция не выполняется. Есть ли другой, лучший способ, чем этот?

Тапио
источник

Ответы:

20

Проверка во время настройки / компиляции функций, от которых зависит ваш код, - это путь. Проверка на определенные устройства проблематична, потому что избежать ложных срабатываний практически невозможно (кто-то может обмануть вас преднамеренно даже без особых усилий), и цель таких проверок состоит в том, чтобы ответить на вопрос: «Могу ли я построить здесь? Если да, какой путь кода должен Я буду использовать? , а не "это устройство мне нравится имя?"


Согласно этой ссылке (отличный источник информации о предопределенных макросах в целом) вы можете использовать макрос:

__arm__

Для обнаружения комбинации GCC / Arm.

Я проверил это на моем с:

#include <stdio.h>

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

Который действительно напечатал сообщение.

Обратите внимание, что это также охватит все устройства Arm, поэтому я рекомендую использовать часть вашего инструмента сборки (например cmake/autoconf), чтобы проверить наличие /opt/vc/include/bcm_host.h.

Например с

AC_CHECK_HEADERS
в автоконф:

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

причины:

HAVE__OPT_VC_INCLUDE_BCM_HOST_H

быть определенным в config.h

Или для CMake:

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

Я не думаю, что есть лучший способ обнаружить это на самом деле - вы могли бы настроить / CMake искать специфичные для оборудования вещи, но будут другие платформы с таким же SoC, так что даже это не очень надежно и то, что вас действительно волнует является существованием этого заголовочного файла, так как он информирует вас о том, как построить для данной цели. Даже если вы можете доказать, что это Raspberry Pi, но не можете найти нужный заголовочный файл, вы все равно застряли, и ошибка на ранних этапах лучше, чем неправильная сборка.

Если вы действительно хотите проверить, является ли это Pi (или достаточно похожим), вы можете прибегнуть к чему-то простому, например:

grep -o BCM2708 /proc/cpuinfo

или (для малины 2 и 3):

grep -o BCM2709 /proc/cpuinfo

во время настройки, которое будет соответствовать SoC, на котором основан Raspberry Pi.

Вы можете добавить еще несколько тестов (например, USB поможет вам разобраться с этим и даже намекнуть, если это устройство модели A или B), но ничего не достаточно, чтобы сказать наверняка.

Вы можете проверить хэши файлов в / boot по известному списку, но тогда вы не сможете собрать, если есть обновление прошивки или неофициальное, о котором вы не знали. (Или другие аналогичные устройства, не поддерживающие Pi, с такой же настройкой загрузки)

Flexo
источник
Возможно, описание моей идеи не было достаточно ясным, но __ARMEL__способ определения точно такой же, как ваш __arm__. Я просто не удосужился найти лучший макрос.
Тапио
Я исправил описание своей идеи, чтобы уточнить, что поиск файла также не является проблемой - я ищу другие, более эффективные способы сделать это, а не то, как реализовать идею, которую я представил.
Тапио
@Tapio - я не думаю, что это правильная проблема - даже если вы докажете, что это Pi, информация бесполезна без заголовочных файлов, которые вам нужны для создания кода, специфичного для Pi. Даже если вы найдете устройство BCM, отличное от Pi, код, который вы пишете для Pi, вероятно, будет работать на нем, если он основан на том же SoC.
Флекс
Вы правы. Эта мысль пришла мне в голову, но я не думал об этом достаточно. В любом случае, ваши изменения делают этот ответ превосходным, и его стоит принять.
Тапио
2
Проверка /opt/vc/include/bcm_host.h- как это работает для кросс-компиляции, поскольку файл вряд ли будет в этом месте на (компилирующем) хост-компьютере? Точно так grep -o BCM2grep -o BCM2708 /proc/cpuinfo708 /proc/cpuinfoже собирается обнаружить узел компиляции, а не цель ...?
SlySven