一、环境:
二、下载
wget https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tgz
三、编译过程
1、预安装相关库
pact install make
pact install tcl tcltk tcl-tk tcl-tk-devel tcl-devel
pact install ncurses ncurses-devel libncurses-devel
pact install bzip2 libbz2-devel libreadline-devel readline libreadline7
pact install sqlite3 libsqlite3-devel libsqlite3_0 tcl-sqlite3
pact install gdbm libgdbm-devel
pact install liblzma-devel xz liblzma5 lzma
pact install crypt libcrypt-devel libcrypt0
pact install openssl openssl-devel
2、解压
tar zxvf Python-3.5.2.tgz
cd Python-3.5.2
3、修改问题文件
sed -i '/PyLong_FromLong(si->si_band)/i\#ifdef __CYGWIN__\n PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(0L));\n#else' ./Modules/signalmodule.c
sed -i '/PyLong_FromLong(si->si_band)/a\#endif' ./Modules/signalmodule.c
sed -i 's/libpython$(VERSION).dll.a/libpython$(LDVERSION).dll.a/' Makefile.pre.in
sed -i 's/-lpython\\$(VERSION)/-lpython\\$(LDVERSION)/' Modules/makesetup
sed -i 's/PyVarObject_HEAD_INIT(&PyType_Type/PyVarObject_HEAD_INIT(NULL/' Modules/_struct.c
sed -i '/PyType_GenericAlloc(&unpackiter_type/i\ Py_TYPE(&unpackiter_type) = &PyType_Type;' Modules/_struct.c
sed -i '717,723s/^/#/' Lib/distutils/command/build_ext.py
sed -i 's/\".tbd\"/\".dll.a\"/' ./Lib/distutils/unixccompiler.py
sed -i '/include "Python.h"/a\#ifdef HAVE_CURSES_IS_PAD\n#define py_is_pad(win) is_pad(win)\n#else\n#if defined(WINDOW_HAS_FLAGS) \&\& !NCURSES_OPAQUE\n#define py_is_pad(win) ((win) ? ((win)->_flags \& _ISPAD) != 0 : FALSE)\n#else \n#define py_is_pad(win) FALSE\n#endif\n#endif' Modules/_cursesmodule.c
sed -i 's/self->win->_flags \& _ISPAD/py_is_pad(self->win)/' Modules/_cursesmodule.c
sed -i '/NCURSES_OPAQUE 0/a\#else\n#define NCURSES_OPAQUE 1' Include/py_curses.h
4、编译:
./configure
make > make1112_2055.log 2>make1112_2055.err
make install
四、安装后:
如果系统中有多套python版本,请正确设置环境变量:PATH,PYTHONHOME,PYTHONPATH
然后重新启动cygwin或babun终端,一定要重新启动。
五、遇到的问题汇总:
1.错误:./Modules/signalmodule.c:965:60: error: ‘siginfo_t {aka struct }’ has no member named ‘si_band’
解决:
sed -i '/PyLong_FromLong(si->si_band)/i\#ifdef __CYGWIN__\n PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(0L));\n#else' ./Modules/signalmodule.c
sed -i '/PyLong_FromLong(si->si_band)/a\#endif' ./Modules/signalmodule.c
修改后文件如下:
#ifdef __CYGWIN__
PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(0L));
#else
PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(si->si_band));
#endif
2.错误:make: * No rule to make target ‘libpython3.5m.dll.a’, needed by ‘python.exe’.
解决:
sed -i 's/libpython$(VERSION).dll.a/libpython$(LDVERSION).dll.a/' Makefile.pre.in
3.错误:ld: cannot find -lpython3.5 collect2: error: ld returned 1 exit status
解决:
sed -i 's/-lpython\\$(VERSION)/-lpython\\$(LDVERSION)/' Modules/makesetup
4.错误:/Modules/_struct.c:1629:27: error: initializer element is not constant PyVarObject_HEAD_INIT(&PyType_Type, 0)
解决:
sed -i 's/PyVarObject_HEAD_INIT(&PyType_Type/PyVarObject_HEAD_INIT(NULL/' Modules/_struct.c
sed -i '/PyType_GenericAlloc(&unpackiter_type/i\ Py_TYPE(&unpackiter_type) = &PyType_Type;' Modules/_struct.c
5.错误:running build_ext ld: cannot find -lpython3.5 collect2: error: ld returned 1 exit status
解决:
sed -i '717,723s/^/#/' Lib/distutils/command/build_ext.py
6.错误:INFO: Can’t locate Tcl/Tk libs and/or headers
pact install tcl tcltk tcl-tk tcl-tk-devel tcl-devel
7.错误:
Python build finished successfully!
The necessary bits to build these optional modules were not found:
_bz2 _curses _curses_panel
_gdbm _lzma _sqlite3
_ssl _tkinter nis
ossaudiodev readline spwd
To find the necessary bits, look in setup.py in detect_modules() for the module’s name.
pact install ncurses ncurses-devel libncurses-devel
pact install bzip2 libbz2-devel libreadline-devel readline libreadline7
pact install sqlite3 libsqlite3-devel libsqlite3_0 tcl-sqlite3
pact install gdbm libgdbm-devel
pact install liblzma-devel xz liblzma5 lzma
但是,MinGW/Cygwin确提供了直接与.dll文件链接的作用,就是可以不需要imp-lib库文件,只要DLL文件存在,也可以链接成功。这样就导致.dll.a文件似乎不是那么有用了。在很多场合下,可以不需要.dll.a文件了。但是有几个例外情况,来自于RedHat的官方描述。
ld and WIN32 (cygwin/mingw)
sed -i 's/\".tbd\"/\".dll.a\"/' ./Lib/distutils/unixccompiler.py
8.错误:
_cryptmodule.c:39: undefined reference to `crypt’ collect2: error: ld returned 1 exit status
Failed to build these modules:_crypt
解决:
pact install crypt libcrypt-devel libcrypt0
pact install openssl openssl-devel
9.错误:
Modules/_cursesmodule.c:1073:18: error: dereferencing pointer to incomplete type ‘WINDOW {aka struct _win_st}’
if (self->win->_flags & _ISPAD)
sed -i '/include "Python.h"/a\#ifdef HAVE_CURSES_IS_PAD\n#define py_is_pad(win) is_pad(win)\n#else\n#if defined(WINDOW_HAS_FLAGS) \&\& !NCURSES_OPAQUE\n#define py_is_pad(win) ((win) ? ((win)->_flags \& _ISPAD) != 0 : FALSE)\n#else \n#define py_is_pad(win) FALSE\n#endif\n#endif' Modules/_cursesmodule.c
sed -i 's/self->win->_flags \& _ISPAD/py_is_pad(self->win)/' Modules/_cursesmodule.c
sed -i '/NCURSES_OPAQUE 0/a\#else\n#define NCURSES_OPAQUE 1' Include/py_curses.h
10.错误不再解决
The necessary bits to build these optional modules were not found:
_tkinter nis ossaudiodev
spwd
To find the necessary bits, look in setup.py in detect_modules() for the module’s name.
11.make test执行通不过可以不用处理,报如下错误:
PermissionError: [Errno 13] Permission denied
make: * [Makefile:1014: test] Error 1
12.正确设置环境变量:PATH,PYTHONHOME,PYTHONPATH
尤其是安装有window版本的python时,否则会冒出各种各样的问题,例如:
(1)Fatal Python error: Py_Initialize: Unable to get the locale encoding
ImportError: No module named ‘encodings’
(2)ImportError: No module named ‘_sysconfigdata’
解决:
export PATH=` echo $PATH|sed 's/\/cygdrive\/d\/app\/Python34\/Lib\/site-packages\/PyQt5://'|sed 's/\/cygdrive\/d\/app\/Python34\/Scripts://'|sed 's/\/cygdrive\/d\/app\/Python34://'`
export PYTHONHOME=/usr/lib/python2.7
export PYTHONPATH=/usr/lib/python2.7/lib:/usr/lib/python2.7
六、遇到的告警问题汇总:
1.信息:关于pthread_key_t类型转换问题,在cygwin64中会变成错误
下面的修改不正确,仅作为修改记录.不需要按下面的处理
Python/thread_pthread.h:613:13: warning: comparison between pointer and integer
if (key > INT_MAX) {
处理:
sed -i 's/PyThread_create_key(void)/PyThread_create_key(pthread_key_t *key)/' Python/thread_pthread.h
sed -i '/pthread_key_t key;/s/^/\/\//' Python/thread_pthread.h
sed -i 's/pthread_key_create(\&key/pthread_key_create(key/' Python/thread_pthread.h
sed -i '/ if (key > INT_MAX)/i\#if defined(__INSIDE_CYGWIN__) \&\& defined(__cplusplus)' Python/thread_pthread.h
sed -i 's/if (key > INT_MAX)/if (*key > INT_MAX)/' Python/thread_pthread.h
sed -i 's/pthread_key_delete(key);\n errno = ENOMEM;/pthread_key_delete(*key);\n errno = ENOMEM;/' Python/thread_pthread.h
sed -i '/return (int)key;/i\#endif' Python/thread_pthread.h
sed -i 's/return (int)key;/return 0;/' Python/thread_pthread.h
sed -i 's/PyThread_delete_key(int key)/PyThread_delete_key(pthread_key_t key)/' Python/thread_pthread.h
sed -i 's/PyThread_delete_key_value(int key)/PyThread_delete_key_value(pthread_key_t key)/' Python/thread_pthread.h
sed -i 's/PyThread_set_key_value(int key/PyThread_set_key_value(pthread_key_t key/' Python/thread_pthread.h
sed -i 's/PyThread_get_key_value(int key)/PyThread_get_key_value(pthread_key_t key)/' Python/thread_pthread.h
sed -i 's/PyThread_create_key(void);/PyThread_create_key(pthread_key_t *key);/' Include/pythread.h
sed -i 's/PyThread_delete_key(int);/PyThread_delete_key(pthread_key_t key);/' Include/pythread.h
sed -i 's/PyThread_set_key_value(int/PyThread_set_key_value(pthread_key_t/' Include/pythread.h
sed -i 's/PyThread_get_key_value(int)/PyThread_get_key_value(pthread_key_t)/' Include/pythread.h
sed -i 's/PyThread_delete_key_value(int key);/PyThread_delete_key_value(pthread_key_t key);/' Include/pythread.h
sed -i 's/static int autoTLSkey = 0;/static pthread_key_t autoTLSkey = 0;/' Python/pystate.c
sed -i '/autoTLSkey = PyThread_create_key/s/^/\/\//' Python/pystate.c
sed -i 's/autoTLSkey == -1/PyThread_create_key(\&autoTLSkey) == -1/' Python/pystate.c
sed -i 's/static int tracemalloc_reentrant_key;/static pthread_key_t tracemalloc_reentrant_key;/' ./Modules/_tracemalloc.c
sed -i '/tracemalloc_reentrant_key = PyThread_create_key/s/^/\/\//' ./Modules/_tracemalloc.c
sed -i 's/tracemalloc_reentrant_key == -1/PyThread_create_key(\&tracemalloc_reentrant_key) == -1/' ./Modules/_tracemalloc.c
终于搞定了,带着疲惫,带着欢欣^_^