tklib_build.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. # C bindings with libtcl and libtk.
  2. from cffi import FFI
  3. import sys, os
  4. # XXX find a better way to detect paths
  5. # XXX pick up CPPFLAGS and LDFLAGS and add to these paths?
  6. if sys.platform.startswith("openbsd"):
  7. incdirs = ['/usr/local/include/tcl8.5', '/usr/local/include/tk8.5', '/usr/X11R6/include']
  8. linklibs = ['tk85', 'tcl85']
  9. libdirs = ['/usr/local/lib', '/usr/X11R6/lib']
  10. elif sys.platform.startswith("freebsd"):
  11. incdirs = ['/usr/local/include/tcl8.6', '/usr/local/include/tk8.6', '/usr/local/include/X11', '/usr/local/include']
  12. linklibs = ['tk86', 'tcl86']
  13. libdirs = ['/usr/local/lib']
  14. elif sys.platform == 'win32':
  15. incdirs = []
  16. linklibs = ['tcl85', 'tk85']
  17. libdirs = []
  18. elif sys.platform == 'darwin':
  19. incdirs = ['/System/Library/Frameworks/Tk.framework/Versions/Current/Headers/']
  20. linklibs = ['tcl', 'tk']
  21. libdirs = []
  22. else:
  23. # On some Linux distributions, the tcl and tk libraries are
  24. # stored in /usr/include, so we must check this case also
  25. libdirs = []
  26. found = False
  27. for _ver in ['', '8.6', '8.5']:
  28. incdirs = ['/usr/include/tcl' + _ver]
  29. linklibs = ['tcl' + _ver, 'tk' + _ver]
  30. if os.path.isdir(incdirs[0]):
  31. found = True
  32. break
  33. if not found:
  34. for _ver in ['8.6', '8.5', '']:
  35. incdirs = []
  36. linklibs = ['tcl' + _ver, 'tk' + _ver]
  37. if os.path.isfile(''.join(['/usr/lib/lib', linklibs[1], '.so'])):
  38. found = True
  39. break
  40. if not found:
  41. sys.stderr.write("*** TCL libraries not found! Falling back...\n")
  42. incdirs = []
  43. linklibs = ['tcl', 'tk']
  44. config_ffi = FFI()
  45. config_ffi.cdef("""
  46. #define TK_HEX_VERSION ...
  47. #define HAVE_WIDE_INT_TYPE ...
  48. """)
  49. config_lib = config_ffi.verify("""
  50. #include <tk.h>
  51. #define TK_HEX_VERSION ((TK_MAJOR_VERSION << 24) | \
  52. (TK_MINOR_VERSION << 16) | \
  53. (TK_RELEASE_LEVEL << 8) | \
  54. (TK_RELEASE_SERIAL << 0))
  55. #ifdef TCL_WIDE_INT_TYPE
  56. #define HAVE_WIDE_INT_TYPE 1
  57. #else
  58. #define HAVE_WIDE_INT_TYPE 0
  59. #endif
  60. """,
  61. include_dirs=incdirs,
  62. libraries=linklibs,
  63. library_dirs = libdirs
  64. )
  65. TK_HEX_VERSION = config_lib.TK_HEX_VERSION
  66. HAVE_LIBTOMMATH = int((0x08050208 <= TK_HEX_VERSION < 0x08060000) or
  67. (0x08060200 <= TK_HEX_VERSION))
  68. HAVE_WIDE_INT_TYPE = config_lib.HAVE_WIDE_INT_TYPE
  69. tkffi = FFI()
  70. tkffi.cdef("""
  71. char *get_tk_version();
  72. char *get_tcl_version();
  73. #define HAVE_LIBTOMMATH ...
  74. #define HAVE_WIDE_INT_TYPE ...
  75. #define TCL_READABLE ...
  76. #define TCL_WRITABLE ...
  77. #define TCL_EXCEPTION ...
  78. #define TCL_ERROR ...
  79. #define TCL_OK ...
  80. #define TCL_LEAVE_ERR_MSG ...
  81. #define TCL_GLOBAL_ONLY ...
  82. #define TCL_EVAL_DIRECT ...
  83. #define TCL_EVAL_GLOBAL ...
  84. #define TCL_DONT_WAIT ...
  85. typedef unsigned short Tcl_UniChar;
  86. typedef ... Tcl_Interp;
  87. typedef ...* Tcl_ThreadId;
  88. typedef ...* Tcl_Command;
  89. typedef struct Tcl_ObjType {
  90. const char *name;
  91. ...;
  92. } Tcl_ObjType;
  93. typedef struct Tcl_Obj {
  94. char *bytes;
  95. int length;
  96. const Tcl_ObjType *typePtr;
  97. union { /* The internal representation: */
  98. long longValue; /* - an long integer value. */
  99. double doubleValue; /* - a double-precision floating value. */
  100. struct { /* - internal rep as two pointers. */
  101. void *ptr1;
  102. void *ptr2;
  103. } twoPtrValue;
  104. } internalRep;
  105. ...;
  106. } Tcl_Obj;
  107. Tcl_Interp *Tcl_CreateInterp();
  108. void Tcl_DeleteInterp(Tcl_Interp* interp);
  109. int Tcl_Init(Tcl_Interp* interp);
  110. int Tk_Init(Tcl_Interp* interp);
  111. void Tcl_Free(void* ptr);
  112. const char *Tcl_SetVar(Tcl_Interp* interp, const char* varName, const char* newValue, int flags);
  113. const char *Tcl_SetVar2(Tcl_Interp* interp, const char* name1, const char* name2, const char* newValue, int flags);
  114. const char *Tcl_GetVar(Tcl_Interp* interp, const char* varName, int flags);
  115. Tcl_Obj *Tcl_SetVar2Ex(Tcl_Interp* interp, const char* name1, const char* name2, Tcl_Obj* newValuePtr, int flags);
  116. Tcl_Obj *Tcl_GetVar2Ex(Tcl_Interp* interp, const char* name1, const char* name2, int flags);
  117. int Tcl_UnsetVar2(Tcl_Interp* interp, const char* name1, const char* name2, int flags);
  118. const Tcl_ObjType *Tcl_GetObjType(const char* typeName);
  119. Tcl_Obj *Tcl_NewStringObj(const char* bytes, int length);
  120. Tcl_Obj *Tcl_NewUnicodeObj(const Tcl_UniChar* unicode, int numChars);
  121. Tcl_Obj *Tcl_NewLongObj(long longValue);
  122. Tcl_Obj *Tcl_NewBooleanObj(int boolValue);
  123. Tcl_Obj *Tcl_NewDoubleObj(double doubleValue);
  124. void Tcl_IncrRefCount(Tcl_Obj* objPtr);
  125. void Tcl_DecrRefCount(Tcl_Obj* objPtr);
  126. int Tcl_GetBoolean(Tcl_Interp* interp, const char* src, int* boolPtr);
  127. int Tcl_GetInt(Tcl_Interp* interp, const char* src, int* intPtr);
  128. int Tcl_GetDouble(Tcl_Interp* interp, const char* src, double* doublePtr);
  129. int Tcl_GetBooleanFromObj(Tcl_Interp* interp, Tcl_Obj* objPtr, int* valuePtr);
  130. char *Tcl_GetString(Tcl_Obj* objPtr);
  131. char *Tcl_GetStringFromObj(Tcl_Obj* objPtr, int* lengthPtr);
  132. unsigned char *Tcl_GetByteArrayFromObj(Tcl_Obj* objPtr, int* lengthPtr);
  133. Tcl_Obj *Tcl_NewByteArrayObj(unsigned char *bytes, int length);
  134. int Tcl_ExprBoolean(Tcl_Interp* interp, const char *expr, int *booleanPtr);
  135. int Tcl_ExprLong(Tcl_Interp* interp, const char *expr, long* longPtr);
  136. int Tcl_ExprDouble(Tcl_Interp* interp, const char *expr, double* doublePtr);
  137. int Tcl_ExprString(Tcl_Interp* interp, const char *expr);
  138. Tcl_UniChar *Tcl_GetUnicode(Tcl_Obj* objPtr);
  139. int Tcl_GetCharLength(Tcl_Obj* objPtr);
  140. Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj* const objv[]);
  141. int Tcl_ListObjGetElements(Tcl_Interp *interp, Tcl_Obj *listPtr, int *objcPtr, Tcl_Obj ***objvPtr);
  142. int Tcl_ListObjLength(Tcl_Interp* interp, Tcl_Obj* listPtr, int* intPtr);
  143. int Tcl_ListObjIndex(Tcl_Interp* interp, Tcl_Obj* listPtr, int index, Tcl_Obj** objPtrPtr);
  144. int Tcl_SplitList(Tcl_Interp* interp, char* list, int* argcPtr, const char*** argvPtr);
  145. char* Tcl_Merge(int argc, char** argv);
  146. int Tcl_Eval(Tcl_Interp* interp, const char* script);
  147. int Tcl_EvalFile(Tcl_Interp* interp, const char* filename);
  148. int Tcl_EvalObjv(Tcl_Interp* interp, int objc, Tcl_Obj** objv, int flags);
  149. Tcl_Obj *Tcl_GetObjResult(Tcl_Interp* interp);
  150. const char *Tcl_GetStringResult(Tcl_Interp* interp);
  151. void Tcl_SetObjResult(Tcl_Interp* interp, Tcl_Obj* objPtr);
  152. typedef void* ClientData;
  153. typedef int Tcl_CmdProc(
  154. ClientData clientData,
  155. Tcl_Interp *interp,
  156. int argc,
  157. const char *argv[]);
  158. typedef void Tcl_CmdDeleteProc(
  159. ClientData clientData);
  160. Tcl_Command Tcl_CreateCommand(Tcl_Interp* interp, const char* cmdName, Tcl_CmdProc proc, ClientData clientData, Tcl_CmdDeleteProc deleteProc);
  161. int Tcl_DeleteCommand(Tcl_Interp* interp, const char* cmdName);
  162. Tcl_ThreadId Tcl_GetCurrentThread();
  163. int Tcl_DoOneEvent(int flags);
  164. int Tk_GetNumMainWindows();
  165. void Tcl_FindExecutable(char *argv0);
  166. """)
  167. if HAVE_WIDE_INT_TYPE:
  168. tkffi.cdef("""
  169. typedef int... Tcl_WideInt;
  170. int Tcl_GetWideIntFromObj(Tcl_Interp *interp, Tcl_Obj *obj, Tcl_WideInt *value);
  171. Tcl_Obj *Tcl_NewWideIntObj(Tcl_WideInt value);
  172. """)
  173. if HAVE_LIBTOMMATH:
  174. tkffi.cdef("""
  175. #define MP_OKAY ...
  176. #define MP_ZPOS ...
  177. #define MP_NEG ...
  178. typedef struct {
  179. int sign;
  180. ...;
  181. } mp_int;
  182. int Tcl_GetBignumFromObj(Tcl_Interp *interp, Tcl_Obj *obj, mp_int *value);
  183. Tcl_Obj *Tcl_NewBignumObj(mp_int *value);
  184. int mp_unsigned_bin_size(mp_int *a);
  185. int mp_to_unsigned_bin_n(mp_int * a, unsigned char *b, unsigned long *outlen);
  186. int mp_read_radix(mp_int *a, const char *str, int radix);
  187. int mp_init(mp_int *a);
  188. void mp_clear(mp_int *a);
  189. """)
  190. tkffi.set_source("_tkinter.tklib_cffi", """
  191. #define HAVE_LIBTOMMATH %(HAVE_LIBTOMMATH)s
  192. #define HAVE_WIDE_INT_TYPE %(HAVE_WIDE_INT_TYPE)s
  193. #include <tcl.h>
  194. #include <tk.h>
  195. #if HAVE_LIBTOMMATH
  196. #include <tclTomMath.h>
  197. #endif
  198. char *get_tk_version(void) { return TK_VERSION; }
  199. char *get_tcl_version(void) { return TCL_VERSION; }
  200. """ % globals(),
  201. include_dirs=incdirs,
  202. libraries=linklibs,
  203. library_dirs = libdirs
  204. )
  205. if __name__ == "__main__":
  206. tkffi.compile(os.path.join(os.path.dirname(sys.argv[0]), '..'))