From ed6ce8b43b6f25df1d4809ac799de4dd1c85c1f3 Mon Sep 17 00:00:00 2001 From: nagai Date: Sun, 12 Jul 2009 23:08:32 +0000 Subject: * ext/tk/extconf.rb: New strategy for searching Tcl/Tk libraries. * ext/tk/*: Support new features of Tcl/Tk8.6b1 and minor bug fixes. ( [KNOWN BUG] Ruby/Tk on Ruby 1.9 will not work on Cygwin. ) * ext/tk/*: Unify sources between Ruby 1.8 & 1.9. Improve default_widget_set handling. * ext/tk/*: Multi-TkInterpreter (multi-tk.rb) works on Ruby 1.8 & 1.9. ( [KNOWN BUG] On Ruby 1.8, join to a long term Thread on Tk callbacks may freeze. On Ruby 1.9, cannot create a second master interpreter (creating slaves are OK); supported master interpreter is the default master interpreter only. ) * ext/tk/lib/tkextlib/*: Update supported versions of Tk extensions. Tcllib 1.8/Tklib 0.4.1 ==> Tcllib 1.11.1/Tklib 0.5 BWidgets 1.7 ==> BWidgets 1.8 TkTable 2.9 ==> TkTable 2.10 TkTreeCtrl 2005-12-02 ==> TkTreeCtrl 2.2.9 Tile 0.8.0/8.5.1 ==> Tile 0.8.3/8.6b1 IncrTcl 2005-02-14 ==> IncrTcl 2008-12-15 TclX 2005-02-07 ==> TclX 2008-12-15 Trofs 0.4.3 ==> Trofs 0.4.4 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24063 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/tk/extconf.rb | 1087 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 930 insertions(+), 157 deletions(-) (limited to 'ext/tk/extconf.rb') diff --git a/ext/tk/extconf.rb b/ext/tk/extconf.rb index ebc83a0c0b..7d2853a37b 100644 --- a/ext/tk/extconf.rb +++ b/ext/tk/extconf.rb @@ -1,93 +1,126 @@ +############################################################## # extconf.rb for tcltklib - +# release date: 2009-07-12 +############################################################## require 'mkmf' -is_win32 = (/mswin|mingw|cygwin|bccwin/ =~ RUBY_PLATFORM) -#is_macosx = (/darwin/ =~ RUBY_PLATFORM) +TkLib_Config = {} +TkLib_Config['search_versions'] = + %w[8.9 8.8 8.7 8.6 8.5 8.4 8.3 8.2 8.1 8.0 4.2] -have_func("ruby_native_thread_p", "ruby.h") -have_func("rb_errinfo", "ruby.h") -have_func("rb_safe_level", "ruby.h") -have_struct_member("struct RArray", "ptr", "ruby.h") -have_struct_member("struct RArray", "len", "ruby.h") -def find_framework(tcl_hdr, tk_hdr) - if framework_dir = with_config("tcltk-framework") - paths = [framework_dir] - else - unless tcl_hdr || tk_hdr || - enable_config("tcltk-framework", false) || - enable_config("mac-tcltk-framework", false) - return false - end - paths = ["/Library/Frameworks", "/System/Library/Frameworks"] - end - - checking_for('Tcl/Tk Framework') { - paths.find{|dir| - dir.strip! - dir.chomp!('/') - (tcl_hdr || FileTest.directory?(dir + "/Tcl.framework/") ) && - (tk_hdr || FileTest.directory?(dir + "/Tk.framework/") ) - } - } +############################################################## +# use old extconf.rb ? +############################################################## +if with_config('tk-old-extconf') + require File.join(File.dirname(__FILE__), 'old-extconf.rb') + exit end -tcl_framework_header = with_config("tcl-framework-header") -tk_framework_header = with_config("tk-framework-header") -tcltk_framework = find_framework(tcl_framework_header, tk_framework_header) - -unless is_win32 - have_library("nsl", "t_open") - have_library("socket", "socket") - have_library("dl", "dlopen") - have_library("m", "log") +############################################################## +# check configs +############################################################## +$cleanfiles << 'config_list' +config_list_file = File.join(File.dirname(__FILE__),'config_list') +config_list_file_source = config_list_file + '.in' +if !File.exist?(config_list_file) || + File.ctime(config_list_file_source) > File.ctime(config_list_file) + old_config_list_file = config_list_file_source +else + old_config_list_file = config_list_file end -tk_idir, tk_ldir = dir_config("tk") -tcl_idir, tcl_ldir = dir_config("tcl") -x11_idir, x11_ldir = dir_config("X11") +current_configs = {'with'=>{}, 'enable'=>{}} -tk_ldir2 = with_config("tk-lib") -tcl_ldir2 = with_config("tcl-lib") -x11_ldir2 = with_config("X11-lib") +# setup keys by config_list.in +IO.foreach(config_list_file_source){|line| + line.chomp! + line.lstrip! + next if line.empty? || line =~ /^\#/ # + mode, key, value = line.split(/\s+/, 3) + value ||= "" + current_configs[mode][key] = value rescue nil +} -tk_ldir_list = [tk_ldir2, tk_ldir] -tcl_ldir_list = [tcl_ldir2, tcl_ldir] +# define current value of keys +IO.foreach(old_config_list_file){|line| + line.chomp! + line.lstrip! + next if line.empty? || line =~ /^\#/ # + mode, key, value = line.split(/\s+/, 3) + value ||= "" + if current_configs[mode] && current_configs[mode].has_key?(key) + current_configs[mode][key] = value + end +} -tklib = with_config("tklib") -tcllib = with_config("tcllib") -stubs = enable_config("tcltk_stubs") || with_config("tcltk_stubs") +update_flag = false +current_configs['with'].each_key{|key| + if (value = with_config(key).to_s) != current_configs['with'][key] + update_flag = true + current_configs['with'][key] = value + end +} +current_configs['enable'].each_key{|key| + if (value = enable_config(key).to_s) != current_configs['enable'][key] + update_flag = true + current_configs['enable'][key] = value + end +} -tcltk_version = with_config("tcltkversion") +# update current_configs +if update_flag || !File.exist?(config_list_file) + open(config_list_file, 'w'){|fobj| + fobj.print("# values of current configure options (generated by extconf.rb)\n"); + ['with', 'enable'].each{|mode| + current_configs[mode].each_key{|key| + fobj.print("#{mode} #{key} #{current_configs[mode][key]}\n") + } + } + } +end -use_X = with_config("X11", (! is_win32)) +if update_flag + puts "Configure options for Ruby/Tk may be updated." + puts "So, delete files which depend on old configs." + File.delete(*(Dir.glob(File.join(File.dirname(__FILE__), + "*.#{CONFIG['DLEXT']}")))) + File.delete(*(Dir.glob(File.join(File.dirname(__FILE__), "*.#{$OBJEXT}")))) + File.delete(File.join(File.dirname(__FILE__), 'Makefile')) rescue nil -def parse_tclConfig(file) - # check tclConfig.sh/tkConfig.sh - tbl = {} - IO.foreach(file){|line| - line.strip! - next if line !~ /^([^\#=][^=]*)=(['"]|)(.*)\2$/ - key, val = $1, $3 - tbl[key] = val.gsub(/\$\{([^}]+)\}/){|s| tbl[$1]} rescue nil - } - tbl +else + makefile = File.join(File.dirname(__FILE__),'Makefile') + if File.exist?(makefile) && + File.ctime(config_list_file) > File.ctime(makefile) + # no need to update Makefile + exit + end +end + +############################################################## +# fuctions +############################################################## +def is_win32? + /mswin|mingw|cygwin|bccwin/ =~ RUBY_PLATFORM +end + +def is_macosx? + /darwin/ =~ RUBY_PLATFORM end def check_tcltk_version(version) - return [nil, nil] unless version + return [nil, nil] unless version.kind_of? String version = version.strip tclver = version.dup tkver = version.dup - major = dot = minor = dot = plvl = ext = nil + dot = major = minor_dot = minor = plvl_dot = plvl = ext = nil if version =~ /^(\d)(\.?)(\d)(\.?)(\d*)(.*)$/ - major = $1; minor_dot = $2; minor = $3; plvl_dot = $4; plvl = $5; ext = $6 + major = $1; minor_dot = $2; minor = $3; plvl_dot = $4; plvl = $5; ext = $6 dot = ! minor_dot.empty? if plvl_dot.empty? && ! plvl.empty? minor << plvl @@ -111,12 +144,536 @@ def check_tcltk_version(version) [tclver, tkver] end +def get_shlib_versions(major = 8, minor_max = 9, minor_min = 0, ext = "") + if tclcfg = TkLib_Config["tclConfig_info"] + major = tclcfg['TCL_MAJOR_VERSION'].to_i + minor_min = tclcfg['TCL_MINOR_VERSION'].to_i + + elsif TkLib_Config["tcltkversion"] + tclver, tkver = TkLib_Config["tcltkversion"] + if tclver =~ /8\.?(\d)(.*)/ + minor_min = $1.to_i + ext = $2 + else + # unsupported version + return [""] + end + end + + # if disable-stubs, version is fixed. + minor_max = minor_min unless TkLib_Config["tcltk-stubs"] + + vers = [] + minor_max.downto(minor_min){|minor| + vers << "#{major}.#{minor}#{ext}" unless ext.empty? + vers << "#{major}.#{minor}" + } + + vers << "" +end + +def get_shlib_path_head + path_head = [] + path_dirs = [] + + if TkLib_Config["ActiveTcl"].kind_of?(String) # glob path + path_dirs.concat Dir.glob(TkLib_Config["ActiveTcl"]).sort.reverse + end + + if is_win32? + if TkLib_Config["ActiveTcl"] + path_head.concat ["c:/ActiveTcl", "c:/Program Files/ActiveTcl"] + end + path_head.concat [ + "c:/Tcl", "c:/Program Files/Tcl", + "/Tcl", "/Program Files/Tcl" + ] + path_head.each{|dir| path_dirs << "#{dir}"} + + else + [ + '/opt', '/pkg', '/share', + '/usr/local/opt', '/usr/local/pkg', '/usr/local/share', '/usr/local', + '/usr/opt', '/usr/pkg', '/usr/share', '/usr/contrib', '/usr' + ].each{|dir| + next unless File.directory?(dir) + + path_dirs << "#{dir}/lib" + path_dirs << "#{dir}" unless Dir.glob("#{dir}/lib*.*").empty? + + dirnames = [] + if TkLib_Config["ActiveTcl"] + dirnames.concat ["ActiveTcl","activeTcl","Activetcl","activetcl"] + end + dirnames.concat ["TclTk","Tcl_Tk","Tcl-Tk","tcltk","tcl_tk","tcl-tk"] + + dirnames.each{|name| + path_dirs << "#{dir}/#{name}" if File.directory?("#{dir}/#{name}") + path_head << "#{dir}/#{name}" unless Dir.glob("#{dir}/#{name}[-89_]*").empty? + } + } + end + + [path_head, path_dirs] +end + +def find_macosx_framework + use_framework = is_macosx? && TkLib_Config["ActiveTcl"] + + use_framework ||= (tcl_hdr = with_config("tcl-framework-header")) + use_framework ||= (tk_hdr = with_config("tk-framework-header")) + tcl_hdr = nil unless tcl_hdr.kind_of? String + tk_hdr = nil unless tk_hdr.kind_of? String + TkLib_Config["tcl-framework-header"] = tcl_hdr + TkLib_Config["tk-framework-header"] = tk_hdr + + use_framework ||= (tcl_dir = with_config("tcl-framework-dir")) + tcl_dir = nil unless tcl_dir.kind_of? String + if !tcl_dir && tcl_hdr + # e.g. /Library/Frameworks/Tcl.framework/Headers + # ==> /Library/Frameworks/Tcl.framework + tcl_dir = File.dirname(tcl_hdr.strip.chomp('/')) + end + TkLib_Config["tcl-framework-dir"] = tcl_dir + + use_framework ||= (tk_dir = with_config("tk-framework-dir")) + tk_dir = nil unless tk_dir.kind_of? String + if !tk_dir && tk_hdr + # e.g. /Library/Frameworks/Tk.framework/Headers + # ==> /Library/Frameworks/Tk.framework + tk_dir = File.dirname(tk_hdr.strip.chomp('/')) + end + TkLib_Config["tk-framework-dir"] = tk_dir + + if tcl_dir && !tk_dir + tk_dir = File.join(File.dirname(tcl_dir), 'Tk.framework') + TkLib_Config["tk-framework-dir"] = tk_dir + elsif !tcl_dir && tk_dir + tcl_dir = File.join(File.dirname(tk_dir), 'Tcl.framework') + TkLib_Config["tcl-framework-dir"] = tcl_dir + end + if tcl_dir && tk_dir + TkLib_Config["tcltk-framework"] = File.dirname(tcl_dir) unless TkLib_Config["tcltk-framework"] + return [tcl_dir, tk_dir] + end + + # framework is disabled? + if with_config("tcltk-framework") == false || + enable_config("tcltk-framework") == false + return false + end + + use_framework ||= (framework_dir = with_config("tcltk-framework")) + if framework_dir.kind_of? String + TkLib_Config["tcltk-framework"] = framework_dir.strip.chomp('/') + return [File.join(TkLib_Config["tcltk-framework"], 'Tcl.framework'), + File.join(TkLib_Config["tcltk-framework"], 'Tk.framework')] + end + + unless enable_config("tcltk-framework", use_framework) || + enable_config("mac-tcltk-framework", use_framework) + TkLib_Config["tcltk-framework"] = false + return false + end + + paths = [ + #"~/Library/Frameworks", + "/Library/Frameworks", + "/Network/Library/Frameworks", "/System/Library/Frameworks" + ] + + paths.map{|dir| dir.strip.chomp('/')}.each{|dir| + next unless File.directory?(tcldir = File.join(dir, "Tcl.framework")) + next unless File.directory?(tkdir = File.join(dir, "Tk.framework")) + TkLib_Config["tcltk-framework"] = dir + return [tcldir, tkdir] + } + + nil +end + +def collect_tcltk_defs(tcl_defs_str, tk_defs_str) + conflicts = [ + 'PACKAGE_NAME', 'PACKAGE_TARNAME', 'PACKAGE_VERSION', + 'PACKAGE_STRING', 'PACKAGE_BUGREPORT' + ] + + begin + # Ruby 1.9.x or later + arch_config_h = RbConfig.expand($arch_hdrdir + "/ruby/config.h") + if File.exist?(arch_config_h) + keys = [] + IO.foreach(arch_config_h){|line| + if line =~ /^#define +([^ ]+)/ + keys << $1 + end + } + conflicts = keys + end + rescue + # ignore, use default + end + + if tcl_defs_str + tcl_defs = tcl_defs_str.split(/ ?-D/).map{|s| + s =~ /^([^=]+)(.*)$/ + [$1, $2] + } + else + tcl_defs = [] + end + + if tk_defs_str + tk_defs = tk_defs_str.split(/ ?-D/).map{|s| + s =~ /^([^=]+)(.*)$/ + [$1, $2] + } + else + tk_defs = [] + end + + defs = tcl_defs | tk_defs + + defs.delete_if{|name,value| + conflicts.include?(name) || + ( (vtcl = tcl_defs.assoc(name)) && (vtk = tk_defs.assoc(name)) && + vtcl != vtk ) + } + + defs.map{|ary| s = ary.join(''); (s.strip.empty?)? "": "-D" << s}.join(' ') +end + +def parse_tclConfig(file) + # check tclConfig.sh/tkConfig.sh + tbl = Hash.new{|h,k| h[k] = ""} + return tbl unless file + IO.foreach(file){|line| + line.strip! + next if line !~ /^([^\#=][^=]*)=(['"]|)(.*)\2$/ + key, val = $1, $3 + tbl[key] = val.gsub(/\$\{([^}]+)\}/){|s| + subst = $1 + (tbl[subst])? tbl[subst]: s + } rescue nil + } + tbl +end + +def get_libpath(lib_flag, lib_spec) + # get libpath fro {TCL,Tk}_LIB_FLAG and {TCL,Tk}_LIB_SPEC + libpath = lib_spec.gsub(/(#{lib_flag}|-L)/, "").strip +end + +def search_tclConfig(*paths) # list of lib-dir or [tcl-libdir, tk-libdir] + TkLib_Config["tclConfig_paths"] = [] + config_dir = [] + + paths.compact! + + fixed_tclConfig = ! paths.empty? + + paths.each{|path| + if path.kind_of?(Array) + config_dir << path + else + dirs = Dir.glob(path) + config_dir.concat(dirs.zip(dirs)) + end + } + + if is_win32? + if TkLib_Config["ActiveTcl"] + dirs = [] + if TkLib_Config["ActiveTcl"].kind_of?(String) + dirs << TkLib_Config["ActiveTcl"] + end + dirs.concat [ + "c:/ActiveTcl*/lib", "c:/Activetcl*/lib", + "c:/activeTcl*/lib", "c:/activetcl*/lib", + "c:/Tcl*/lib", "c:/tcl*/lib", + "c:/Program Files/ActiveTcl*/lib", "c:/Program Files/Activetcl*/lib", + "c:/Program Files/activeTcl*/lib", "c:/Program Files/activetcl*/lib", + "c:/Program Files/Tcl*/lib", "c:/Program Files/tcl*/lib", + "/ActiveTcl*/lib", "/Activetcl*/lib", + "/activeTcl*/lib", "/activetcl*/lib", + "/Tcl*/lib", "/tcl*/lib", + "/Program Files/ActiveTcl*/lib", "/Program Files/Activetcl*/lib", + "/Program Files/activeTcl*/lib", "/Program Files/activetcl*/lib", + "/Program Files/Tcl*/lib", "/Program Files/tcl*/lib" + ] + else + dirs = [ + "c:/Tcl*/lib", "c:/tcl*/lib", + "c:/Program Files/Tcl*/lib", "c:/Program Files/tcl*/lib", + "/Tcl*/lib", "/tcl*/lib", + "/Program Files/Tcl*/lib", "/Program Files/tcl*/lib" + ] + end + dirs.collect{|d| Dir.glob(d)}.flatten! + dirs |= dirs + + ENV['PATH'].split(';').each{|dir| + dirs << File.expand_path(File.join(dir, '..', 'lib')) + dirs << dir + dirs << File.expand_path(File.join(dir, '..')) + } + + config_dir.concat(dirs.zip(dirs)) + + elsif framework = find_macosx_framework() + config_dir.unshift(framework) + + else + if activeTcl = TkLib_Config['ActiveTcl'] + # check latest version at first + config_dir.concat(Dir.glob(activeTcl).sort.reverse) + end + + config_dir.concat [ + RbConfig::CONFIG['libdir'], + File.join(RbConfig::CONFIG['exec_prefix'], 'lib'), + File.join(RbConfig::CONFIG['prefix'], 'lib'), + "/usr/local/opt/lib", "/usr/local/pkg/lib", "/usr/local/share/lib", + "/usr/local/lib", "/usr/opt/lib", "/usr/pkg/lib", + "/usr/share/lib", "/usr/contrib/lib", "/usr/lib" + ] + + config_dir.concat [ + '/opt', '/pkg', '/share', + '/usr/local/opt', '/usr/local/pkg', '/usr/local/share', '/usr/local', + '/usr/opt', '/usr/pkg', '/usr/share', '/usr/contrib', '/usr' + ].map{|dir| + Dir.glob(dir + '/{TclTk,tcltk,Tcl,tcl,Tk,tk}[87]*/lib') + Dir.glob(dir + '/{TclTk,tcltk,Tcl,tcl,Tk,tk}[87]*') + Dir.glob(dir + '/{TclTk,tcltk,Tcl,tcl,Tk,tk}/lib') + Dir.glob(dir + '/{TclTk,tcltk,Tcl,tcl,Tk,tk}') + }.flatten! + + ENV['PATH'].split(':').each{|dir| + config_dir << File.expand_path(File.join(dir, '..', 'lib')) + } + + # for MacOS X + #config_dir << "~/Library/Tcl" + #config_dir.concat(Dir.glob("~/Library/Tcl/*").sort.reverse) + config_dir << "/Library/Tcl" + config_dir.concat(Dir.glob("/Library/Tcl/*").sort.reverse) + config_dir << "/Network/Library/Tcl" + config_dir.concat(Dir.glob("/Network/Library/Tcl/*").sort.reverse) + config_dir << "/System/Library/Tcl" + config_dir.concat(Dir.glob("/System/Library/Tcl/*").sort.reverse) + [ + #"~/Library/Frameworks", + "/Library/Frameworks", + "/Network/Library/Frameworks", "/System/Library/Frameworks" + ].each{|framework| + config_dir << [File.expand_path(File.join(framework, 'Tcl.framework')), + File.expand_path(File.join(framework, 'Tk.framework'))] + } + end + + tclver, tkver = TkLib_Config['tcltkversion'] + conf = nil + + config_dir.map{|dir| + if dir.kind_of? Array + [dir[0].strip.chomp('/'), dir[1].strip.chomp('/')] + else + dir.strip.chomp('/') + end + }.each{|dir| + # print("check #{dir} ==>"); + if dir.kind_of? Array + tcldir, tkdir = dir + else + tcldir = tkdir = dir + end + + ['Config-shared.sh','config-shared.sh','Config.sh','config.sh'].each{|f| + tclpath = File.join(tcldir, 'tcl' << f) + tkpath = File.join(tkdir, 'tk' << f) + next if !File.exist?(tclpath) || !File.exist?(tkpath) + + # parse tclConfig.sh/tkConfig.sh + tclconf = parse_tclConfig(tclpath) + next if tclver && tclver !~ /^#{tclconf['TCL_MAJOR_VERSION']}(\.?)#{tclconf['TCL_MINOR_VERSION']}/ + tkconf = parse_tclConfig(tkpath) + next if tkver && tkver !~ /^#{tkconf['TK_MAJOR_VERSION']}(\.?)#{tkconf['TK_MINOR_VERSION']}/ + + # find tclConfig.sh & tkConfig.sh + conf = [tclconf, tkconf] unless conf + + # nativethread check + unless TkLib_Config["ruby_with_thread"] + tclconf['TCL_THREADS'] == '1' + puts "WARNIG: find #{tclpath.inspect}, but it WITH nativethread-support under ruby WITHOUT nativethread-support. So, ignore it." + TkLib_Config["tcltk-NG-path"] << File.dirname(tclpath) + next + end + + #return [tclpath, tkpath] + # print(" #{[tclpath, tkpath]}"); + TkLib_Config["tclConfig_paths"] << [tclpath, tkpath] + } + + # print("\n"); + } + + if TkLib_Config["tclConfig_paths"].empty? + [nil, nil] + else + # find tclConfig.sh and tkConfig.sh + TkLib_Config["tclConfig_info"], TkLib_Config["tkConfig_info"] = conf + TkLib_Config["tclConfig_paths"][0] + end +end + +def get_tclConfig(tclConfig_file, tclConfig_dir, tkConfig_dir) + use_tclConfig = (tclConfig_file != false) && + (tclConfig_dir != false) && (tkConfig_dir != false) + + tclConfig_file = nil unless tclConfig_file.kind_of? String + tclConfig_dir = nil unless tclConfig_dir.kind_of? String + tkConfig_dir = nil unless tkConfig_dir.kind_of? String + + unless tclConfig_dir + if tclConfig_file + tclConfig_dir = File.dirname(tclConfig_file) + elsif tkConfig_dir + tclConfig_dir = tkConfig_dir + end + end + tkConfig_dir ||= tclConfig_dir + + TkLib_Config["tclConfig-file"] = tclConfig_file + TkLib_Config["tclConfig-dir"] = tclConfig_dir + TkLib_Config["tkConfig-dir"] = tkConfig_dir + + unless use_tclConfig + puts("Don't use [tclConfig.sh, tkConfig.sh]") + else + puts("Search tclConfig.sh and tkConfig.sh.") + if tclConfig_dir + tclConfig, tkConfig = search_tclConfig([tclConfig_dir, tkConfig_dir]) + else + tclConfig, tkConfig = search_tclConfig() + end + # TclConfig_Info = TkLib_Config["tclConfig_info"] + # TkConfig_Info = TkLib_Config["tkConfig_info"] + + if tclConfig && tkConfig + puts("Use [tclConfig.sh,tkConfig.sh] == ['#{tclConfig}','#{tkConfig}']") + $LIBPATH |= [File.dirname(tclConfig)] + $LIBPATH |= [File.dirname(tkConfig)] + #TkLib_Config["tclConfig_paths"].each{|tclcfg, tkcfg| + # $LIBPATH |= [File.dirname(tclcfg)] | [File.dirname(tkcfg)] + #} + else + puts("Fail to find [tclConfig.sh, tkConfig.sh]") + end + end + + [tclConfig, tkConfig] +end + +def check_NG_path(path_list) + path_list.find_all{|path| not TkLib_Config["tcltk-NG-path"].include?(path) } +end + +def check_shlib_search_path(paths) + if !paths || paths.empty? + path_list = [] + + #if TkLib_Config["ActiveTcl"] + # path_list.concat Dir.glob(TkLib_Config["ActiveTcl"]).sort.reverse + #end + if TkLib_Config["ActiveTcl"].kind_of?(String) # glob path + path_list.concat Dir.glob(TkLib_Config["ActiveTcl"]).sort.reverse + end + + vers = get_shlib_versions + path_head, path_dirs = get_shlib_path_head + + path_list.concat vers.map{|ver| + path_head.map{|head| + if ver.empty? + head + "/lib" + else + dirs = [] + + if !Dir.glob(head + "-*").empty? + dirs << head + "-#{ver}/lib" if !Dir.glob(head + "-[89].*").empty? + dirs << head + "-#{ver.delete('.')}/lib" if !Dir.glob(head + "-[89][0-9]*").empty? + end + + if !Dir.glob(head + "[_-]*").empty? + dirs << head + "_#{ver}/lib" if !Dir.glob(head + "_[89].*").empty? + dirs << head + "-#{ver}/lib" if !Dir.glob(head + "-[89].*").empty? + dirs << head + "_#{ver.delete('.')}/lib" if !Dir.glob(head + "_[89][0-9]*").empty? + dirs << head + "-#{ver.delete('.')}/lib" if !Dir.glob(head + "-[89][0-9]*").empty? + end + + dirs + end + } + }.flatten! + + path_list.concat path_dirs + + else + # paths is a string with PATH environment style + path_list = paths.split((is_win32?)? ';': ':') + end + + path_list = check_NG_path(path_list) + + path_list.each{|path| $LIBPATH |= [path.strip] } +end + def find_tcl(tcllib, stubs, version, *opt_paths) - default_paths = ["/usr/local/lib", "/usr/pkg/lib", "/usr/lib"] - default_paths << "/Tcl/lib" # default for ActiveTcl + puts "Search Tcl library" + default_paths = [] + + default_paths.concat [ + RbConfig::CONFIG['libdir'], + File.join(RbConfig::CONFIG['exec_prefix'], 'lib'), + File.join(RbConfig::CONFIG['prefix'], 'lib'), + "/usr/local/lib", "/usr/pkg/lib", "/usr/contrib/lib", "/usr/lib" + ].find_all{|dir| File.directory?(dir)} + + default_paths.concat [ + "c:/Tcl/lib", "c:/Program Files/Tcl/lib", + "/Tcl/lib", "/Program Files/Tcl/lib" + ].find_all{|dir| File.directory?(dir)} if (paths = opt_paths.compact).empty? - paths = default_paths + if TclConfig_Info['config_file_path'] + # use definisions on tclConfig.sh + TclConfig_Info['TCL_LIB_SPEC'].sub(TclConfig_Info['TCL_LIB_FLAG'],"").strip.sub("-L","") =~ /("|'|)([^"']+)\1/ + $LIBPATH |= [$2] unless $2.empty? + + unless stubs + #*** Probably, TCL_LIBS is a subset of TK_LIBS. *** + # $LDFLAGS << ' ' << TclConfig_Info['TCL_LIBS'] + # $DLDFLAGS << ' ' << TclConfig_Info['TCL_LIBS'] + $LDFLAGS << ' ' << TclConfig_Info['TCL_LIB_SPEC'] + return true + end + + if TclConfig_Info['TCL_SUPPORTS_STUBS'] == '0' || + TclConfig_Info['TCL_STUB_LIB_SPEC'].strip.empty? + puts "#{TclConfig_Info['config_file_path']} tells us that your Tcl/Tk library doesn't support stub." + return false + else + #*** Probably, TCL_LIBS is a subset of TK_LIBS. *** + # $LDFLAGS << ' ' << TclConfig_Info['TCL_LIBS'] + # $DLDFLAGS << ' ' << TclConfig_Info['TCL_LIBS'] + $LDFLAGS << ' ' << TclConfig_Info['TCL_STUB_LIB_SPEC'] + return true + end + end + + paths = check_NG_path(default_paths) end if stubs @@ -130,7 +687,7 @@ def find_tcl(tcllib, stubs, version, *opt_paths) if version && ! version.empty? versions = [version] else - versions = %w[8.7 8.6 8.5 8.4 8.3 8.2 8.1 8.0 7.6] + versions = TkLib_Config['search_versions'] end if tcllib @@ -154,12 +711,62 @@ def find_tcl(tcllib, stubs, version, *opt_paths) st end +def parse_TK_LIBS(tklibs) + sfx = "lib|shlib|dll|so" + re = /(("|')[^"']+\.(#{sfx})\2|[^"' ]+\.(#{sfx})|-l("|')[^"']+\5|-l[^" ]+)/#' + + tklibs.scan(re).map{|lib,| + if lib =~ /^("|')([^"]+)\.(#{sfx})\1/ + "\"-l#{$2}\"" + elsif lib =~ /([^" ]+)\.(#{sfx})/ + "-l#{$1}" + else + lib + end + }.join(' ') +end + def find_tk(tklib, stubs, version, *opt_paths) - default_paths = ["/usr/local/lib", "/usr/pkg/lib", "/usr/lib"] - default_paths << "/Tcl/lib" # default for ActiveTcl + puts "Search Tk library" + default_paths = [] + + default_paths.concat [ + RbConfig::CONFIG['libdir'], + File.join(RbConfig::CONFIG['exec_prefix'], 'lib'), + File.join(RbConfig::CONFIG['prefix'], 'lib'), + "/usr/local/lib", "/usr/pkg/lib", "/usr/contrib/lib", "/usr/lib" + ].find_all{|dir| File.directory?(dir)} + + default_paths.concat [ + "c:/Tcl/lib", "c:/Program Files/Tcl/lib", + "/Tcl/lib", "/Program Files/Tcl/lib" + ].find_all{|dir| File.directory?(dir)} if (paths = opt_paths.compact).empty? - paths = default_paths + if TkConfig_Info['config_file_path'] + # use definisions on tkConfig.sh + TkConfig_Info['TK_LIB_SPEC'].sub(TkConfig_Info['TK_LIB_FLAG'],"").strip.sub("-L","") =~ /("|'|)([^"']+)\1/ + $LIBPATH |= [$2] unless $2.empty? + + unless stubs + $LDFLAGS << ' ' << parse_TK_LIBS(TkConfig_Info['TK_LIBS']) + # $DLDFLAGS << ' ' << parse_TK_LIBS(TkConfig_Info['TK_LIBS']) + $LDFLAGS << ' ' << TkConfig_Info['TK_LIB_SPEC'] + return true + end + + if TkConfig_Info['TK_STUB_LIB_SPEC'].strip.empty? + puts "#{TkConfig_Info['config_file_path']} tells us that your Tcl/Tk library doesn't support stub." + return false + else + $LDFLAGS << ' ' << parse_TK_LIBS(TkConfig_Info['TK_LIBS']) + # $DLDFLAGS << ' ' << parse_TK_LIBS(TkConfig_Info['TK_LIBS']) + $LDFLAGS << ' ' << TkConfig_Info['TK_STUB_LIB_SPEC'] + return true + end + end + + paths = check_NG_path(default_paths) end if stubs @@ -173,7 +780,7 @@ def find_tk(tklib, stubs, version, *opt_paths) if version && ! version.empty? versions = [version] else - versions = %w[8.7 8.6 8.5 8.4 8.3 8.2 8.1 8.0 4.2] + versions = TkLib_Config['search_versions'] end if tklib @@ -198,38 +805,93 @@ def find_tk(tklib, stubs, version, *opt_paths) end def find_tcltk_header(tclver, tkver) - base_dir = ['/usr/local/include', '/usr/pkg/include', '/usr/include'] - base_dir << '/Tcl/include' # default for ActiveTcl + base_dir = [] + + base_dir.concat [ + File.join(RbConfig::CONFIG['prefix'], 'include'), + "/usr/local/include", "/usr/pkg/include", "/usr/contrib/include", + "/usr/include" + ].find_all{|dir| File.directory?(dir)} - unless have_tcl_h = have_header('tcl.h') + base_dir.concat [ + "c:/Tcl/include", "c:/Program Files/Tcl/include", + "/Tcl/include", "/Program Files/Tcl/include" + ].find_all{|dir| File.directory?(dir)} + + if TclConfig_Info['TCL_INCLUDE_SPEC'] && + have_tcl_h = try_cpp('tcl.h', TclConfig_Info['TCL_INCLUDE_SPEC']) + $INCFLAGS << " " << TclConfig_Info['TCL_INCLUDE_SPEC'] + elsif have_tcl_h = have_header('tcl.h') + # find + else if tclver && ! tclver.empty? versions = [tclver] else - versions = %w[8.7 8.6 8.5 8.4 8.3 8.2 8.1 8.0 7.6] + versions = TkLib_Config['search_versions'] end paths = base_dir.dup - versions.each{|ver| paths.concat(base_dir.map{|dir| dir + '/tcl' + ver})} + versions.each{|ver| + paths.concat(base_dir.map{|dir| + [dir + '/tcl' + ver, dir + '/tcl' + ver.delete('.')] + }.flatten) + } have_tcl_h = find_header('tcl.h', *paths) end - unless have_tk_h = have_header("tk.h") + if TkConfig_Info['TK_INCLUDE_SPEC'] && + have_tk_h = try_cpp('tk.h', TclConfig_Info['TK_INCLUDE_SPEC']) + $INCFLAGS << " " << TkConfig_Info['TK_INCLUDE_SPEC'] + elsif have_tk_h = have_header('tk.h') + # find + else if tkver && ! tkver.empty? versions = [tkver] else - versions = %w[8.7 8.6 8.5 8.4 8.3 8.2 8.1 8.0 4.2] + versions = TkLib_Config['search_versions'] end paths = base_dir.dup - versions.each{|ver| paths.concat(base_dir.map{|dir| dir + '/tk' + ver})} + versions.each{|ver| + paths.concat(base_dir.map{|dir| + [dir + '/tk' + ver, dir + '/tk' + ver.delete('.')] + }.flatten) + } have_tk_h = find_header('tk.h', *paths) end have_tcl_h && have_tk_h end +def setup_for_macosx_framework + # search directory of header files + if File.exist?(dir = File.join(TkLib_Config["tcltk-framework"], + 'Tcl.framework', 'Headers')) + TclConfig_Info['TCL_INCLUDE_SPEC'] = "-I#{dir} " + TclConfig_Info['TK_INCLUDE_SPEC'] = "-I#{File.join(TkLib_Config['tcltk-framework'], 'Tk.framework', 'Headers')} " + else + dir = Dir.glob(File.join(TkLib_Config["tcltk-framework"], + 'Tcl.framework', '*', 'Headers')) + TclConfig_Info['TCL_INCLUDE_SPEC'] = "-I#{dir[0]} " unless dir.empty? + TclConfig_Info['TK_INCLUDE_SPEC'] = "-I#{Dir.glob(File.join(TkLib_Config['tcltk-framework'], 'Tk.framework', '*', 'Headers'))[0]} " + end + + $LDFLAGS << ' -framework Tk -framework Tcl' + + if TkLib_Config["tcl-framework-header"] + TclConfig_Info['TCL_INCLUDE_SPEC'] = + "-I#{TkLib_Config["tcl-framework-header"]} " + end + if TkLib_Config["tk-framework-header"] + TkConfig_Info['TK_INCLUDE_SPEC'] = + "-I#{TkLib_Config["tk-framework-header"]} " + end +end + def find_X11(*opt_paths) - default_paths = - [ "/usr/X11/lib", "/usr/lib/X11", "/usr/X11R6/lib", "/usr/openwin/lib" ] - paths = opt_paths.compact.concat(default_paths) + defaults = + [ "/usr/X11*/lib", "/usr/lib/X11*", "/usr/local/X11*", "/usr/openwin/lib" ] + paths = [] + opt_paths.compact.each{|path| paths.concat(Dir.glob(path.strip.chomp('/')))} + defaults.compact.each{|path| paths.concat(Dir.glob(path.strip.chomp('/')))} st = find_library("X11", "XOpenDisplay", *paths) unless st puts("Warning:: cannot find X11 library. tcltklib will not be compiled (tcltklib is disabled on your Ruby == Ruby/Tk will not work). Please check configure options. If your Tcl/Tk don't require X11, please try --without-X11.") @@ -237,6 +899,31 @@ def find_X11(*opt_paths) st end +def search_X_libraries + if TkConfig_Info['config_file_path'] + # use definitions on tkConfig.sh + if TkConfig_Info['TK_XINCLUDES'] && TkConfig_Info['TK_XLIBSW'] && + !TkConfig_Info['TK_XINCLUDES'].strip.empty? && + !TkConfig_Info['TK_XLIBSW'].strip.empty? + use_X = true && with_config("X11", (! is_win32?)) + else + use_X = false || with_config("X11", false) + end + else + # depend on configure options + use_X = with_config("X11", (! is_win32?)) + end + + if use_X + puts("Use X11 libraries.") + x11_idir, x11_ldir = dir_config("X11") + x11_ldir2 = with_config("X11-lib") + exit unless find_X11(x11_ldir2, x11_ldir) + end + + use_X +end + def pthread_check() tcl_major_ver = nil tcl_minor_ver = nil @@ -251,42 +938,36 @@ def pthread_check() tcl_enable_thread = nil end - if (tclConfig = with_config("tclConfig-file")) + if TclConfig_Info['config_file_path'] if tcl_enable_thread == true - puts("Warning: --with-tclConfig-file option is ignored, because --enable-tcl-thread option is given.") + puts("Warning: definiton of tclConfig.sh is ignored, because --enable-tcl-thread option is given.") elsif tcl_enable_thread == false - puts("Warning: --with-tclConfig-file option is ignored, because --disable-tcl-thread option is given.") + puts("Warning: definition of tclConfig.sh is ignored, because --disable-tcl-thread option is given.") else # tcl-thread is unknown and tclConfig.sh is given - begin - tbl = parse_tclConfig(tclConfig) - if tbl['TCL_THREADS'] - tcl_enable_thread = (tbl['TCL_THREADS'] == "1") - else - tcl_major_ver = tbl['TCL_MAJOR_VERSION'].to_i - tcl_minor_ver = tbl['TCL_MINOR_VERSION'].to_i - if tcl_major_ver < 8 || (tcl_major_ver == 8 && tcl_minor_ver == 0) - tcl_enable_thread = false - end + if TclConfig_Info['TCL_THREADS'] + tcl_enable_thread = (TclConfig_Info['TCL_THREADS'] == "1") + else + tcl_major_ver = TclConfig_Info['TCL_MAJOR_VERSION'].to_i + tcl_minor_ver = TclConfig_Info['TCL_MINOR_VERSION'].to_i + if tcl_major_ver < 8 || (tcl_major_ver == 8 && tcl_minor_ver == 0) + tcl_enable_thread = false end + end - if tcl_enable_thread == nil - # cannot find definition - if tcl_major_ver - puts("Warning: '#{tclConfig}' doesn't include TCL_THREADS definition.") - else - puts("Warning: '#{tclConfig}' may not be a tclConfig file.") - end - tclConfig = false + if tcl_enable_thread == nil + # cannot find definition + if tcl_major_ver + puts("Warning: '#{TclConfig_Info['config_file_path']}' doesn't include TCL_THREADS definition.") + else + puts("Warning: '#{TclConfig_Info['config_file_path']}' may not be a tclConfig file.") end - rescue Exception - puts("Warning: fail to read '#{tclConfig}'!! --> ignore the file") tclConfig = false end end end - if tcl_enable_thread == nil && !tclConfig + if tcl_enable_thread == nil && !TclConfig_Info['config_file_path'] # tcl-thread is unknown and tclConfig is unavailable begin try_run_available = try_run("int main() { exit(0); }") @@ -295,12 +976,12 @@ def pthread_check() puts(%Q'\ ***************************************************************************** ** -** PTHREAD SUPPORT CHECK WARNING: +** NATIVETHREAD SUPPORT CHECK WARNING: ** -** We cannot check the consistency of pthread support between Ruby -** and the Tcl/Tk library in your environment (are you perhaps -** cross-compiling?). If pthread support for these 2 packages is -** inconsistent you may find you get errors when running Ruby/Tk +** We cannot check the consistency of nativethread support between +** Ruby and the Tcl/Tk library in your environment (are you perhaps +** cross-compiling?). If nativethread support for these 2 packages +** is inconsistent you may find you get errors when running Ruby/Tk ** (e.g. hangs or segmentation faults). We strongly recommend ** you to check the consistency manually. ** @@ -333,26 +1014,27 @@ EOF end # check pthread mode - if (macro_defined?('HAVE_NATIVETHREAD', '#include "ruby.h"')) + if (TkLib_Config["ruby_with_thread"]) # ruby -> enable unless tcl_enable_thread # ruby -> enable && tcl -> disable puts(%Q'\ ***************************************************************************** ** -** PTHREAD SUPPORT MODE WARNING: +** NATIVETHREAD SUPPORT MODE WARNING: ** -** Ruby is compiled with --enable-pthread, but your Tcl/Tk library -** seems to be compiled without pthread support. Although you can -** create the tcltklib library, this combination may cause errors -** (e.g. hangs or segmentation faults). If you have no reason to -** keep the current pthread support status, we recommend you reconfigure -** and recompile the libraries so that both or neither support pthreads. +** Ruby is compiled with --enable-pthread, but your Tcl/Tk library +** seems to be compiled without nativethread support. Although you can +** create the tcltklib library, this combination may cause errors (e.g. +** hangs or segmentation faults). If you have no reason to keep the +** current nativethread support status, we recommend you reconfigure and +** recompile the libraries so that both or neither support nativethreads. ** -** If you want change the status of pthread support, please recompile -** Ruby without "--enable-pthread" configure option or recompile Tcl/Tk -** with "--enable-threads" configure option (if your Tcl/Tk is later -** than or equal to Tcl/Tk 8.1). +** If you want change the status of nativethread support, please recompile +** Ruby without "--enable-pthread" configure option (If you use Ruby 1.9.x +** or later, you cannot remove this option, because it requires native- +** thread support.) or recompile Tcl/Tk with "--enable-threads" configure +** option (if your Tcl/Tk is later than or equal to Tcl/Tk 8.1). ** ***************************************************************************** ') @@ -374,13 +1056,13 @@ EOF puts(%Q'\ ***************************************************************************** ** -** PTHREAD SUPPORT MODE ERROR: +** NATIVETHREAD SUPPORT MODE ERROR: ** ** Ruby is not compiled with --enable-pthread, but your Tcl/Tk -** library seems to be compiled with pthread support. This +** library seems to be compiled with nativethread support. This ** combination may cause frequent hang or segmentation fault ** errors when Ruby/Tk is working. We recommend that you NEVER -** create the library with such a combination of pthread support. +** create the library with such a combination of nativethread support. ** ** Please recompile Ruby with the "--enable-pthread" configure option ** or recompile Tcl/Tk with the "--disable-threads" configure option. @@ -397,44 +1079,135 @@ EOF end end -tclver, tkver = check_tcltk_version(tcltk_version) +############################################################## +# main +############################################################## +# check header files +have_func("ruby_native_thread_p", "ruby.h") +have_func("rb_errinfo", "ruby.h") +have_func("rb_safe_level", "ruby.h") +have_func("rb_hash_lookup", "ruby.h") +have_func("rb_proc_new", "ruby.h") +have_func("rb_obj_untrust", "ruby.h") +have_func("rb_obj_taint", "ruby.h") +have_func("rb_set_safe_level_force", "ruby.h") -if ( tcltk_framework || - ( find_tcltk_header(tclver, tkver) && - ( !use_X || find_X11(x11_ldir2, x11_ldir) ) && - find_tcl(tcllib, stubs, tclver, *tcl_ldir_list) && - find_tk(tklib, stubs, tkver, *tk_ldir_list) ) ) - $CPPFLAGS += ' -DUSE_TCL_STUBS -DUSE_TK_STUBS' if stubs - $CPPFLAGS += ' -D_WIN32' if /cygwin/ =~ RUBY_PLATFORM +have_struct_member("struct RArray", "ptr", "ruby.h") +have_struct_member("struct RArray", "len", "ruby.h") - if tcltk_framework - if tcl_framework_header - $CPPFLAGS += " -I#{tcl_framework_header}" - else - $CPPFLAGS += " -I#{tcltk_framework}/Tcl.framework/Headers" - end +# check libraries +unless is_win32? + have_library("nsl", "t_open") + have_library("socket", "socket") + have_library("dl", "dlopen") + have_library("m", "log") +end +$CPPFLAGS += ' -D_WIN32' if /cygwin/ =~ RUBY_PLATFORM - if tk_framework_header - $CPPFLAGS += " -I#{tk_framework_header}" - else - $CPPFLAGS += " -I#{tcltk_framework}/Tk.framework/Headers" - end +# Does ruby have nativethread ? +TkLib_Config["ruby_with_thread"] = + macro_defined?('HAVE_NATIVETHREAD', '#include "ruby.h"') - $LDFLAGS += ' -framework Tk -framework Tcl' +#--------------------------------------------------- +# check requirement of Tcl/tk version +tcltk_version = with_config("tcltkversion") +tclver, tkver = + TkLib_Config["tcltkversion"] = check_tcltk_version(tcltk_version) +puts("Specified Tcl/Tk version is #{[tclver, tkver]}") if tclver && tkver + +# use ActiveTcl ? +#if activeTcl = with_config("ActiveTcl") +if activeTcl = with_config("ActiveTcl", true) + puts("Use ActiveTcl libraries (if available).") + activeTcl = '/opt/ActiveTcl*/lib' unless activeTcl.kind_of? String +end +TkLib_Config["ActiveTcl"] = activeTcl + +# enable Tcl/Tk stubs? +=begin +if TclConfig_Info['TCL_STUB_LIB_SPEC'] && TkConfig_Info['TK_STUB_LIB_SPEC'] && + !TclConfig_Info['TCL_STUB_LIB_SPEC'].strip.empty? && + !TkConfig_Info['TK_STUB_LIB_SPEC'].strip.empty? + stubs = true + unless (st = enable_config("tcltk-stubs")).nil? + stubs &&= st + end + unless (st = with_config("tcltk-stubs")).nil? + stubs &&= st end +else + stubs = enable_config("tcltk-stubs") || with_config("tcltk-stubs") +end +=end +stubs = enable_config("tcltk-stubs") || with_config("tcltk-stubs") +if (TkLib_Config["tcltk-stubs"] = stubs) + puts("Compile with Tcl/Tk stubs.") + $CPPFLAGS += ' -DUSE_TCL_STUBS -DUSE_TK_STUBS' +end - if stubs or pthread_check - # create Makefile +# get tclConfig.sh/tkConfig.sh +TkLib_Config["tcltk-NG-path"] = [] +tclcfg, tkcfg = get_tclConfig(with_config("tclConfig-file", true), + with_config("tclConfig-dir", true), + with_config("tkConfig-dir", true)) +TclConfig_Info = TkLib_Config["tclConfig_info"] || {} +TkConfig_Info = TkLib_Config["tkConfig_info"] || {} +TclConfig_Info['config_file_path'] = tclcfg +TkConfig_Info['config_file_path'] = tkcfg - # for SUPPORT_STATUS - $INSTALLFILES ||= [] - $INSTALLFILES << ["lib/tkextlib/SUPPORT_STATUS", "$(RUBYLIBDIR)", "lib"] +# check tk_shlib_search_path +check_shlib_search_path(with_config('tk-shlib-search-path')) - have_func("rb_hash_lookup", "ruby.h") +# search X libraries +use_X = search_X_libraries - # create - $defs << %[-DRUBY_VERSION=\\"#{RUBY_VERSION}\\"] - $defs << %[-DRUBY_RELEASE_DATE=\\"#{RUBY_RELEASE_DATE}\\"] - create_makefile("tcltklib") - end +# set TCL_DEFS and TK_DEFS +# $CPPFLAGS += " #{TclConfig_Info['TCL_DEFS']}" +# $CPPFLAGS += " #{TkConfig_Info['TK_DEFS']}" +$CPPFLAGS += collect_tcltk_defs(TclConfig_Info['TCL_DEFS'], TkConfig_Info['TK_DEFS']) + +# MacOS X Frameworks? +if TkLib_Config["tcltk-framework"] + puts("Use MacOS X Frameworks.") + setup_for_macosx_framework +end + +# search Tcl/Tk libraries +tk_idir, tk_ldir = dir_config("tk") if with_config('tk') +tcl_idir, tcl_ldir = dir_config("tcl") if with_config('tcl') + +tk_ldir2 = with_config("tk-lib") +tcl_ldir2 = with_config("tcl-lib") + +tk_ldir_list = [tk_ldir2, tk_ldir] +tcl_ldir_list = [tcl_ldir2, tcl_ldir] + +tklib = with_config("tklib") +tcllib = with_config("tcllib") + +TclConfig_Info['TCL_INCLUDE_SPEC'] = "-I#{tcl_idir.quote}" if tcl_idir +TkConfig_Info['TK_INCLUDE_SPEC'] = "-I#{tk_idir.quote}" if tk_idir + +#--------------------------------------------------- + +if (TkLib_Config["tcltk-framework"] || + ( find_tcltk_header(tclver, tkver) && + find_tcl(tcllib, stubs, tclver, *tcl_ldir_list) && + find_tk(tklib, stubs, tkver, *tk_ldir_list) ) ) && + (stubs || pthread_check()) + # create Makefile + + # for SUPPORT_STATUS + $INSTALLFILES ||= [] + $INSTALLFILES << ["lib/tkextlib/SUPPORT_STATUS", "$(RUBYLIBDIR)", "lib"] + + # create + $defs << %[-DRUBY_VERSION=\\"#{RUBY_VERSION}\\"] + $defs << %[-DRUBY_RELEASE_DATE=\\"#{RUBY_RELEASE_DATE}\\"] + + create_makefile("tcltklib") + + puts "Find Tcl/Tk libraries. Make tcltklib.so which is required by Ruby/Tk." +else + puts "Can't find proper Tcl/Tk libraries. So, can't make tcltklib.so which is required by Ruby/Tk." end -- cgit v1.2.3