Я установил python 3.9.1 на свой Raspberry Pi, следуя инструкциям здесь https://www.ramoonus.nl/2020/10/06/how-to-install-python-3-9-on-raspberry-pi/ и установите его в качестве интерпретатора Python по умолчанию. Я получил параметры компиляции и компоновки для встроенного Python, следуя инструкциям здесь https://docs.python.org/3.9/extending/embedding.html#compiling-and-linking-under-unix-like-systems
Я попробовал простой тест со следующим кодом (test.c):
#include <Python.h>
int
main(int argc, char *argv[])
{
wchar_t *program = Py_DecodeLocale(argv[0], NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
exit(1);
}
Py_SetProgramName(program); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print('Today is', ctime(time()))\n");
Py_Finalize();
PyMem_RawFree(program);
return 0;
}
а потом
gcc -I/usr/local/opt/python-3.9.1/include/python3.9 -I/usr/local/opt/python-3.9.1/include/python3.9 -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -c test.c -o test.o
и
gcc -L/usr/local/opt/python-3.9.1/lib/python3.9/config-3.9-arm-linux-gnueabihf -L/usr/local/opt/python-3.9.1/lib -lcrypt -lpthread -ldl -lutil -lm -o test.o
и получил
/usr/lib/gcc/arm-linux-gnueabihf/4.9/../../../arm-linux-gnueabihf/crt1.o: In function '_start': /build/glibc-P1SmLh/glibc-2.19/csu/../ports/sysdeps/arm/start.S:119: undefined reference to 'main' collect2: error: ld returned 1 exit status
Попытка скомпилировать пример на https://docs.python.org/3.9/extending/embedding.html#pure-embedding выдает ту же ошибку. В чем может быть проблема?
Редактировать: После комментария Expolarity я изменил команду компоновщика на:
gcc test.o -L/usr/local/opt/python-3.9.1/lib/python3.9/config-3.9-arm-linux-gnueabihf -L/usr/local/opt/python-3.9.1/lib -lcrypt -lpthread -ldl -lutil -lm -o test
который, похоже, сработал, но выдал мне кучу других ошибок:
test.o: В функции main': /home/pi/Downloads/test.c:6: undefined reference to
Py_DecodeLocale'
/home/pi/Downloads/test.c:11: неопределенная ссылка на Py_SetProgramName' /home/pi/Downloads/test.c:12: undefined reference to
Py_Initialize'
/home/pi/Downloads/test.c:13: неопределенная ссылка на PyRun_SimpleStringFlags' /home/pi/Downloads/test.c:15: undefined reference to
Py_Finalize'
/home/pi/Downloads/test.c:16: неопределенная ссылка на `PyMem_RawFree'
collect2: ошибка: ld вернул 1 статус выхода
Это кажется более серьезным. Есть идеи?
Я считаю, что набрать просто test, как я сделал вместо test.o, то же самое. Я попробовал test.o и все равно выдает ту же ошибку.
Если вы пробовали другие команды, пожалуйста, отредактируйте свой вопрос, скопируйте и вставьте точную команду и вывод, а не расплывчато описывайте, что вы сделали. Чтобы прояснить мой предыдущий комментарий: в команде компоновщика удалите /usr/bin/g++
и вместо этого добавьте test.o
.
вы пытаетесь запустить несвязанный объектный файл ELF, вам нужно связать его, чтобы он был исполняемым файлом ELF. если быть точным, эта команда должна работать: gcc test.o -L/usr/local/opt/python-3.9.1/lib/python3.9/config-3.9-arm-linux-gnueabihf -L/usr/local/opt/python-3.9.1/lib -lcrypt -lpthread -ldl -lutil -lm -o test
Ладно, это прогресс! Кажется, вы забыли указать ссылку на библиотеку python, попробуйте gcc test.o -L/usr/local/opt/python-3.9.1/lib/python3.9/config-3.9-arm-linux-gnueabihf -L/usr/local/opt/python-3.9.1/lib -lpython3.9 -lcrypt -lpthread -ldl -lutil -lm -o test
, параметр -L
в верхнем регистре указывает каталоги для поиска библиотек (которые затем указываются с использованием нижнего регистра -l
)
После ответа tttapa над здесь он, наконец, сработал, настроив команду компоновщика следующим образом:
gcc test.o -L/usr/local/opt/python-3.9.1/lib/python3.9/config-3.9-arm-linux-gnueabihf -L/usr/local/opt/python-3.9.1/lib -lcrypt -lpthread -ldl -lutil -lm -lpython3.9 -o test
Обновлено: Expolarity также правильно ответила сразу после tttapa. Большое спасибо всем!
Строка
gcc /usr/bin/g++ -L/usr/local/opt/python-3.9.1/...
не содержит объектного файлаtest.o
(который содержит вашу функциюmain
) и вместо этого попытается скомпилировать или связать/usr/bin/g++
. Разве вы не получаете сообщение об ошибке о/usr/bin/g++
?