这两天把VASPy代码兼容了Python3,于是打算在IBM上用python3跑,结果发现IBM上没有python3,于是我就打算编译一下,本以为就几分钟的事,结果发生了奇怪的错误。。。最终找到原因,竟是自己坑了自己。

就第一步编译python.c就直接报错了,我也是崩溃的

   パ..パ
  ( °Д°)・・・
__(_っ / ̄ ̄ ̄ ̄ ̄/_
    \/_____/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
[zjshao@master Python-3.5.2]$ make
gcc -pthread -c -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -Werror=declaration-after-statement -I. -IInclude -I./Include -DPy_BUILD_CORE -o Programs/python.o ./Programs/python.c
In file included from Include/Python.h:65:0,
from ./Programs/python.c:3:
Include/pytime.h:24:4: error: #error "_PyTime_t need signed 64-bit integer type"
# error "_PyTime_t need signed 64-bit integer type"
^~~~~
In file included from Include/Python.h:50:0,
from ./Programs/python.c:3:
Include/pytime.h:70:12: error: unknown type name ‘_PyTime_t’
PyAPI_FUNC(_PyTime_t) _PyTime_FromSeconds(int seconds);
^
Include/pyport.h:768:34: note: in definition of macro ‘PyAPI_FUNC’
# define PyAPI_FUNC(RTYPE) RTYPE
^~~~~
Include/pytime.h:78:12: error: unknown type name ‘_PyTime_t’
PyAPI_FUNC(_PyTime_t) _PyTime_FromNanoseconds(PY_LONG_LONG ns);
^
Include/pyport.h:768:34: note: in definition of macro ‘PyAPI_FUNC’
# define PyAPI_FUNC(RTYPE) RTYPE
^~~~~
In file included from Include/Python.h:65:0,
from ./Programs/python.c:3:
Include/pytime.h:82:43: error: unknown type name ‘_PyTime_t’
PyAPI_FUNC(int) _PyTime_FromSecondsObject(_PyTime_t *t,
^~~~~~~~~
Include/pytime.h:88:48: error: unknown type name ‘_PyTime_t’
PyAPI_FUNC(int) _PyTime_FromMillisecondsObject(_PyTime_t *t,
^~~~~~~~~
Include/pytime.h:93:44: error: unknown type name ‘_PyTime_t’
PyAPI_FUNC(double) _PyTime_AsSecondsDouble(_PyTime_t t);
^~~~~~~~~
In file included from Include/Python.h:50:0,
from ./Programs/python.c:3:
Include/pytime.h:96:12: error: unknown type name ‘_PyTime_t’
PyAPI_FUNC(_PyTime_t) _PyTime_AsMilliseconds(_PyTime_t t,
^
Include/pyport.h:768:34: note: in definition of macro ‘PyAPI_FUNC’
# define PyAPI_FUNC(RTYPE) RTYPE
^~~~~
In file included from Include/Python.h:65:0,
from ./Programs/python.c:3:
Include/pytime.h:96:46: error: unknown type name ‘_PyTime_t’
PyAPI_FUNC(_PyTime_t) _PyTime_AsMilliseconds(_PyTime_t t,
^~~~~~~~~
In file included from Include/Python.h:50:0,
from ./Programs/python.c:3:
Include/pytime.h:100:12: error: unknown type name ‘_PyTime_t’
PyAPI_FUNC(_PyTime_t) _PyTime_AsMicroseconds(_PyTime_t t,
^
Include/pyport.h:768:34: note: in definition of macro ‘PyAPI_FUNC’
# define PyAPI_FUNC(RTYPE) RTYPE
^~~~~
In file included from Include/Python.h:65:0,
from ./Programs/python.c:3:
Include/pytime.h:100:46: error: unknown type name ‘_PyTime_t’
PyAPI_FUNC(_PyTime_t) _PyTime_AsMicroseconds(_PyTime_t t,
^~~~~~~~~
Include/pytime.h:105:52: error: unknown type name ‘_PyTime_t’
PyAPI_FUNC(PyObject *) _PyTime_AsNanosecondsObject(_PyTime_t t);
^~~~~~~~~
Include/pytime.h:111:35: error: unknown type name ‘_PyTime_t’
PyAPI_FUNC(int) _PyTime_AsTimeval(_PyTime_t t,
^~~~~~~~~
Include/pytime.h:116:43: error: unknown type name ‘_PyTime_t’
PyAPI_FUNC(int) _PyTime_AsTimeval_noraise(_PyTime_t t,
^~~~~~~~~
In file included from Include/Python.h:50:0,
from ./Programs/python.c:3:
Include/pytime.h:131:12: error: unknown type name ‘_PyTime_t’
PyAPI_FUNC(_PyTime_t) _PyTime_GetSystemClock(void);
^
Include/pyport.h:768:34: note: in definition of macro ‘PyAPI_FUNC’
# define PyAPI_FUNC(RTYPE) RTYPE
^~~~~
Include/pytime.h:140:12: error: unknown type name ‘_PyTime_t’
PyAPI_FUNC(_PyTime_t) _PyTime_GetMonotonicClock(void);
^
Include/pyport.h:768:34: note: in definition of macro ‘PyAPI_FUNC’
# define PyAPI_FUNC(RTYPE) RTYPE
^~~~~
In file included from Include/Python.h:65:0,
from ./Programs/python.c:3:
Include/pytime.h:156:5: error: unknown type name ‘_PyTime_t’
_PyTime_t *t,
^~~~~~~~~
Include/pytime.h:168:5: error: unknown type name ‘_PyTime_t’
_PyTime_t *t,
^~~~~~~~~
In file included from Include/Python.h:77:0,
from ./Programs/python.c:3:
Include/unicodeobject.h:65:0: warning: "Py_USING_UNICODE" redefined
#define Py_USING_UNICODE

In file included from Include/Python.h:8:0,
from ./Programs/python.c:3:
/usr/local/include/python2.7/pyconfig.h:962:0: note: this is the location of the previous definition
#define Py_USING_UNICODE 1

In file included from Include/Python.h:77:0,
from ./Programs/python.c:3:
Include/unicodeobject.h:71:0: warning: "Py_UNICODE_SIZE" redefined
#define Py_UNICODE_SIZE SIZEOF_WCHAR_T

In file included from Include/Python.h:8:0,
from ./Programs/python.c:3:
/usr/local/include/python2.7/pyconfig.h:959:0: note: this is the location of the previous definition
#define Py_UNICODE_SIZE 2

In file included from Include/Python.h:77:0,
from ./Programs/python.c:3:
Include/unicodeobject.h:92:0: warning: "PY_UNICODE_TYPE" redefined
#define PY_UNICODE_TYPE wchar_t

In file included from Include/Python.h:8:0,
from ./Programs/python.c:3:
/usr/local/include/python2.7/pyconfig.h:950:0: note: this is the location of the previous definition
#define PY_UNICODE_TYPE unsigned short

make: *** [Programs/python.o] Error 1
[zjshao@master Python-3.5.2]$

这个问题在google上没搜到,我当时竟然愚蠢的认为难道最新的Python3.5.2用了什么C的新特性IBM上的gcc不支持。。。

于是我就蛋疼的去下载了最新版本的gcc6.1.0,
经过漫长的编译过程之后用了最新的编译器编译python

还是同样的错误。。(醉了。。。

于是,

我决定看一下到底是哪里的错误,干脆自己解决丰衣足食。

最初的问题就在于_PyTime_t这个宏定义没有完成,于是我就找到了相应宏定义的地方(pytime.h):

1
2
3
4
5
6
7
8
9
10
#ifdef PY_INT64_T
/* _PyTime_t: Python timestamp with subsecond precision. It can be used to
store a duration, and so indirectly a date (related to another date, like
UNIX epoch). */
typedef PY_INT64_T _PyTime_t;
#define _PyTime_MIN PY_LLONG_MIN
#define _PyTime_MAX PY_LLONG_MAX
#else
# error "_PyTime_t need signed 64-bit integer type"
#endif

可见,预处理器报错的原因在于没有定义宏PY_INT64_T

那再去找PY_INT64_T定义的地方(pyport.h):

1
2
3
4
5
6
7
8
9
10
11
12
/* Macros for a 64-bit unsigned integer type; used for type 'twodigits' in the
* integer implementation, when 30-bit digits are enabled.
*/
#ifdef int64_t
#define HAVE_INT64_T 1
#endif

#ifdef HAVE_INT64_T
#ifndef PY_INT64_T
#define PY_INT64_T int64_t
#endif
#endif

也就是说预处理器没有找到int64_t的定义,我就纳闷了,int64_t的定义不是在C的标准库stdint.h里面就定义好了的么,那么也就是说

根本没有将标准库里的stdint.hinclude进来!

再继续找。。。

1
2
3
4
5
6
7
8
9
/* Some versions of HP-UX & Solaris need inttypes.h for int32_t,
INT32_MAX, etc. */
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif

#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif

没包含只有一种可能了就是上面的HAVE_STDINT_H没有定义,再继续。。。

然后我就找到了pyconfig.h

1
2
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1

看来没有设置这个宏,难道我压根就没有包含这个pyconfig.h?

不能够啊,编译参数里面都写得很清楚了-I.。。。

这个时候我想到了一个东西: C_INCLUDE_PATH!

我之前为了编译自己写得C++扩展模块,将这个路径改成了Python2.7的头文件路径了。。。输出一下,果然:

1
2
3
[zjshao@master Python-3.5.0]$ echo $C_INCLUDE_PATH 
/usr/local/include/python2.7/:
[zjshao@master Python-3.5.0]$

那我就试试把当前python源代码的路径添加进去再编译试试。。。

结果。。。

就成了。。

成了。。。了。。。

果然还是太年轻,自己坑了自己。。。

不过这是不是也说明了环境变量C_INCLUDE_PATH的搜索顺序在编译参数-I的前面?
应该是吧。

Comments

2016-07-16