Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fe2834b

Browse files
committed
Applied Ludwigs build tkagg w/o x11 server patch
svn path=/trunk/matplotlib/; revision=4507
1 parent 6c9fe1e commit fe2834b

3 files changed

Lines changed: 115 additions & 82 deletions

File tree

CODING_GUIDE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ python, C and C++
117117

118118

119119

120-
for older versions of emacs (emacs<22) you may need to do
120+
for older versions of emacs (emacs<22) you need to do
121121

122122
(add-hook 'python-mode-hook
123123
(lambda ()

examples/loadrec.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from pylab import figure, show
33

44
a = mlab.csv2rec('data/msft.csv')
5+
a.sort()
56
print a.dtype
67

78
fig = figure()

setupext.py

Lines changed: 113 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@
9292
BUILT_CONTOUR = False
9393
BUILT_GDK = False
9494

95+
TCL_TK_CACHE = None
96+
9597
AGG_VERSION = 'agg23'
9698

9799
# for nonstandard installation/build with --prefix variable
@@ -797,51 +799,6 @@ def add_wx_flags(module, wxconfig):
797799
# or else you'll build for a wrong version of the Tcl
798800
# interpreter (leading to nasty segfaults).
799801

800-
class FoundTclTk:
801-
pass
802-
803-
def find_tcltk():
804-
"""Finds Tcl/Tk includes/libraries/version by interrogating Tkinter."""
805-
# By this point, we already know that Tkinter imports correctly
806-
import Tkinter
807-
o = FoundTclTk()
808-
try:
809-
tk=Tkinter.Tk()
810-
except Tkinter.TclError:
811-
o.tcl_lib = "/usr/local/lib"
812-
o.tcl_inc = "/usr/local/include"
813-
o.tk_lib = "/usr/local/lib"
814-
o.tk_inc = "/usr/local/include"
815-
o.tkv = ""
816-
else:
817-
tk.withdraw()
818-
o.tcl_lib = os.path.normpath(os.path.join(str(tk.getvar('tcl_library')), '../'))
819-
o.tk_lib = os.path.normpath(os.path.join(str(tk.getvar('tk_library')), '../'))
820-
o.tkv = str(Tkinter.TkVersion)[:3]
821-
o.tcl_inc = os.path.normpath(os.path.join(str(tk.getvar('tcl_library')),
822-
'../../include/tcl'+o.tkv))
823-
if not os.path.exists(o.tcl_inc):
824-
o.tcl_inc = os.path.normpath(os.path.join(str(tk.getvar('tcl_library')),
825-
'../../include'))
826-
o.tk_inc = os.path.normpath(os.path.join(str(tk.getvar('tk_library')),
827-
'../../include/tk'+o.tkv))
828-
if not os.path.exists(o.tk_inc):
829-
o.tk_inc = os.path.normpath(os.path.join(str(tk.getvar('tk_library')),
830-
'../../include'))
831-
832-
if ((not os.path.exists(os.path.join(o.tk_inc,'tk.h'))) and
833-
os.path.exists(os.path.join(o.tcl_inc,'tk.h'))):
834-
o.tk_inc = o.tcl_inc
835-
836-
if not os.path.exists(o.tcl_inc):
837-
# this is a hack for suse linux, which is broken
838-
if (sys.platform.startswith('linux') and
839-
os.path.exists('/usr/include/tcl.h') and
840-
os.path.exists('/usr/include/tk.h')):
841-
o.tcl_inc = '/usr/include/'
842-
o.tk_inc = '/usr/include/'
843-
return o
844-
845802
def check_for_tk():
846803
gotit = False
847804
explanation = None
@@ -853,29 +810,27 @@ def check_for_tk():
853810
explanation = 'Tkinter present but import failed'
854811
else:
855812
if Tkinter.TkVersion < 8.3:
856-
explanation = "Tcl/Tk v8.3 or later required\n"
857-
sys.exit(1)
813+
explanation = "Tcl/Tk v8.3 or later required"
858814
else:
859-
try:
860-
tk = Tkinter.Tk()
861-
tk.withdraw()
862-
except Tkinter.TclError:
863-
explanation = """\
864-
Using default library and include directories for Tcl and Tk because a
865-
Tk window failed to open. You may need to define DISPLAY for Tk to work
866-
so that setup can determine where your libraries are located."""
867815
gotit = True
868-
816+
869817
if gotit:
870818
module = Extension('test', [])
871819
try:
872-
add_tk_flags(module)
820+
explanation = add_tk_flags(module)
873821
except RuntimeError, e:
874822
explanation = str(e)
875823
gotit = False
876-
if not find_include_file(module.include_dirs, "tk.h"):
877-
explanation = 'Tkinter present, but header files are not installed. You may need to install development packages.'
878-
824+
else:
825+
if not find_include_file(module.include_dirs, "tk.h"):
826+
message = 'Tkinter present, but header files are not found. ' + \
827+
'You may need to install development packages.'
828+
if explanation is not None:
829+
explanation += '\n' + message
830+
else:
831+
explanation = message
832+
gotit = False
833+
879834
if gotit:
880835
print_status("Tkinter", "Tkinter: %s, Tk: %s, Tcl: %s" %
881836
(Tkinter.__version__.split()[-2], Tkinter.TkVersion, Tkinter.TclVersion))
@@ -885,34 +840,74 @@ def check_for_tk():
885840
print_message(explanation)
886841
return gotit
887842

843+
def query_tcltk():
844+
"""Tries to open a Tk window in order to query the Tk object about its library paths.
845+
This should never be called more than once by the same process, as Tk intricacies
846+
may cause the Python interpreter to hang. The function also has a workaround if
847+
no X server is running (useful for autobuild systems)."""
848+
global TCL_TK_CACHE
849+
# Use cached values if they exist, which ensures this function only executes once
850+
if TCL_TK_CACHE is not None:
851+
return TCL_TK_CACHE
852+
853+
# By this point, we already know that Tkinter imports correctly
854+
import Tkinter
855+
tcl_lib_dir = ''
856+
tk_lib_dir = ''
857+
# First try to open a Tk window (requires a running X server)
858+
try:
859+
tk = Tkinter.Tk()
860+
except Tkinter.TclError:
861+
# Next, start Tcl interpreter without opening a Tk window (no need for X server)
862+
# This feature is available in python version 2.4 and up
863+
try:
864+
tcl = Tkinter.Tcl()
865+
except AttributeError: # Python version not high enough
866+
pass
867+
except Tkinter.TclError: # Something went wrong while opening Tcl
868+
pass
869+
else:
870+
tcl_lib_dir = str(tcl.getvar('tcl_library'))
871+
# Guess Tk location based on Tcl location
872+
tk_lib_dir = tcl_lib_dir.replace('Tcl', 'Tk').replace('tcl', 'tk')
873+
else:
874+
# Obtain Tcl and Tk locations from Tk widget
875+
tk.withdraw()
876+
tcl_lib_dir = str(tk.getvar('tcl_library'))
877+
tk_lib_dir = str(tk.getvar('tk_library'))
878+
879+
# Save directories and version string to cache
880+
TCL_TK_CACHE = tcl_lib_dir, tk_lib_dir, str(Tkinter.TkVersion)[:3]
881+
return TCL_TK_CACHE
882+
888883
def add_tk_flags(module):
889884
'Add the module flags to build extensions which use tk'
890-
if sys.platform=='win32':
885+
message = None
886+
if sys.platform == 'win32':
891887
major, minor1, minor2, s, tmp = sys.version_info
892-
if major==2 and minor1 in [3, 4, 5]:
888+
if major == 2 and minor1 in [3, 4, 5]:
893889
module.include_dirs.extend(['win32_static/include/tcl8.4'])
894890
module.libraries.extend(['tk84', 'tcl84'])
895-
elif major==2 and minor1==2:
891+
elif major == 2 and minor1 == 2:
896892
module.include_dirs.extend(['win32_static/include/tcl8.3'])
897893
module.libraries.extend(['tk83', 'tcl83'])
898894
else:
899895
raise RuntimeError('No tk/win32 support for this python version yet')
900896
module.library_dirs.extend([os.path.join(sys.prefix, 'dlls')])
901-
return
902-
903-
elif sys.platform == 'darwin' :
897+
898+
elif sys.platform == 'darwin':
904899
# this config section lifted directly from Imaging - thanks to
905900
# the effbot!
906-
901+
907902
# First test for a MacOSX/darwin framework install
908903
from os.path import join, exists
909904
framework_dirs = [
910905
'/System/Library/Frameworks/',
911906
'/Library/Frameworks',
912907
join(os.getenv('HOME'), '/Library/Frameworks')
913908
]
914-
915-
# Find the directory that contains the Tcl.framwork and Tk.framework
909+
910+
# Find the directory that contains the Tcl.framework and Tk.framework
916911
# bundles.
917912
# XXX distutils should support -F!
918913
tk_framework_found = 0
@@ -936,7 +931,7 @@ def add_tk_flags(module):
936931
for fw in 'Tcl', 'Tk'
937932
for H in 'Headers', 'Versions/Current/PrivateHeaders'
938933
]
939-
934+
940935
# For 8.4a2, the X11 headers are not included. Rather than include a
941936
# complicated search, this is a hard-coded path. It could bail out
942937
# if X11 libs are not found...
@@ -945,14 +940,54 @@ def add_tk_flags(module):
945940
module.include_dirs.extend(tk_include_dirs)
946941
module.extra_link_args.extend(frameworks)
947942
module.extra_compile_args.extend(frameworks)
948-
return
949-
950-
# you're still here? ok we'll try it this way
951-
o = find_tcltk() # todo: try/except
952-
module.include_dirs.extend([o.tcl_inc, o.tk_inc])
953-
module.library_dirs.extend([o.tcl_lib, o.tk_lib])
954-
module.libraries.extend(['tk'+o.tkv, 'tcl'+o.tkv])
955-
943+
944+
# you're still here? ok we'll try it this way...
945+
else:
946+
# Query Tcl/Tk system for library paths and version string
947+
tcl_lib_dir, tk_lib_dir, tk_ver = query_tcltk() # todo: try/except
948+
949+
# Process base directories to obtain include + lib dirs
950+
if tcl_lib_dir != '' and tk_lib_dir != '':
951+
tcl_lib = os.path.normpath(os.path.join(tcl_lib_dir, '../'))
952+
tk_lib = os.path.normpath(os.path.join(tk_lib_dir, '../'))
953+
tcl_inc = os.path.normpath(os.path.join(tcl_lib_dir,
954+
'../../include/tcl' + tk_ver))
955+
if not os.path.exists(tcl_inc):
956+
tcl_inc = os.path.normpath(os.path.join(tcl_lib_dir,
957+
'../../include'))
958+
tk_inc = os.path.normpath(os.path.join(tk_lib_dir,
959+
'../../include/tk' + tk_ver))
960+
if not os.path.exists(tk_inc):
961+
tk_inc = os.path.normpath(os.path.join(tk_lib_dir,
962+
'../../include'))
963+
964+
if ((not os.path.exists(os.path.join(tk_inc,'tk.h'))) and
965+
os.path.exists(os.path.join(tcl_inc,'tk.h'))):
966+
tk_inc = tcl_inc
967+
968+
if not os.path.exists(tcl_inc):
969+
# this is a hack for suse linux, which is broken
970+
if (sys.platform.startswith('linux') and
971+
os.path.exists('/usr/include/tcl.h') and
972+
os.path.exists('/usr/include/tk.h')):
973+
tcl_inc = '/usr/include'
974+
tk_inc = '/usr/include'
975+
else:
976+
message = """\
977+
Using default library and include directories for Tcl and Tk because a
978+
Tk window failed to open. You may need to define DISPLAY for Tk to work
979+
so that setup can determine where your libraries are located."""
980+
tcl_inc = "/usr/local/include"
981+
tk_inc = "/usr/local/include"
982+
tcl_lib = "/usr/local/lib"
983+
tk_lib = "/usr/local/lib"
984+
tk_ver = ""
985+
# Add final versions of directories and libraries to module lists
986+
module.include_dirs.extend([tcl_inc, tk_inc])
987+
module.library_dirs.extend([tcl_lib, tk_lib])
988+
module.libraries.extend(['tk' + tk_ver, 'tcl' + tk_ver])
989+
990+
return message
956991

957992
def add_windowing_flags(module):
958993
'Add the module flags to build extensions using windowing api'
@@ -1031,9 +1066,6 @@ def build_tkagg(ext_modules, packages):
10311066
deps,
10321067
)
10331068

1034-
# add agg flags before pygtk because agg only supports freetype1
1035-
# and pygtk includes freetype2. This is a bit fragile.
1036-
10371069
add_tk_flags(module) # do this first
10381070
add_agg_flags(module)
10391071
add_ft2font_flags(module)

0 commit comments

Comments
 (0)