|
69 | 69 | from distutils.core import Extension |
70 | 70 | import glob |
71 | 71 | import ConfigParser |
| 72 | +import cStringIO |
72 | 73 |
|
73 | 74 | major, minor1, minor2, s, tmp = sys.version_info |
74 | 75 | if major<2 or (major==2 and minor1<3): |
@@ -888,6 +889,105 @@ def query_tcltk(): |
888 | 889 | TCL_TK_CACHE = tcl_lib_dir, tk_lib_dir, str(Tkinter.TkVersion)[:3] |
889 | 890 | return TCL_TK_CACHE |
890 | 891 |
|
| 892 | +def parse_tcl_config(tcl_lib_dir, tk_lib_dir): |
| 893 | + # This is where they live on Ubuntu Hardy (at least) |
| 894 | + tcl_config = os.path.join(tcl_lib_dir, "tclConfig.sh") |
| 895 | + tk_config = os.path.join(tk_lib_dir, "tkConfig.sh") |
| 896 | + if not (os.path.exists(tcl_config) and os.path.exists(tk_config)): |
| 897 | + # This is where they live on RHEL4 (at least) |
| 898 | + tcl_config = "/usr/lib/tclConfig.sh" |
| 899 | + tk_config = "/usr/lib/tkConfig.sh" |
| 900 | + if not (os.path.exists(tcl_config) and os.path.exists(tk_config)): |
| 901 | + return None |
| 902 | + |
| 903 | + # These files are shell scripts that set a bunch of |
| 904 | + # environment variables. To actually get at the |
| 905 | + # values, we use ConfigParser, which supports almost |
| 906 | + # the same format, but requires at least one section. |
| 907 | + # So, we push a "[default]" section to a copy of the |
| 908 | + # file in a StringIO object. |
| 909 | + try: |
| 910 | + tcl_vars_str = cStringIO.StringIO( |
| 911 | + "[default]\n" + open(tcl_config, "r").read()) |
| 912 | + tk_vars_str = cStringIO.StringIO( |
| 913 | + "[default]\n" + open(tk_config, "r").read()) |
| 914 | + except IOError: |
| 915 | + # if we can't read the file, that's ok, we'll try |
| 916 | + # to guess instead |
| 917 | + return None |
| 918 | + |
| 919 | + tcl_vars_str.seek(0) |
| 920 | + tcl_vars = ConfigParser.RawConfigParser() |
| 921 | + tk_vars_str.seek(0) |
| 922 | + tk_vars = ConfigParser.RawConfigParser() |
| 923 | + try: |
| 924 | + tcl_vars.readfp(tcl_vars_str) |
| 925 | + tk_vars.readfp(tk_vars_str) |
| 926 | + except ConfigParser.ParsingError: |
| 927 | + # if we can't read the file, that's ok, we'll try |
| 928 | + # to guess instead |
| 929 | + return None |
| 930 | + |
| 931 | + try: |
| 932 | + tcl_lib = tcl_vars.get("default", "TCL_LIB_SPEC")[1:-1].split()[0][2:] |
| 933 | + tcl_inc = tcl_vars.get("default", "TCL_INCLUDE_SPEC")[3:-1] |
| 934 | + tk_lib = tk_vars.get("default", "TK_LIB_SPEC")[1:-1].split()[0][2:] |
| 935 | + if tk_vars.has_option("default", "TK_INCLUDE_SPEC"): |
| 936 | + # On Ubuntu 8.04 |
| 937 | + tk_inc = tk_vars.get("default", "TK_INCLUDE_SPEC")[3:-1] |
| 938 | + else: |
| 939 | + # On RHEL4 |
| 940 | + tk_inc = tcl_inc |
| 941 | + except (ConfigParser.NoSectionError, ConfigParser.NoOptionError): |
| 942 | + return None |
| 943 | + |
| 944 | + if not os.path.exists(os.path.join(tk_inc, 'tk.h')): |
| 945 | + return None |
| 946 | + |
| 947 | + return tcl_lib, tcl_inc, tk_lib, tk_inc |
| 948 | + |
| 949 | +def guess_tcl_config(tcl_lib_dir, tk_lib_dir, tk_ver): |
| 950 | + if not (os.path.exists(tcl_lib_dir) and os.path.exists(tk_lib_dir)): |
| 951 | + return None |
| 952 | + |
| 953 | + tcl_lib = os.path.normpath(os.path.join(tcl_lib_dir, '../')) |
| 954 | + tk_lib = os.path.normpath(os.path.join(tk_lib_dir, '../')) |
| 955 | + |
| 956 | + tcl_inc = os.path.normpath(os.path.join(tcl_lib_dir, |
| 957 | + '../../include/tcl' + tk_ver)) |
| 958 | + if not os.path.exists(tcl_inc): |
| 959 | + tcl_inc = os.path.normpath(os.path.join(tcl_lib_dir, |
| 960 | + '../../include')) |
| 961 | + |
| 962 | + tk_inc = os.path.normpath(os.path.join(tk_lib_dir, |
| 963 | + '../../include/tk' + tk_ver)) |
| 964 | + if not os.path.exists(tk_inc): |
| 965 | + tk_inc = os.path.normpath(os.path.join(tk_lib_dir, |
| 966 | + '../../include')) |
| 967 | + |
| 968 | + if not os.path.exists(os.path.join(tk_inc, 'tk.h')): |
| 969 | + tk_inc = tcl_inc |
| 970 | + |
| 971 | + if not os.path.exists(tcl_inc): |
| 972 | + # this is a hack for suse linux, which is broken |
| 973 | + if (sys.platform.startswith('linux') and |
| 974 | + os.path.exists('/usr/include/tcl.h') and |
| 975 | + os.path.exists('/usr/include/tk.h')): |
| 976 | + tcl_inc = '/usr/include' |
| 977 | + tk_inc = '/usr/include' |
| 978 | + |
| 979 | + if not os.path.exists(os.path.join(tk_inc, 'tk.h')): |
| 980 | + return None |
| 981 | + |
| 982 | + return tcl_lib, tcl_inc, tk_lib, tk_inc |
| 983 | + |
| 984 | +def hardcoded_tcl_config(): |
| 985 | + tcl_inc = "/usr/local/include" |
| 986 | + tk_inc = "/usr/local/include" |
| 987 | + tcl_lib = "/usr/local/lib" |
| 988 | + tk_lib = "/usr/local/lib" |
| 989 | + return tcl_lib, tcl_inc, tk_lib, tk_inc |
| 990 | + |
891 | 991 | def add_tk_flags(module): |
892 | 992 | 'Add the module flags to build extensions which use tk' |
893 | 993 | message = None |
@@ -951,46 +1051,39 @@ def add_tk_flags(module): |
951 | 1051 |
|
952 | 1052 | # you're still here? ok we'll try it this way... |
953 | 1053 | else: |
| 1054 | + success = False |
| 1055 | + # There are 3 methods to try, in decreasing order of "smartness" |
| 1056 | + # |
| 1057 | + # 1. Parse the tclConfig.sh and tkConfig.sh files that have |
| 1058 | + # all the information we need |
| 1059 | + # |
| 1060 | + # 2. Guess the include and lib dirs based on the location of |
| 1061 | + # Tkinter's 'tcl_library' and 'tk_library' variables. |
| 1062 | + # |
| 1063 | + # 3. Use some hardcoded locations that seem to work on a lot |
| 1064 | + # of distros. |
| 1065 | + |
954 | 1066 | # Query Tcl/Tk system for library paths and version string |
955 | | - tcl_lib_dir, tk_lib_dir, tk_ver = query_tcltk() # todo: try/except |
956 | | - |
957 | | - # Process base directories to obtain include + lib dirs |
958 | | - if tcl_lib_dir != '' and tk_lib_dir != '': |
959 | | - tcl_lib = os.path.normpath(os.path.join(tcl_lib_dir, '../')) |
960 | | - tk_lib = os.path.normpath(os.path.join(tk_lib_dir, '../')) |
961 | | - tcl_inc = os.path.normpath(os.path.join(tcl_lib_dir, |
962 | | - '../../include/tcl' + tk_ver)) |
963 | | - if not os.path.exists(tcl_inc): |
964 | | - tcl_inc = os.path.normpath(os.path.join(tcl_lib_dir, |
965 | | - '../../include')) |
966 | | - tk_inc = os.path.normpath(os.path.join(tk_lib_dir, |
967 | | - '../../include/tk' + tk_ver)) |
968 | | - if not os.path.exists(tk_inc): |
969 | | - tk_inc = os.path.normpath(os.path.join(tk_lib_dir, |
970 | | - '../../include')) |
971 | | - |
972 | | - if ((not os.path.exists(os.path.join(tk_inc,'tk.h'))) and |
973 | | - os.path.exists(os.path.join(tcl_inc,'tk.h'))): |
974 | | - tk_inc = tcl_inc |
975 | | - |
976 | | - if not os.path.exists(tcl_inc): |
977 | | - # this is a hack for suse linux, which is broken |
978 | | - if (sys.platform.startswith('linux') and |
979 | | - os.path.exists('/usr/include/tcl.h') and |
980 | | - os.path.exists('/usr/include/tk.h')): |
981 | | - tcl_inc = '/usr/include' |
982 | | - tk_inc = '/usr/include' |
| 1067 | + try: |
| 1068 | + tcl_lib_dir, tk_lib_dir, tk_ver = query_tcltk() |
| 1069 | + except: |
| 1070 | + result = hardcoded_tcl_config() |
983 | 1071 | else: |
984 | | - message = """\ |
| 1072 | + result = parse_tcl_config(tcl_lib_dir, tk_lib_dir) |
| 1073 | + if result is None: |
| 1074 | + message = """\ |
| 1075 | +Guessing the library and include directories for Tcl and Tk because the |
| 1076 | +tclConfig.sh and tkConfig.sh could not be found and/or parsed.""" |
| 1077 | + result = guess_tcl_config(tcl_lib_dir, tk_lib_dir, tk_ver) |
| 1078 | + if result is None: |
| 1079 | + message = """\ |
985 | 1080 | Using default library and include directories for Tcl and Tk because a |
986 | 1081 | Tk window failed to open. You may need to define DISPLAY for Tk to work |
987 | 1082 | so that setup can determine where your libraries are located.""" |
988 | | - tcl_inc = "/usr/local/include" |
989 | | - tk_inc = "/usr/local/include" |
990 | | - tcl_lib = "/usr/local/lib" |
991 | | - tk_lib = "/usr/local/lib" |
992 | | - tk_ver = "" |
| 1083 | + result = hardcoded_tcl_config() |
| 1084 | + |
993 | 1085 | # Add final versions of directories and libraries to module lists |
| 1086 | + tcl_lib, tcl_inc, tk_lib, tk_inc = result |
994 | 1087 | module.include_dirs.extend([tcl_inc, tk_inc]) |
995 | 1088 | module.library_dirs.extend([tcl_lib, tk_lib]) |
996 | 1089 | module.libraries.extend(['tk' + tk_ver, 'tcl' + tk_ver]) |
|
0 commit comments