Вы можете попробовать кросс-компиляцию своего кода, чтобы обойти эту проблему.
Для цепочки инструментов вы можете использовать Crosstool-NG . Получение Python для кросс-компиляции - немного больше работы, и я не буду go подробно об этом здесь. Я отошлю вас к Dockerfile и сценариям оболочки , которые я использовал. Вы можете найти больше информации о них здесь .
Для целей этого ответа я собираюсь использовать Docker изображения, которые я построил сам. Они доступны из Docker Hub. Конечно, вы можете создать их самостоятельно, если хотите, исходный код доступен в репозитории GitHub, на который я ссылался ранее. Если вам не нужны NumPy и OpenCV, обязательно закомментируйте все это в Dockerfile, потому что для кросс-компиляции требуется много времени.
Я использовал цепочку инструментов для Linux 4.15 и позже. Если вы используете Raspbian Stretch, его ядро может быть слишком старым. Это должно работать на Raspbian Buster и Ubuntu 18.04 и более поздних версиях. Если вы действительно хотите использовать Stretch, вам нужно отредактировать файл конфигурации цепочки инструментов, как объяснено здесь , и собрать цепочку инструментов самостоятельно. То же самое касается версии Python. По умолчанию используется Python 3.8.2.
1. Подготовьте свой рабочий каталог
Подготовьте папку, содержащую весь код, который вы хотите кросс-компилировать. Если у вас есть внешние зависимости, которые вы можете легко перемещать, поместите их в папку. Позже мы просто смонтируем эту папку в контейнер Docker.
2. Напишите команды сборки в небольшом сценарии оболочки
Создайте файл build-docker.sh
, который содержит все команды, которые вы хотите выполнить, в контейнере Docker для создания кода.
set -ex
PY_CONFIG="${RPI_SYSROOT}/usr/local/bin/python3.8-config"
OPTS=$(${PY_CONFIG} --cflags --ldflags)
CC=${HOST_TRIPLE}-gcc
${CC} ${OPTS} CCODE.c -o EXECUTABLE_CODE
Примечание как я использовал скрипт python3.8-config
в папке sys root Raspberry Pi. Если вы просто используете python3.8-config
без указания полного пути, он будет использовать конфигурацию установки Python на сборочной машине, а это не то, что вам нужно.
Вам также нужно указать кросс-компилятор. Опять же, если вы просто напишите gcc
, он использует собственный компилятор x86_64 системы сборки. Вам нужен кросс-компилятор ARM.
3. Запустите скрипт в Docker контейнере
Ваш рабочий каталог должен выглядеть следующим образом:
.
├── build-docker.sh
└── CCODE.c
Теперь мы запустим контейнер Docker с необходимыми инструментами кросс-компиляции , смонтируйте в нем рабочий каталог, чтобы вы могли получить доступ к своему CCODE.c
и запустите команды сборки в только что написанном нами скрипте.
docker run \
--rm \
-it \
-v "$PWD:/tmp/workdir" \
-w "/tmp/workdir" \
tttapa/rpi-cross:armv8-rpi3-linux-gnueabihf \
"bash" "build-docker.sh"
При первом запуске он вытянет изображение из Docker Hub, так что это займет некоторое время (больше ГиБ).
Когда сборка будет завершена, у вас должен остаться файл EXECUTABLE_CODE
в вашем рабочем каталоге:
$ file EXECUTABLE_CODE
EXECUTABLE_CODE: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV),
dynamically linked, interpreter /lib/ld-linux-armhf.so.3,
for GNU/Linux 4.15.18, with debug_info, not stripped
Более подробный пример вы можете найти здесь: https://github.com/tttapa/RPi-Cpp-Toolchain/tree/master/extra/python/cross-compile-module/spam
Небольшая рекомендация: если вы пишете много кода, который требует взаимодействие между C / C ++ и Python, или код, который включает интерпретатор Python, Pybind11 - отличный инструмент. Он имеет привязки для всех стандартных контейнеров C ++ и типов Python / NumPy / Eigen, он позволяет вызывать код Python из кода C ++, экспортировать функции / структуры / классы C / C ++ в виде Python модулей и обрабатывает всю компиляцию для вы используете CMake: https://github.com/pybind/cmake_example
Редактировать: Если ваш секретный CCODE должен вставлять Python, вы должны связаться с lib python :
https://docs.python.org/3.8/whatsnew/3.8.html#debug -build-использует-то-же-abi-as-release-build
Для встраивания Python в приложение, новая опция --embed
должна быть передана в python3-config --libs --embed
, чтобы получить -lpython3.8
(свяжите приложение с lib python).
OPTS=$(${PY_CONFIG} --cflags --ldflags --embed)