############################################################## # extconf.rb for tcltklib # release date: 2010-05-31 ############################################################## require 'mkmf' 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 7.6 4.2] # %w[8.7 8.6 8.5 8.4 8.3 8.2 8.1 8.0] %w[8.7 8.6 8.5 8.4 8.0] # to shorten search steps ############################################################## # use old extconf.rb ? ############################################################## if with_config('tk-old-extconf') require File.join(File.dirname(__FILE__), 'old-extconf.rb') exit end ############################################################## # check configs ############################################################## $cleanfiles << 'config_list' config_list_file = 'config_list' config_list_file_source = File.join(File.dirname(__FILE__),'config_list.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 current_configs = {'with'=>{}, 'enable'=>{}} # 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 } # 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 } 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 } # 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 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("*.#{CONFIG['DLEXT']}", File::FNM_CASEFOLD)) File.delete(*Dir.glob("*.#{$OBJEXT}", File::FNM_CASEFOLD)) File.delete('Makefile') rescue nil else makefile = '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.kind_of? String version = version.strip tclver = version.dup tkver = version.dup 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 dot = ! minor_dot.empty? if plvl_dot.empty? && ! plvl.empty? minor << plvl end elsif version =~ /^(\d)(\.?)(\d?)(.*)$/ major = $1; minor_dot = $2; minor = $3; ext = $4 dot = ! minor_dot.empty? else # unknown -> believe user return [tclver, tkver] end # check Tcl7.6 / Tk4.2 ? if major == "7" # Tcl7.6 ( not support Tclversion < 7.6 ) # Tk4.2 tkver = "4" + ((dot)? ".": "") + ((minor.empty)? "": "2") + ext elsif major == "4" # Tk4.2 ( not support Tkversion < 4.2 ) # Tcl7.6 tclver = "7" + ((dot)? ".": "") + ((minor.empty)? "": "6") + ext end [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_head << TkLib_Config["ActiveTcl"] path_head.concat Dir.glob(TkLib_Config["ActiveTcl"], File::FNM_CASEFOLD).sort.reverse # path_dirs.concat Dir.glob(File.join(TkLib_Config["ActiveTcl"], 'lib'), File::FNM_CASEFOLD).sort.reverse end if CROSS_COMPILING elsif 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*.*", File::FNM_CASEFOLD).empty? dirnames = [] if TkLib_Config["ActiveTcl"] dirnames.concat ["ActiveTcl"] end dirnames.concat ["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_]*", File::FNM_CASEFOLD).empty? } } end unless TkLib_Config["space-on-tk-libpath"] path_head.delete_if{|path| path =~ / /} path_dirs.delete_if{|path| path =~ / /} 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.reverse! unless TkLib_Config["ActiveTcl"] # system has higher priority 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 get_tclConfig_dirs config_dir = [] if CROSS_COMPILING elsif is_win32? if TkLib_Config["ActiveTcl"] dirs = [] if TkLib_Config["ActiveTcl"].kind_of?(String) dirs << File.join(TkLib_Config["ActiveTcl"], 'lib') end dirs.concat [ "c:/ActiveTcl*/lib", "c:/Tcl*/lib", "c:/Program Files/ActiveTcl*/lib", "c:/Program Files/Tcl*/lib", "/ActiveTcl*/lib", "/Tcl*/lib", "/Program Files/ActiveTcl*/lib", "/Program Files/Tcl*/lib" ] else dirs = [ "c:/Tcl*/lib", "c:/Program Files/Tcl*/lib", "/Tcl*/lib", "/Program Files/Tcl*/lib" ] end dirs.collect{|d| Dir.glob(d, File::FNM_CASEFOLD)}.flatten! dirs |= dirs exeext = RbConfig::CONFIG['EXEEXT'] ENV['PATH'].split(File::PATH_SEPARATOR).each{|dir| dir.tr!(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR next if Dir.glob(File.join(dir, "{tclsh,wish}*#{exeext}"), File::FNM_CASEFOLD).empty? dirs << File.expand_path(File.join(dir, '..', 'lib')) dirs << dir # dirs << File.expand_path(File.join(dir, '..')) } unless TkLib_Config["space-on-tk-libpath"] dirs.delete_if{|path| path =~ / /} end config_dir.concat(dirs.zip(dirs)) else if framework = find_macosx_framework() config_dir.unshift(framework) end if activeTcl = TkLib_Config['ActiveTcl'] # check latest version at first if is_macosx? base = File.expand_path(activeTcl) config_dir << [ File.join(base, 'Tcl.framework'), File.join(base, 'Tk.framework') ] config_dir << [ File.join(base, 'Tcl.framework', 'Versions', 'Current'), File.join(base, 'Tk.framework', 'Versions', 'Current') ] Dir.glob(File.join(base, 'Tcl.framework', 'Versions', '*')).sort.reverse.each{|dir| next if dir =~ /Current/ config_dir << [dir, dir.gsub(/Tcl/, 'Tk')] } else config_dir.concat(Dir.glob(File.join(activeTcl, 'lib'), File::FNM_CASEFOLD).sort.reverse) end 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,tcl,tk}[87]*/lib', File::FNM_CASEFOLD) Dir.glob(dir + '/{tcltk,tcl,tk}[87]*', File::FNM_CASEFOLD) Dir.glob(dir + '/{tcltk,tcl,tk}/lib', File::FNM_CASEFOLD) Dir.glob(dir + '/{tcltk,tcl,tk}', File::FNM_CASEFOLD) }.flatten! exeext = RbConfig::CONFIG['EXEEXT'] ENV['PATH'].split(File::PATH_SEPARATOR).each{|dir| dir.tr!(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR next if Dir.glob(File.join(dir, "{tclsh,wish}*#{exeext}"), File::FNM_CASEFOLD).empty? config_dir << File.expand_path(File.join(dir, '..', 'lib')) } # for MacOS X paths = [ #"~/Library/Tcl", "/Library/Tcl", "/Network/Library/Tcl", "/System/Library/Tcl" ] paths.reverse! unless TkLib_Config["ActiveTcl"] paths.each{|path| config_dir << path config_dir.concat(Dir.glob(File.join(path, '{tcl,tk}*'), File::FNM_CASEFOLD).sort.reverse.find_all{|d| File.directory?(d)}) } paths = [ #"~/Library/Frameworks", "/Library/Frameworks", "/Network/Library/Frameworks", "/System/Library/Frameworks" ] paths.reverse! unless TkLib_Config["ActiveTcl"] paths.each{|framework| base = File.expand_path(framework) config_dir << [ File.join(base, 'Tcl.framework'), File.join(base, 'Tk.framework') ] config_dir << [ File.join(base, 'Tcl.framework', 'Versions', 'Current'), File.join(base, 'Tk.framework', 'Versions', 'Current') ] Dir.glob(File.join(base, 'Tcl.framework', 'Versions', '*')).sort.reverse.each{|dir| next if dir =~ /Current/ config_dir << [dir, dir.gsub(/Tcl/, 'Tk')] } } end config_dir end def libcheck_for_tclConfig(dir, tclconf, tkconf) tcllib_ok = tklib_ok = false if TkLib_Config["tcltk-stubs"] stub = "stub" tclfunc = "Tcl_InitStubs" tkfunc = "Tk_InitStubs" else stub = "" tclfunc = "Tcl_FindExecutable" tkfunc = "Tk_Init" end libpath = $LIBPATH tcllibs = nil begin tcllib_ok ||= Dir.glob(File.join(dir, "*tcl#{stub}#{tclconf['TCL_MAJOR_VERSION']}{.,}#{tclconf['TCL_MINOR_VERSION']}*.*"), File::FNM_CASEFOLD).find{|file| if file =~ /^.*(tcl#{stub}#{tclconf['TCL_MAJOR_VERSION']}(\.|)#{tclconf['TCL_MINOR_VERSION']}.*)\.[^.]*$/ #puts "check #{file} #{$1} #{tclfunc} #{dir}" #find_library($1, tclfunc, dir) tcllibs = append_library($libs, $1) $LIBPATH = libpath | [dir] try_func(tclfunc, tcllibs) end } tklib_ok ||= Dir.glob(File.join(dir, "*tk#{stub}#{tkconf['TK_MAJOR_VERSION']}{.,}#{tkconf['TK_MINOR_VERSION']}*.*"), File::FNM_CASEFOLD).find{|file| if file =~ /^.*(tk#{stub}#{tkconf['TK_MAJOR_VERSION']}(\.|)#{tkconf['TK_MINOR_VERSION']}.*)\.[^.]*$/ #puts "check #{file} #{$1} #{tkfunc} #{dir}" # find_library($1, tkfunc, dir) tklibs = append_library(tcllibs, $1) $LIBPATH = libpath | [dir] try_func(tkfunc, tklibs) end } ensure $LIBPATH = libpath end [tcllib_ok, tklib_ok] end def search_tclConfig(*paths) # libdir list or [tcl-libdir|file, tk-libdir|file] TkLib_Config["tclConfig_paths"] = [] paths.compact! if paths.empty? config_dir = get_tclConfig_dirs else # fixed tclConfig config_dir = [] paths.each{|path| if path.kind_of?(Array) config_dir << path else dirs = Dir.glob(path, File::FNM_CASEFOLD) config_dir.concat(dirs.zip(dirs)) end } end tclver, tkver = TkLib_Config['tcltkversion'] conf = nil config_dir.uniq! 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(".") # progress # print("check #{dir} ==>"); if dir.kind_of? Array tcldir, tkdir = dir else tcldir = tkdir = dir end tails = ['Config-shared.sh', 'config-shared.sh', 'Config.sh', 'config.sh'] if File.file?(tcldir) tclcfg_files = [tcldir] * tails.length else tclcfg_files = tails.map{|f| File.join(tcldir, 'tcl' << f)} end if File.file?(tkdir) tkcfg_files = [tkdir] * tails.length else tkcfg_files = tails.map{|f| File.join(tkdir, 'tk' << f)} end tclcfg_files.zip(tkcfg_files).uniq.each{|tclpath, tkpath| 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']}/ # nativethread check if !TkLib_Config["ruby_with_thread"] && tclconf['TCL_THREADS'] == '1' puts "\nWARNING: found #{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 # find tclConfig.sh & tkConfig.sh conf = [tclconf, tkconf] unless conf # check Tcl library if is_macosx? && TkLib_Config["tcltk-framework"] # if use framework, not check (believe it is installed properly) tcllib_ok = tklib_ok = true else tcllib_ok, tklib_ok = libcheck_for_tclConfig(File.dirname(tclpath), tclconf, tkconf) =begin tcllib_ok = tklib_ok = false if TkLib_Config["tcltk-stubs"] stub = "stub" tclfunc = "Tcl_InitStubs" tkfunc = "Tk_InitStubs" else stub = "" tclfunc = "Tcl_FindExecutable" tkfunc = "Tk_Init" end dir = File.dirname(tclpath) libpath = $LIBPATH tcllibs = nil begin tcllib_ok ||= Dir.glob(File.join(dir, "*tcl#{stub}#{tclconf['TCL_MAJOR_VERSION']}{.,}#{tclconf['TCL_MINOR_VERSION']}*.*"), File::FNM_CASEFOLD).find{|file| if file =~ /^.*(tcl#{stub}#{tclconf['TCL_MAJOR_VERSION']}(\.|)#{tclconf['TCL_MINOR_VERSION']}.*)\.[^.]*$/ #puts "check #{file} #{$1} #{tclfunc} #{dir}" #find_library($1, tclfunc, dir) tcllibs = append_library($libs, $1) $LIBPATH = libpath | [dir] try_func(tclfunc, tcllibs) end } tklib_ok ||= Dir.glob(File.join(dir, "*tk#{stub}#{tkconf['TK_MAJOR_VERSION']}{.,}#{tkconf['TK_MINOR_VERSION']}*.*"), File::FNM_CASEFOLD).find{|file| if file =~ /^.*(tk#{stub}#{tkconf['TK_MAJOR_VERSION']}(\.|)#{tkconf['TK_MINOR_VERSION']}.*)\.[^.]*$/ #puts "check #{file} #{$1} #{tkfunc} #{dir}" # find_library($1, tkfunc, dir) tklibs = append_library(tcllibs, $1) $LIBPATH = libpath | [dir] try_func(tkfunc, tklibs) end } ensure $LIBPATH = libpath end =end end unless tcllib_ok && tklib_ok puts "\nWARNING: found #{tclpath.inspect}, but cannot find valid Tcl/Tk libraries on the same directory. So, ignore it." TkLib_Config["tcltk-NG-path"] << File.dirname(tclpath) next end #return [tclpath, tkpath] # print(" #{[tclpath, tkpath].inspect}"); TkLib_Config["tclConfig_paths"] << [tclpath, tkpath] } # print("\n"); } if is_macosx? && TkLib_Config["tcltk-stubs"] CONFIG['LDSHARED'] << " -Xlinker -bind_at_load" if config_string('LDSHAREDXX') config_string('LDSHAREDXX') << " -Xlinker -bind_at_load" end end 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, tkConfig_file, tclConfig_dir, tkConfig_dir) use_tclConfig = (tclConfig_file != false) && (tkConfig_file != false) && (tclConfig_dir != false) && (tkConfig_dir != false) unless use_tclConfig puts("Don't use [tclConfig.sh, tkConfig.sh]") return [nil, nil] end tclConfig_file = nil unless tclConfig_file.kind_of? String tkConfig_file = nil unless tkConfig_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 unless tkConfig_dir if tkConfig_file tkConfig_dir = File.dirname(tkConfig_file) elsif tclConfig_dir tkConfig_dir = tclConfig_dir end end tkConfig_dir ||= tclConfig_dir TkLib_Config["tclConfig-file"] = tclConfig_file TkLib_Config["tkConfig-file"] = tkConfig_file TkLib_Config["tclConfig-dir"] = tclConfig_dir TkLib_Config["tkConfig-dir"] = tkConfig_dir print("Search tclConfig.sh", (tclConfig_dir)? " (in #{tclConfig_dir})": "", " and tkConfig.sh", (tkConfig_dir)? " (in #{tkConfig_dir})": "", ".") if tclConfig_dir tclConfig, tkConfig = search_tclConfig([ ((tclConfig_file)? tclConfig_file: tclConfig_dir), ((tkConfig_file)? tkConfig_file: tkConfig_dir) ]) else tclConfig, tkConfig = search_tclConfig() end print("\n") # TclConfig_Info = TkLib_Config["tclConfig_info"] # TkConfig_Info = TkLib_Config["tkConfig_info"] if tclConfig && tkConfig dirs = TkLib_Config["tclConfig_paths"].map{|tclpath, tkpath| File.dirname(tclpath) } dirs |= dirs puts("Valid tclConfig.sh and tkConfig.sh are found in #{dirs.inspect}") 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 [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"], File::FNM_CASEFOLD).sort.reverse #end if TkLib_Config["ActiveTcl"].kind_of?(String) # glob path path_list.concat Dir.glob(TkLib_Config["ActiveTcl"], File::FNM_CASEFOLD).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, File::FNM_CASEFOLD).find{|dir| dir == head} dirs << head + "/lib" end if !Dir.glob(head + "-*", File::FNM_CASEFOLD).empty? dirs << head + "-#{ver}/lib" if !Dir.glob(head + "-[89].*", File::FNM_CASEFOLD).empty? dirs << head + "-#{ver.delete('.')}/lib" if !Dir.glob(head + "-[89][0-9]*", File::FNM_CASEFOLD).empty? end if !Dir.glob(head + "[_-]*", File::FNM_CASEFOLD).empty? dirs << head + "_#{ver}/lib" if !Dir.glob(head + "_[89].*", File::FNM_CASEFOLD).empty? dirs << head + "-#{ver}/lib" if !Dir.glob(head + "-[89].*", File::FNM_CASEFOLD).empty? dirs << head + "_#{ver.delete('.')}/lib" if !Dir.glob(head + "_[89][0-9]*", File::FNM_CASEFOLD).empty? dirs << head + "-#{ver.delete('.')}/lib" if !Dir.glob(head + "-[89][0-9]*", File::FNM_CASEFOLD).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.map!{|path| path.strip} if !CROSS_COMPILING and (is_win32? || is_macosx?) # exist-dir only path_list.delete_if{|path| Dir.glob(File.join(path, "*.{a,so,dll,lib}")).empty?} end # keep paths for searching dynamic libs $LIBPATH |= path_list end def search_vers_on_path(vers, path, *heads) if enable_config("shared") == false exts = CONFIG['LIBEXT'] + ',' + CONFIG['DLEXT'] else exts = CONFIG['DLEXT'] + ',' + CONFIG['LIBEXT'] end exts << ",dll,lib" if is_win32? exts << ",bundle,dylib" if is_macosx? || /nextstep|openstep|rhapsody/ =~ RUBY_PLATFORM files = Dir.glob(File.join(path, "*{#{heads.join(',')}}*.{#{exts}}"), File::FNM_CASEFOLD) vers.find_all{|ver| files.find{|f| f =~ /(#{ver}|#{ver.delete('.')})/} } end def find_tcl(tcllib, stubs, version, *opt_paths) print "Search Tcl library" if stubs func = "Tcl_InitStubs" lib = "tclstub" else func = "Tcl_FindExecutable" lib = "tcl" end if version && ! version.empty? versions = [version] else versions = TkLib_Config['search_versions'] end 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)} unless CROSS_COMPILING if TkLib_Config["ActiveTcl"].kind_of?(String) # glob path default_paths.concat Dir.glob(TkLib_Config["ActiveTcl"]).sort.reverse.map{|d| d << "/lib"} end if !CROSS_COMPILING and is_win32? default_paths.concat [ "c:/Tcl/lib", "c:/Program Files/Tcl/lib", "/Tcl/lib", "/Program Files/Tcl/lib" ].find_all{|dir| File.directory?(dir)} end unless TkLib_Config["space-on-tk-libpath"] default_paths.delete_if{|path| path =~ / /} end if (paths = opt_paths.compact).empty? unless TclConfig_Info['config_file_path'] paths = check_NG_path(default_paths) else # 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? if stubs if TclConfig_Info['TCL_SUPPORTS_STUBS'] == '0' || TclConfig_Info['TCL_STUB_LIB_SPEC'].strip.empty? print(".\n") # progress 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. *** unless is_win32? # ignore tclConfig on Windows # $LDFLAGS << ' ' << TclConfig_Info['TCL_LIBS'] # $DLDFLAGS << ' ' << TclConfig_Info['TCL_LIBS'] $LDFLAGS << ' ' << TclConfig_Info['TCL_STUB_LIB_SPEC'] end end else #*** Probably, TCL_LIBS is a subset of TK_LIBS. *** unless is_win32? # ignore tclConfig on Windows # $LDFLAGS << ' ' << TclConfig_Info['TCL_LIBS'] # $DLDFLAGS << ' ' << TclConfig_Info['TCL_LIBS'] $LDFLAGS << ' ' << TclConfig_Info['TCL_LIB_SPEC'] end end paths = [File.dirname(TclConfig_Info['config_file_path'])] versions = [TclConfig_Info['TCL_VERSION']] end end ret = paths.map{|path| if tcllib print(".") [path, find_library(tcllib, func, path)] else st = search_vers_on_path(versions, path, lib, 'tcl').find{|ver| (print(".");find_library("#{lib}#{ver}", func, path)) or (print(".");find_library("#{lib}#{ver.delete('.')}", func, path)) or (print(".");find_library("#{lib}#{ver}g", func, path)) or (print(".");find_library("#{lib}#{ver.delete('.')}g", func, path)) or (print(".");find_library("tcl#{ver}", func, path)) or (print(".");find_library("tcl#{ver.delete('.')}", func, path)) or (print(".");find_library("tcl#{ver}g", func, path)) or (print(".");find_library("tcl#{ver.delete('.')}g", func, path)) } || (!version && (print(".");find_library(lib, func, path))) [path, st] end } print("\n") # progress ret 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) print "Search Tk library" if stubs func = "Tk_InitStubs" lib = "tkstub" else func = "Tk_Init" lib = "tk" end if version && ! version.empty? versions = [version] else versions = TkLib_Config['search_versions'] end 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)} unless CROSS_COMPILING if !CROSS_COMPILING and is_win32? default_paths.concat [ "c:/Tcl/lib", "c:/Program Files/Tcl/lib", "/Tcl/lib", "/Program Files/Tcl/lib" ].find_all{|dir| File.directory?(dir)} end unless TkLib_Config["space-on-tk-libpath"] default_paths.delete_if{|path| path =~ / /} end if (paths = opt_paths.compact).empty? unless TkConfig_Info['config_file_path'] paths = check_NG_path(default_paths) else # 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? if stubs if TkConfig_Info['TK_STUB_LIB_SPEC'].strip.empty? print(".\n") # progress puts "#{TkConfig_Info['config_file_path']} tells us that your Tcl/Tk library doesn't support stub." return false else unless is_win32? # ignore tclConfig on Windows # $LDFLAGS << ' ' << parse_TK_LIBS(TkConfig_Info['TK_LIBS']) $LDFLAGS << ' ' << TkConfig_Info['TK_LIBS'] # $DLDFLAGS << ' ' << parse_TK_LIBS(TkConfig_Info['TK_LIBS']) $LDFLAGS << ' ' << TkConfig_Info['TK_STUB_LIB_SPEC'] end end else unless is_win32? # ignore tclConfig on Windows # $LDFLAGS << ' ' << parse_TK_LIBS(TkConfig_Info['TK_LIBS']) $LDFLAGS << ' ' << TkConfig_Info['TK_LIBS'] unless is_win32? # $DLDFLAGS << ' ' << parse_TK_LIBS(TkConfig_Info['TK_LIBS']) $LDFLAGS << ' ' << TkConfig_Info['TK_LIB_SPEC'] unless is_win32? end end paths = [File.dirname(TkConfig_Info['config_file_path'])] versions = [TkConfig_Info['TK_VERSION']] end end ret = paths.map{|path| if tklib print(".") [path, find_library(tklib, func, path)] else st = search_vers_on_path(versions, path, lib, 'tk').find{|ver| (print(".");find_library("#{lib}#{ver}", func, path)) or (print(".");find_library("#{lib}#{ver.delete('.')}", func, path)) or (print(".");find_library("#{lib}#{ver}g", func, path)) or (print(".");find_library("#{lib}#{ver.delete('.')}g", func, path)) or (print(".");find_library("tk#{ver}", func, path)) or (print(".");find_library("tk#{ver.delete('.')}", func, path)) or (print(".");find_library("tk#{ver}g", func, path)) or (print(".");find_library("tk#{ver.delete('.')}g", func, path)) } || (!version && (print(".");find_library(lib, func, path))) [path, st] end } print("\n") # progress ret end def find_tcltk_library(tcllib, tklib, stubs, tclversion, tkversion, tcl_opt_paths, tk_opt_paths) ret = find_tcl(tcllib, stubs, tclversion, *tcl_opt_paths) unless ret && ret.find{|path, val| val} puts("Warning:: cannot find Tcl library. tcltklib will not be compiled (tcltklib is disabled on your Ruby == Ruby/Tk will not work). Please check configure options.") return false end ret = find_tk(tklib, stubs, tkversion, *tk_opt_paths) unless ret && ret.find{|path, val| val} puts("Warning:: cannot find Tk library. tcltklib will not be compiled (tcltklib is disabled on your Ruby == Ruby/Tk will not work). Please check configure options.") return false end true end def find_tcltk_header(tclver, tkver) 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)} if !CROSS_COMPILING && is_win32? base_dir.concat [ "c:/Tcl/include", "c:/Program Files/Tcl/include", "/Tcl/include", "/Program Files/Tcl/include" ].find_all{|dir| File.directory?(dir)} end unless TkLib_Config["space-on-tk-libpath"] base_dir.delete_if{|path| path =~ / /} end if TclConfig_Info['TCL_INCLUDE_SPEC'] && have_tcl_h = try_cpp('#include ', 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 = TkLib_Config['search_versions'] end paths = base_dir.dup 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 if TkConfig_Info['TK_INCLUDE_SPEC'] && have_tk_h = try_cpp('#include ', TkConfig_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 = TkLib_Config['search_versions'] end paths = base_dir.dup 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(tclver, tkver) # use framework, but no tclConfig.sh unless $LDFLAGS.include?('-framework') $LDFLAGS << ' -framework Tk -framework Tcl' end if TkLib_Config["tcl-framework-header"] TclConfig_Info['TCL_INCLUDE_SPEC'] << "-I#{TkLib_Config["tcl-framework-header"].quote} " else TclConfig_Info['TCL_INCLUDE_SPEC'] = "" tcl_base = File.join(TkLib_Config["tcltk-framework"], 'Tcl.framework') if tclver TclConfig_Info['TCL_INCLUDE_SPEC'] << "-I#{File.join(tcl_base, 'Versions', tclver, 'Headers').quote} " end TclConfig_Info['TCL_INCLUDE_SPEC'] << File.join(tcl_base, 'Headers') unless tclver dir = Dir.glob(File.join(tcl_base, 'Versions', '*', 'Headers'), File::FNM_CASEFOLD).sort.reverse[0] TclConfig_Info['TCL_INCLUDE_SPEC'] << "-I#{dir.quote} " if dir end end if TkLib_Config["tk-framework-header"] TkConfig_Info['TK_INCLUDE_SPEC'] = "-I#{TkLib_Config["tk-framework-header"].quote} " else TkConfig_Info['TK_INCLUDE_SPEC'] = "" tk_base = File.join(TkLib_Config["tcltk-framework"], 'Tk.framework') if tkver TkConfig_Info['TK_INCLUDE_SPEC'] << "-I#{File.join(tk_base, 'Versions', tkver, 'Headers').quote} " end TkConfig_Info['TK_INCLUDE_SPEC'] << File.join(tk_base, 'Headers') unless tkver dir = Dir.glob(File.join(tk_base, 'Versions', '*', 'Headers'), File::FNM_CASEFOLD).sort.reverse[0] TkConfig_Info['TK_INCLUDE_SPEC'] << "-I#{dir.quote} " if dir end end end def find_X11(*opt_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('/'), File::FNM_CASEFOLD))} defaults.compact.each{|path| paths.concat(Dir.glob(path.strip.chomp('/'), File::FNM_CASEFOLD))} 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.") end 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?) use_X = with_config("X11", true) else #use_X = false || with_config("X11", false) use_X = with_config("X11", false) end else # depend on configure options use_X = with_config("X11", !(is_win32? || TkLib_Config["tcltk-framework"])) end if use_X puts("Use X11 libraries.") x11_idir, x11_ldir = dir_config("X11") x11_ldir2 = with_config("X11-lib") unless find_X11(x11_ldir2, x11_ldir) puts("Can't find X11 libraries. So, can't make tcltklib.so which is required by Ruby/Tk.") exit end if TkConfig_Info['TK_XINCLUDES'] && !TkConfig_Info['TK_XINCLUDES'].strip.empty? $INCFLAGS << " " << TkConfig_Info['TK_XINCLUDES'].strip end end use_X end def pthread_check() tcl_major_ver = nil tcl_minor_ver = nil # Is tcl-thread given by user ? case enable_config("tcl-thread") when true tcl_enable_thread = true when false tcl_enable_thread = false else tcl_enable_thread = nil end if TclConfig_Info['config_file_path'] if tcl_enable_thread == true puts("Warning: definiton of tclConfig.sh is ignored, because --enable-tcl-thread option is given.") elsif tcl_enable_thread == false 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 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_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 tclConfig = false end end end 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); }") rescue Exception # cannot try_run. Is CROSS-COMPILE environment? puts(%Q'\ ***************************************************************************** ** ** NATIVETHREAD SUPPORT CHECK WARNING: ** ** 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. ** ***************************************************************************** ') return true end end if tcl_enable_thread == nil # tcl-thread is unknown if try_run(< int main() { Tcl_Interp *ip; ip = Tcl_CreateInterp(); exit((Tcl_Eval(ip, "set tcl_platform(threaded)") == TCL_OK)? 0: 1); } EOF tcl_enable_thread = true elsif try_run(< static Tcl_ThreadDataKey dataKey; int main() { exit((Tcl_GetThreadData(&dataKey, 1) == dataKey)? 1: 0); } EOF tcl_enable_thread = true else tcl_enable_thread = false end end # check pthread mode if (TkLib_Config["ruby_with_thread"]) # ruby -> enable unless tcl_enable_thread # ruby -> enable && tcl -> disable puts(%Q'\ ***************************************************************************** ** ** NATIVETHREAD SUPPORT MODE WARNING: ** ** 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 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). ** ***************************************************************************** ') end # ruby -> enable && tcl -> enable/disable if tcl_enable_thread $CPPFLAGS += ' -DWITH_TCL_ENABLE_THREAD=1' else $CPPFLAGS += ' -DWITH_TCL_ENABLE_THREAD=0' end return true else # ruby -> disable if tcl_enable_thread # ruby -> disable && tcl -> enable puts(%Q'\ ***************************************************************************** ** ** NATIVETHREAD SUPPORT MODE ERROR: ** ** Ruby is not compiled with --enable-pthread, but your Tcl/Tk ** 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 nativethread support. ** ** Please recompile Ruby with the "--enable-pthread" configure option ** or recompile Tcl/Tk with the "--disable-threads" configure option. ** ***************************************************************************** ') $CPPFLAGS += ' -DWITH_TCL_ENABLE_THREAD=1' return false else # ruby -> disable && tcl -> disable $CPPFLAGS += ' -DWITH_TCL_ENABLE_THREAD=0' return true end end end ############################################################## # main ############################################################## # check header file print("check functions.") have_func("ruby_native_thread_p", "ruby.h") print(".") # progress have_func("rb_errinfo", "ruby.h") print(".") # progress have_func("rb_safe_level", "ruby.h") print(".") # progress have_func("rb_hash_lookup", "ruby.h") print(".") # progress have_func("rb_proc_new", "ruby.h") print(".") # progress have_func("rb_obj_untrust", "ruby.h") print(".") # progress have_func("rb_obj_taint", "ruby.h") print(".") # progress have_func("rb_set_safe_level_force", "ruby.h") print(".") # progress have_func("rb_sourcefile", "ruby.h") print("\n") # progress print("check struct members.") have_struct_member("struct RArray", "ptr", "ruby.h") print(".") # progress have_struct_member("struct RArray", "len", "ruby.h") print("\n") # progress # check libraries unless is_win32? print("check libraries.") have_library("nsl", "t_open") print(".") # progress have_library("socket", "socket") print(".") # progress have_library("dl", "dlopen") print(".") # progress have_library("m", "log", "math.h") print("\n") # progress end $CPPFLAGS += ' -D_WIN32' if /cygwin/ =~ RUBY_PLATFORM # Does ruby have nativethread ? TkLib_Config["ruby_with_thread"] = macro_defined?('HAVE_NATIVETHREAD', '#include "ruby.h"') #--------------------------------------------------- # 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].inspect}") if tclver&&tkver # use ActiveTcl ? #if activeTcl = with_config("ActiveTcl") if activeTcl = with_config("ActiveTcl", true) puts("Use ActiveTcl libraries (if available).") unless activeTcl.kind_of? String # set default ActiveTcl path if CROSS_COMPILING elsif is_win32? activeTcl = 'c:/Tcl*' elsif is_macosx? activeTcl = '/Library/Frameworks' else activeTcl = '/opt/ActiveTcl*' end end end TkLib_Config["ActiveTcl"] = activeTcl # allow space chars on a libpath TkLib_Config["space-on-tk-libpath"] = enable_config("space-on-tk-libpath", ! is_win32?) # 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 # directory configuration of Tcl/Tk libraries tk_idir, tk_ldir = dir_config("tk") tcl_idir, tcl_ldir = dir_config("tcl") tcl_idir = tk_idir unless tcl_idir tcl_ldir = tk_ldir unless tcl_ldir tk_idir = tcl_idir unless tk_idir tk_ldir = tcl_ldir unless tk_ldir # get tclConfig.sh/tkConfig.sh TkLib_Config["tcltk-NG-path"] = [] tclcfg, tkcfg = get_tclConfig(with_config("tclConfig-file", true), with_config("tkConfig-file", true), with_config("tclConfig-dir", tcl_ldir || true), with_config("tkConfig-dir", tk_ldir || 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 TclConfig_Info['TCL_INCLUDE_SPEC'] = "-I#{tcl_idir.quote}" if tcl_idir TkConfig_Info['TK_INCLUDE_SPEC'] = "-I#{tk_idir.quote}" if tk_idir tk_cfg_dir = File.dirname(TkConfig_Info['config_file_path']) rescue nil tcl_cfg_dir = File.dirname(TclConfig_Info['config_file_path']) rescue nil tk_ldir_list = [tk_ldir, tk_cfg_dir] tcl_ldir_list = [tcl_ldir, tcl_cfg_dir] # check tk_shlib_search_path check_shlib_search_path(with_config('tk-shlib-search-path')) # 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.") if tcl_cfg_dir $INCFLAGS << ' ' << TclConfig_Info['TCL_INCLUDE_SPEC'] $LDFLAGS << ' ' << TclConfig_Info['TCL_LIBS'] if stubs $LDFLAGS << ' ' << TclConfig_Info['TCL_STUB_LIB_SPEC'] else $LDFLAGS << ' ' << TclConfig_Info['TCL_LIB_SPEC'] end end if tk_cfg_dir $INCFLAGS << ' ' << TkConfig_Info['TK_INCLUDE_SPEC'] $LDFLAGS << ' ' << TkConfig_Info['TK_LIBS'] if stubs $LDFLAGS << ' ' << TkConfig_Info['TK_STUB_LIB_SPEC'] else $LDFLAGS << ' ' << TkConfig_Info['TK_LIB_SPEC'] end end setup_for_macosx_framework(tclver, tkver) if tcl_cfg_dir && tk_cfg_dir end # name of Tcl/Tk libraries tklib = with_config("tklib") tcllib = with_config("tcllib") # search X libraries use_X = search_X_libraries #--------------------------------------------------- if (TkLib_Config["tcltk-framework"] || ( find_tcltk_header(tclver, tkver) && find_tcltk_library(tcllib, tklib, stubs, tclver, tkver, tcl_ldir_list, tk_ldir_list) ) ) && (stubs || pthread_check()) # create Makefile # for SUPPORT_STATUS $INSTALLFILES ||= [] $INSTALLFILES << ["lib/tkextlib/SUPPORT_STATUS", "$(RUBYLIBDIR)", "lib"] # create $CPPFLAGS << %[ -DRUBY_VERSION=\\"#{RUBY_VERSION}\\"] $CPPFLAGS << %[ -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