Извините за такое общее название, но я не совсем уверен, что именно я пропал без вести или что я делаю неправильно. Моя цель - построить расширение python, используя boost.python под cygwin и избегая инструментов boost.build, которые используют make вместо bjam. Последний способ работал для меня неплохо, но теперь я хочу сделать это таким образом. Я решил много вопросов по поиску и поиску похожих тем, что помогло мне разобраться в некоторых трюках и двигаться вперед. Но на последнем этапе, похоже, есть некоторые проблемы. Я попытаюсь описать все свои шаги в некоторых деталях в надежде, что этот пост может быть полезен другим в будущем, а также лучше описать настройку.вручную создает расширение python в cygwin с boost.python
Потому что я не совсем уверен, что оригинальные (из различных Cygwin хранилищ) установок как питона и повысить я решил установить их с нуля в моем домашнем каталоге, так вот что я делаю:
сначала установите python. Я пропущу детали для этого, это более или менее просто. Для последнего описания это просто путь:
/home/Alexey_2/Soft/python2.6 - это PYTHONPATH, также входящий в состав ПУТЬ
работает над повышением:
а) распаковка источник подталкивание в
/home/Alexey_2/Soft/boost_1_50_0 - this is BOOST_ROOT
б), что делает bjam. сначала перейдите в каталог:
/home/Alexey_2/Soft/boost_1_50_0/tools/build/v2
рядом, вызовите bootstrap.sh это в конечном счете, создает b2 и bjam исполняемые файлы в этом каталоге. В .bash_profile добавьте этот каталог в PATH, чтобы мы могли вызвать bjam. Вот и после каждого будущего редактирует из .bash_profile перезапустить Cygwin, чтобы сделать изменения приходят к эффекту
с) еще в
/home/Alexey_2/Soft/boost_1_50_0/tools/build/v2
каталога - редактирования пользовательского config.jam, чтобы bjam знать который использовать python. Так что в моем случае я только добавить одну строку:
using python : 2.6 : /home/Alexey_2/Soft/python2.6/bin/python2.6 : /home/Alexey_2/Soft/python2.6/include/python2.6 : /home/Alexey_2/Soft/python2.6/bin ;
в Lib-пути (последняя запись) я поставил /home/Alexey_2/Soft/python2.6/bin, потому что он содержит libpython2.6.dll
d) хорошо. теперь мы можем создавать библиотеки boost-python. перейти к BOOST_ROOT каталог и выполнить команду
bjam --with-python toolset=gcc link=shared
это создает необходимые библиотеки (cygboost_python.dll и libboost_python.dll.a) и помещает их в
/home/Alexey_2/Soft/boost_1_50_0/stage/lib
расширение здания питона.
вот моя простая тестовая программа (на самом деле часть кода примера)
// file xyz.cpp #include <boost/python.hpp> #include <iostream> #include <iomanip> using namespace std; using namespace boost::python; class Hello { std::string _msg; public: Hello(std::string msg){_msg = msg;} void set(std::string msg) { this->_msg = msg; } std::string greet() { return _msg; } }; BOOST_PYTHON_MODULE(xyz) { class_<Hello>("Hello", init<std::string>()) .def("greet", &Hello::greet) .def("set", &Hello::set) ; }
А вот Makefile:
FLAGS= -fno-for-scope -O2 -fPIC CPP=c++ # BOOST v 1.50.0 p1=/home/Alexey_2/Soft/boost_1_50_0 pl1=/home/Alexey_2/Soft/boost_1_50_0/stage/lib # PYTHON v 2.6 p2=/home/Alexey_2/Soft/python2.6/include/python2.6 pl2=/home/Alexey_2/Soft/python2.6/bin I=-I${p1} -I${p2} L=-L${pl1} -lboost_python -L${pl2} -lpython2.6 all: xyz.so xyz.o: xyz.cpp ${CPP} ${FLAGS} ${I} -c xyz.cpp xyz.so: xyz.o ${CPP} ${FLAGS} -shared -o xyz.so xyz.o ${L} clean: rm *.o rm xyz.so
Некоторые комментарии:
Библиотечные пути установлены, и я компилирую против prope r библиотек (см. больше: compile some code with boost.python by mingw in win7-64bit).
Приведенная выше ссылка объясняет, почему важно настроить user-config.jam - я сделал это на шаге 1c.
Для того, чтобы избежать возможных проблем (как указано в приведенной выше ссылке, а также в Cannot link boost.python with mingw (хотя для MinGW)) с библиотеками boost.python любил статически я использовать
link=shared
в качестве аргумента bjam (см 1d)
Как объяснено здесь: MinGW + Boost: undefined reference to `[email protected]' библиотеки, с которыми один хочет, чтобы собрать что-то должны быть перечислены после объектных файлов, поэтому мы имеем:
${CPP} ${FLAGS} -shared -o xyz.so xyz.o ${L}
и не
${CPP} ${FLAGS} -shared ${L} -o xyz.so xyz.o
А вот кусок моего .bash_profile (в конце концов), где я определить переменные окружения:
# Python
export PATH=/home/Alexey_2/Soft/python2.6/bin:$PATH
export PYTHONPATH=/home/Alexey_2/Soft/python2.6
export LD_LIBRARY_PATH=/home/Alexey_2/Soft/python2.6/lib:/home/Alexey_2/Soft/python2.6/bin:$LD_LIBRARY_PATH
# Boost
export BOOST_ROOT=/home/Alexey_2/Soft/boost_1_50_0
export LD_LIBRARY_PATH=/home/Alexey_2/Soft/boost_1_50_0/stage/lib:$LD_LIBRARY_PATH
export PATH=/home/Alexey_2/Soft/boost_1_50_0/stage/lib:$PATH
# bjam
export PATH=/home/Alexey_2/Soft/boost_1_50_0/tools/build/v2:$PATH
Наконец, к этой проблеме. С учетом указанных выше установки я смог успешно создать файл питон объекта расширения:
xyz.so
Однако, когда я проверить его простой скрипт:
# this is a test.py script
import xyz
ImportError приходит:
$ python test.py
Traceback (most recent call last):
File "test.py", line 1, in <module>
import xyz
ImportError: No module named xyz
Было отмечено, что причиной такой проблемы может быть неправильный исполняемый файл python, но это не тот случай:
$ which python
/home/Alexey_2/Soft/python2.6/bin/python
, что ожидается (примечание питон является символической ссылкой на python2.6 из этого каталога)
Вот еще одна полезная информация у меня есть:
$ ldd xyz.so
ntdll.dll => /cygdrive/c/Windows/SysWOW64/ntdll.dll (0x76fa0000)
kernel32.dll => /cygdrive/c/Windows/syswow64/kernel32.dll (0x76430000)
KERNELBASE.dll => /cygdrive/c/Windows/syswow64/KERNELBASE.dll (0x748e0000)
cygboost_python.dll => /home/Alexey_2/Soft/boost_1_50_0/stage/lib/cygboost_python.dll (0x70cc0000)
cygwin1.dll => /usr/bin/cygwin1.dll (0x61000000)
cyggcc_s-1.dll => /usr/bin/cyggcc_s-1.dll (0x6ff90000)
cygstdc++-6.dll => /usr/bin/cygstdc++-6.dll (0x6fa90000)
libpython2.6.dll => /home/Alexey_2/Soft/python2.6/bin/libpython2.6.dll (0x67ec0000)
??? => ??? (0x410000)
мне интересно, что
??? => ??? (0x410000)
может означать. Может быть, это то, что мне не хватает. Но что это? Любые комментарии и предложения (а не только о последнем вопросе) очень ценятся.
EDIT:
По предложению (twsansbury), рассматривающего питон пути поиска модулей с -vv вариантом:
python -vv test.py
дает
# trying /home/Alexey_2/Programming/test/xyz.dll
# trying /home/Alexey_2/Programming/test/xyzmodule.dll
# trying /home/Alexey_2/Programming/test/xyz.py
# trying /home/Alexey_2/Programming/test/xyz.pyc
...
# trying /home/Alexey_2/Soft/python2.6/lib/python2.6/site-packages/xyz.dll
# trying /home/Alexey_2/Soft/python2.6/lib/python2.6/site-packages/xyzmodule.dll
# trying /home/Alexey_2/Soft/python2.6/lib/python2.6/site-packages/xyz.py
# trying /home/Alexey_2/Soft/python2.6/lib/python2.6/site-packages/xyz.pyc
Traceback (most recent call last):
File "test.py", line 1, in <module>
import xyz
ImportError: No module named xyz
Первый каталог, откуда я вызовите python для запуска скрипта. Основной вывод заключается в том, что cygwin python ищет модули (библиотеки) со стандартным расширением Windows - dll (среди других 3 типов), а не .so, как я изначально ожидал от стиля эмуляции Linux cygwin. Таким образом, изменяя следующие строки в предыдущем Makefile для:
all: xyz.dll
xyz.o: xyz.cpp
${CPP} ${FLAGS} ${I} -c xyz.cpp
xyz.dll: xyz.o
${CPP} ${FLAGS} -shared -o xyz.dll xyz.o ${L}
clean:
rm *.o
rm xyz.dll
производит xyz.dll, которые успешно могут быть загружены:
python -vv test.py
теперь дает:
Python 2.6.8 (unknown, Mar 21 2013, 17:13:04)
[GCC 4.5.3] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
# trying /home/Alexey_2/Programming/test/xyz.dll
dlopen("/home/Alexey_2/Programming/test/xyz.dll", 2);
import xyz # dynamically loaded from /home/Alexey_2/Programming/test/xyz.dll
+1 Хорошо объясненный вопрос и исследование усилий. –