/ext/tk/extconf.rb
Ruby | 2094 lines | 1783 code | 177 blank | 134 comment | 257 complexity | 1d877a5a74d1f44a398e0d3b6298f317 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-3.0, Unlicense, GPL-2.0
Large files files are truncated, but you can click here to view the full file
- ##############################################################
- # extconf.rb for tcltklib
- # release date: 2010-07-30
- ##############################################################
- 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
- %w[8.5 8.4] # At present, Tcl/Tk8.6 is not supported.
- TkLib_Config['unsupported_versions'] =
- %w[8.8 8.7 8.6] # At present, Tcl/Tk8.6 is not supported.
- TkLib_Config['major_nums'] = '87'
- ##############################################################
- TkLib_Config['enable-shared'] = enable_config("shared")
- ##############################################################
- # 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 maybe_64bit?
- /64|universal|s390x/ =~ RUBY_PLATFORM
- end
- def check_tcltk_version(version)
- return [nil, nil] unless version.kind_of? String
- tclver, tkver = version.split(',')
- tclver = tclver.strip
- return [tclver, tkver.strip] if tkver
- dot = major = minor_dot = minor = plvl_dot = plvl = ext = nil
- if tclver =~ /^(\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 tclver =~ /^(\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
- tkver = tclver
- tclver = "7" + ((dot)? ".": "") + ((minor.empty)? "": "6") + ext
- end
- tkver = tclver unless tkver
- [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",
- "c:/Program Files (x86)/ActiveTcl"]
- end
- path_head.concat [
- "c:/Tcl", "c:/Program Files/Tcl", "c:/Program Files (x86)/Tcl",
- "/Tcl", "/Program Files/Tcl", "/Program Files (x86)/Tcl"
- ]
- path_head.uniq!
- #path_head.each{|dir| path_dirs << dir.dup if File.directory? dir}
- path_head.each{|dir| path_dirs << File.expand_path(dir) if File.directory? dir}
- # for MinGW
- ["/usr/local/lib64", "/usr/lib64", "/usr/local/lib", "/usr/lib"].each{|dir|
- #path_dirs << dir if File.directory? dir
- path_dirs << File.expand_path(dir) if File.directory? dir
- }
- path_dirs |= ENV['LIBRARY_PATH'].split(';').find_all{|dir| File.directory? dir}.map{|dir| File.expand_path(dir)} if ENV['LIBRARY_PATH']
- path_dirs |= ENV['PATH'].split(';').find_all{|dir| File.directory? dir}.map{|dir| File.expand_path(dir)} if ENV['PATH']
- 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}/lib64" if maybe_64bit?
- 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.exist?(File.join(dir, "Tcl.framework", "Headers"))
- next unless File.directory?(tcldir = File.join(dir, "Tcl.framework"))
- next unless File.exist?(File.join(dir, "Tk.framework", "Headers"))
- 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}
- 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 from {TCL,Tk}_LIB_FLAG and {TCL,Tk}_LIB_SPEC
- 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 = dirs.collect{|d| Dir.glob(d, File::FNM_CASEFOLD)}.flatten.uniq
- dirs |= ENV['LIBRARY_PATH'].split(';') if ENV['LIBRARY_PATH']
- dirs |= ENV['PATH'].split(';') if ENV['PATH']
- 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 << RbConfig::CONFIG['libdir']
- ((maybe_64bit?)? ['lib64', 'lib']: ['lib']).each{|dir|
- config_dir.concat [
- File.join(RbConfig::CONFIG['exec_prefix'], dir),
- File.join(RbConfig::CONFIG['prefix'], dir),
- "/usr/local/opt/#{dir}", "/usr/local/pkg/#{dir}",
- "/usr/local/share/#{dir}", "/usr/local/#{dir}",
- "/usr/opt/#{dir}", "/usr/pkg/#{dir}", "/usr/share/#{dir}",
- "/usr/contrib/#{dir}", "/usr/#{dir}"
- ]
- }
- 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}[#{TkLib_Config['major_nums']}*/lib",
- File::FNM_CASEFOLD)
- Dir.glob(dir + "/{tcltk,tcl,tk}[#{TkLib_Config['major_nums']}*",
- 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{|frmwk|
- base = File.expand_path(frmwk)
- 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 get_ext_list()
- exts = [CONFIG['DLEXT']]
- exts.concat %w(dll) if is_win32?
- exts.concat %w(bundle dylib) if is_macosx?
- if TkLib_Config["tcltk-stubs"] || TkLib_Config['enable-shared'] == false
- exts.unshift "lib" if is_win32?
- exts.unshift "a"
- exts.unshift CONFIG['LIBEXT']
- end
- if is_win32?
- exts.map!{|ext| [ext.downcase, ext.upcase]}.flatten!
- end
- exts
- end
- def libcheck_for_tclConfig(tcldir, tkdir, 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
- incflags = ($INCFLAGS ||= "").dup
- libpath = ($LIBPATH ||= []).dup
- libs_param = ($libs ||= "").dup
- tcllibs = nil
- mkmf_param = nil
- tclver, tkver = TkLib_Config["tcltkversion"]
- exts = "(" + get_ext_list.join('|') + ")"
- if tclver
- tcl_glob = "*tcl#{stub}#{tclver}.*"
- tcl_regexp = /^.*(tcl#{stub}#{tclver}.*)\.(#{exts}).*$/
- elsif tclconf
- tcl_glob = "*tcl#{stub}#{tclconf['TCL_MAJOR_VERSION']}{.,}#{tclconf['TCL_MINOR_VERSION']}*.*"
- tcl_regexp = /^.*(tcl#{stub}#{tclconf['TCL_MAJOR_VERSION']}(?:\.|)#{tclconf['TCL_MINOR_VERSION']}.*)\.(#{exts}).*$/
- end
- if tkver
- tk_glob = "*tk#{stub}#{tkver}.*"
- tk_regexp = /^.*(tk#{stub}#{tkver}.*)\.(#{exts}).*$/
- elsif tkconf
- tk_glob = "*tk#{stub}#{tkconf['TK_MAJOR_VERSION']}{.,}#{tkconf['TK_MINOR_VERSION']}*.*"
- tk_regexp = /^.*(tk#{stub}#{tkconf['TK_MAJOR_VERSION']}(?:\.|)#{tkconf['TK_MINOR_VERSION']}.*)\.#{exts}.*$/
- end
- tcllib_ok ||= !tclconf || Dir.glob(File.join(tcldir, tcl_glob), File::FNM_CASEFOLD).find{|file|
- if file =~ tcl_regexp
- libname = $1
- ext = $2.downcase
- begin
- $INCFLAGS = incflags.dup << " " << tclconf["TCL_INCLUDE_SPEC"]
- #puts "check #{file} #{$1} #{tclfunc} #{tcldir}"
- #find_library($1, tclfunc, tcldir)
- if (tclconf && tclconf["TCL_SHARED_BUILD"] == "0") ||
- (ext != CONFIG['DLEXT'] && ext == CONFIG['LIBEXT']) || ext == "a"
- # static link
- tcllibs = $libs + " -DSTATIC_BUILD " + file.quote
- # FIX ME: avoid pathname trouble (fail to find) on MinGW.
- # e.g. TCL_INCLUDE_SPEC describes "-I/usr/local/include",
- # but compiler can find "-IC:/msys/1.0/local/include" only.
- $INCFLAGS << " -I" << File.join(File.dirname(File.dirname(file)),"include") if is_win32?
- else
- tcllibs = append_library($libs, libname)
- tcllibs = "#{libpathflag([tcldir])} #{tcllibs}"
- # FIX ME: avoid pathname trouble (fail to find) on MinGW.
- $INCFLAGS << " -I" << File.join(File.dirname(tcldir),"include") if is_win32?
- end
- $LIBPATH = libpath | [tcldir]
- try_func(tclfunc, tcllibs, ["tcl.h"]) ||
- ( try_func(tclfunc, tcllibs << " " << tclconf['TCL_LIBS'], ["tcl.h"]) if tclconf['TCL_LIBS'] )
- ensure
- mkmf_param = {
- 'PATH' => file,
- 'LIBNAME' => libname,
- 'libs' => tcllibs.dup,
- 'INCFLAGS' => $INCFLAGS.dup,
- 'LIBPATH' => $LIBPATH.dup,
- }
- $LIBPATH = libpath.dup
- $libs = libs_param.dup
- end
- end
- }
- tclconf['MKMF_PARAMS'] = mkmf_param if tclconf && tcllib_ok
- tklib_ok ||= !tkconf || Dir.glob(File.join(tkdir, tk_glob), File::FNM_CASEFOLD).find{|file|
- if file =~ tk_regexp
- libname = $1
- ext = $2.downcase
- begin
- #puts "check #{file} #{$1} #{tkfunc} #{tkdir}"
- # find_library($1, tkfunc, tkdir)
- if (tkconf && tkconf["TCL_SHARED_BUILD"] == "0") ||
- (ext != CONFIG['DLEXT'] && ext == CONFIG['LIBEXT']) || ext == "a"
- # static link
- tklibs = " -DSTATIC_BUILD " + file.quote
- # FIX ME: avoid pathname trouble (fail to find) on MinGW.
- $INCFLAGS << " -I" << File.join(File.dirname(File.dirname(file)),"include") if is_win32?
- else
- tklibs = append_library("", libname)
- #tklibs = append_library("", $1)
- tklibs = "#{libpathflag([tkdir])} #{tklibs}"
- # FIX ME: avoid pathname trouble (fail to find) on MinGW.
- $INCFLAGS << " -I" << File.join(File.dirname(tcldir),"include") if is_win32?
- end
- tklibs << " " << tcllibs if tcllibs
- tmp_tklibs = tklibs.dup
- $LIBPATH = libpath | [tkdir]
- try_func(tkfunc, tklibs, ["tcl.h", "tk.h"]) ||
- ( try_func(tkfunc, tklibs << " " << tkconf['TK_LIBS'], ["tcl.h", "tk.h"]) if tkconf['TK_LIBS'] ) ||
- ( try_func(tkfunc, (tklibs = tmp_tklibs.dup) << " " << tkconf['TK_XLIBSW'], ["tcl.h", "tk.h"]) if tkconf['TK_XLIBSW'] ) ||
- ( try_func(tkfunc, tklibs << " " << tkconf['TK_LIBS'], ["tcl.h", "tk.h"]) if tkconf['TK_LIBS'] )
- ensure
- mkmf_param = {
- 'PATH' => file,
- 'LIBNAME' => libname,
- 'libs' => tklibs.dup,
- 'INCFLAGS' => $INCFLAGS.dup,
- 'LIBPATH' => $LIBPATH.dup,
- }
- $LIBPATH = libpath.dup
- $libs = libs_param.dup
- end
- end
- }
- $INCFLAGS = incflags.dup
- tkconf['MKMF_PARAMS'] = mkmf_param if tkconf && tklib_ok
- [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
- elsif paths.length == 1 && !paths[0][0] && !paths[0][1]
- config_dir = get_tclConfig_dirs.map{|dir|
- if dir.kind_of? Array
- [ (paths[0][0] == false)? nil: dir[0],
- (paths[0][1] == false)? nil: dir[1] ]
- else
- [ (paths[0][0] == false)? nil: dir,
- (paths[0][1] == false)? nil: dir ]
- end
- }
- 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']
- if tclver && tclver =~ /^\D*(\d)\.?(\d)?/ # ignore PATCH_LEVEL
- tclver_major = $1
- tclver_minor = $2
- else
- tclver_major = nil
- tclver_minor = nil
- end
- if tkver && tkver =~ /^\D*(\d)\.?(\d)?/ # ignore PATCH_LEVEL
- tkver_major = $1
- tkver_minor = $2
- else
- tkver_major = nil
- tkver_minor = nil
- end
- conf = nil
- progress_flag = false
- config_dir.uniq!
- config_dir.map{|dir|
- if dir.kind_of? Array
- [ (dir[0])? dir[0].strip.chomp('/'): nil,
- (dir[1])? dir[1].strip.chomp('/'): nil ]
- else
- dir.strip.chomp('/')
- end
- }.each{|dir|
- print("."); progress_flag = true # 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 tcldir
- if File.file?(tcldir)
- tclcfg_files = [tcldir] * tails.length
- else
- tclcfg_files = tails.map{|f| File.join(tcldir, 'tcl' << f)}
- end
- else
- tclcfg_files = [nil] * tails.length
- end
- if tkdir
- if File.file?(tkdir)
- tkcfg_files = [tkdir] * tails.length
- else
- tkcfg_files = tails.map{|f| File.join(tkdir, 'tk' << f)}
- end
- else
- tkcfg_files = [nil] * tails.length
- end
- tclcfg_files.zip(tkcfg_files).map{|tclpath, tkpath|
- [ (tclpath && File.exist?(tclpath))? File.expand_path(tclpath): tclpath,
- (tkpath && File.exist?(tkpath))? File.expand_path(tkpath): tkpath ]
- }.uniq.each{|tclpath, tkpath|
- next if tclpath && !File.exist?(tclpath)
- next if tkpath && !File.exist?(tkpath)
- # parse tclConfig.sh/tkConfig.sh
- tclconf = (tclpath)? parse_tclConfig(tclpath): nil
- if tclconf
- if tclver && ((tclver_major && tclver_major != tclconf['TCL_MAJOR_VERSION']) || (tclver_minor && tclver_minor != tclconf['TCL_MINOR_VERSION']))
- print("\n") if progress_flag
- puts "Ignore \"#{tclpath}\" (unmatch with configured version)."
- progress_flag = false
- next
- end
- if TkLib_Config['unsupported_versions'].find{|ver| ver == "#{tclconf['TCL_MAJOR_VERSION']}.#{tclconf['TCL_MINOR_VERSION']}"}
- print("\n") if progress_flag
- puts "Ignore \"#{tclpath}\" (unsupported version of Tcl/Tk)."
- progress_flag = false
- next
- end
- end
- tkconf = (tkpath)? parse_tclConfig(tkpath): nil
- if tkconf
- if tkver && ((tkver_major && tkver_major != tkconf['TK_MAJOR_VERSION']) || (tkver_minor && tkver_minor != tkconf['TK_MINOR_VERSION']))
- print("\n") if progress_flag
- puts "Ignore \"#{tkpath}\" (unmatch with configured version)."
- progress_flag = false
- next
- end
- if TkLib_Config['unsupported_versions'].find{|ver| ver == "#{tkconf['TK_MAJOR_VERSION']}.#{tkconf['TK_MINOR_VERSION']}"}
- print("\n") if progress_flag
- puts "Ignore \"#{tkpath}\" (unsupported version of Tcl/Tk)."
- progress_flag = false
- next
- end
- end
- # nativethread check
- if !TkLib_Config["ruby_with_thread"]
- if tclconf
- if tclconf['TCL_THREADS'] == '1'
- puts "\nWARNING: found #{tclpath.inspect}, but it WITH nativethread-support under ruby WITHOUT nativethread-support. So, ignore it."
- TkLib_Config["tcl-NG-path"] << File.dirname(tclpath)
- next
- end
- else
- puts "\nWARNING: When not refer tclConfig.sh, cannot check native-thread support on Tcl/Tk libraries. Ruby, which is used now, does NOT support native-thread. So, if Tcl/Tk libraries support native-thread, it will NOT work properly."
- end
- 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((tclpath)? File.dirname(tclpath): nil,
- (tkpath)? File.dirname(tkpath): nil,
- tclconf, tkconf)
- end
- unless tcllib_ok && tklib_ok
- unless tcllib_ok
- puts "\nWARNING: found #{tclpath.inspect}, but cannot find valid Tcl library for the tclConfig.sh. So, ignore it."
- TkLib_Config["tcl-NG-path"] << File.dirname(tclpath)
- end
- unless tklib_ok
- puts "\nWARNING: found #{tkpath.inspect}, but cannot find valid Tk library for the tkConfig.sh. So, ignore it."
- TkLib_Config["tk-NG-path"] << File.dirname(tkpath)
- end
- 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 && tclConfig_dir != false
- use_tkConfig = tkConfig_file != false && tkConfig_dir != false
- unless use_tclConfig || use_tkConfig
- 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
- if use_tclConfig && !tclConfig_dir
- if tclConfig_file
- tclConfig_dir = File.dirname(tclConfig_file)
- elsif tkConfig_dir
- tclConfig_dir = tkConfig_dir
- end
- end
- if use_tkConfig && !tkConfig_dir
- if tkConfig_file
- tkConfig_dir = File.dirname(tkConfig_file)
- elsif tclConfig_dir
- tkConfig_dir = tclConfig_dir
- end
- end
- tkConfig_dir ||= tclConfig_dir
- if use_tclConfig
- TkLib_Config["tclConfig-file"] = tclConfig_file
- TkLib_Config["tclConfig-dir"] = tclConfig_dir
- else
- tclConfig_file = false
- tclConfig_dir = false
- end
- if use_tkConfig
- TkLib_Config["tkConfig-file"] = tkConfig_file
- TkLib_Config["tkConfig-dir"] = tkConfig_dir
- else
- tkConfig_file = false
- tkConfig_dir = false
- end
- print ("Don't use tclConfig.sh (specified by configure option).\n") unless use_tclConfig
- print ("Don't use tkConfig.sh (specified by configure option).\n") unless use_tkConfig
- print("Search ")
- print("tclConfig.sh", (tclConfig_dir)? " (in #{tclConfig_dir})": "") if use_tclConfig
- print((use_tclConfig)? " and ": "", "tkConfig.sh", (tkConfig_dir)? " (in #{tkConfig_dir})": "") if use_tkConfig
- print(".")
- if tclConfig_dir || tkConfig_dir || !use_tclConfig || !use_tkConfig
- 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|
- [ (tclpath)? File.dirname(tclpath): nil,
- (tkpath)? File.dirname(tkpath): nil ]
- }
- dirs |= dirs
- puts("Valid [tclConfig.sh, tkConfig.sh] are found in #{dirs.inspect}")
- puts("Use [tclConfig.sh, tkConfig.sh] == #{[tclConfig, tkConfig].inspect}")
- $LIBPATH ||= []
- $LIBPATH |= [File.dirname(tclConfig)] if tclConfig
- $LIBPATH |= [File.dirname(tkConfig)] if 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_tcl_NG_path(path_list)
- path_list.find_all{|path| not TkLib_Config["tcl-NG-path"].include?(path) }
- end
- def check_tk_NG_path(path_list)
- path_list.find_all{|path| not TkLib_Config["tk-NG-path"].include?(path) }
- end
- def check_NG_path(path_list)
- path_list.find_all{|path|
- not (TkLib_Config["tcl-NG-path"].include?(path) &&
- TkLib_Config["tk-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
- path_list.uniq
- end
- def search_vers_on_path(vers, path, *heads)
- exts = get_ext_list.join(',')
- 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)
- if TclConfig_Info['MKMF_PARAMS']
- # already checked existence of tcl library based on tclConfig.sh
- ($INCFLAGS ||= "") << " " << TclConfig_Info['MKMF_PARAMS']['INCFLAGS']
- $LIBPATH ||= []; $LIBPATH |= TclConfig_Info['MKMF_PARAMS']['LIBPATH']
- ($libs ||= "") << " " << TclConfig_Info['MKMF_PARAMS']['libs']
- return [true, nil, nil, nil]
- end
- # else, no available tclConfig.sh on the system
- 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","c:/Program Files (x86)/Tcl/lib",
- "/Tcl/lib","/Program Files/Tcl/lib","/Program Files (x86)/Tcl/lib"
- ].find_all{|dir| File.directory?(dir)}.map{|dir| File.expand_path(dir)}
- # for MinGW
- ["/usr/local/lib64", "/usr/lib64", "/usr/local/lib", "/usr/lib"].each{|dir|
- default_paths << File.expand_path(dir) if File.directory? dir
- }
- default_paths |= ENV['LIBRARY_PATH'].split(';').find_all{|dir| File.directory? dir}.map{|dir| File.expand_path(dir)} if ENV['LIBRARY_PATH']
- default_paths |= ENV['PATH'].split(';').find_all{|dir| File.directory? dir}.map{|dir| File.expand_path(dir)} if ENV['PATH']
- end
- default_paths |= TkLib_Config["checked_shlib_dirs"]
- unless TkLib_Config["space-on-tk-libpath"]
- default_paths.delete_if{|path| path =~ / /}
- end
- if (paths = opt_paths.compact).empty?
- paths = check_tcl_NG_path(default_paths)
- end
- incflags = ($INCFLAGS ||= "").dup
- libpath = ($LIBPATH ||= []).dup
- libs_param = ($libs ||= "").dup
- tcllibs = nil
- exts = "(" + get_ext_list.join('|') + ")"
- paths.map{|path|
- lib_w_sufx = lib
- begin
- $LIBPATH |= [path]
- inc = [File.join(File.dirname(path),"include"), File.dirname(path)]
- inc.each{|f| $INCFLAGS << " -I" << f }
- if tcllib
- print(".")
- if have_library(tcllib, func, ["tcl.h"])
- return [true, path, tcllib, nil, *inc]
- end
- else
- sufx_list = ['', 't', 'g', 's', 'x']
- search_vers_on_path(versions, path, lib, 'tcl').find{|ver|
- dir_enum = Dir.foreach(path)
- no_dot_ver = ver.delete('.')
- libnames = ["#{lib}#{ver}", "#{lib}#{no_dot_ver}"]
- libnames << "tcl#{ver}" << "tcl#{no_dot_ver}" if lib != "tcl"
- libnames.find{|libname|
- sufx_list.find{|sufx|
- print(".")
- dir_enum.map{|fname|
- if fname =~ /^.*(#{libname}.*#{sufx})\.(#{exts}).*$/
- [fname, $1, $2]
- end
- }.compact.find{|fname, lib_w_sufx, ext|
- ext.downcase!
- if (ext != CONFIG['DLEXT'] && ext == CONFIG['LIBEXT']) ||
- ext == "a"
- # static link
- tcllibs = libs_param + " -DSTATIC_BUILD " + fname.quote
- else
- tcllibs = append_library($libs, lib_w_sufx)
- tcllibs = "#{libpathflag([path])} #{tcllibs}"
- end
- if try_func(func, tcllibs, ["tcl.h"])
- return [true, path, nil, tcllibs, *inc]
- end
- }
- }
- }
- }
- if (!version && (print(".");try_func(func, libs_param, ["tcl.h"])))
- return [true, path, lib_w_sufx, nil, *inc]
- end
- end
- ensure
- $LIBPATH = libpath.dup
- $libs = libs_param.dup
- $INCFLAGS = incflags.dup
- end
- }
- print("\n") # progress
- [false, nil, nil, nil]
- 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)
- if TkConfig_Info['MKMF_PARAMS']
- # already checked existence of tcl library based on tkConfig.sh
- ($INCFLAGS ||= "") << " " << TkConfig_Info['MKMF_PARAMS']['INCFLAGS']
- $LIBPATH ||= []; $LIBPATH |= TkConfig_Info['MKMF_PARAMS']['LIBPATH']
- ($libs ||= "") << " " << TkConfig_Info['MKMF_PARAMS']['libs']
- return [true, nil, nil, nil]
- end
- # else, no available tkConfig.sh on the system
- 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","c:/Program Files (x86)/Tcl/lib",
- "/Tcl/lib","/Program Files/Tcl/lib","/Program Files (x86)/Tcl/lib"
- ].find_all{|dir| File.directory?(dir)}
- # for MinGW
- ["/usr/local/lib64", "/usr/lib64", "/usr/local/lib", "/usr/lib"].each{|dir|
- default_paths << File.expand_path(dir) if File.directory? dir
- }
- default_paths |= ENV['LIBRARY_PATH'].split(';').find_all{|dir| File.directory? dir}.map{|dir| File.expand_path(dir)} if ENV['LIBRARY_PATH']
- default_paths |= ENV['PATH'].split(';').find_all{|dir| File.directory? dir}.map{|dir| File.expand_path(dir)} if ENV['PATH']
- end
- default_paths |= TkLib_Config["checked_shlib_dirs"]
- unless TkLib_Config["space-on-tk-libpath"]
- default_paths.delete_if{|path| path =~ / /}
- end
- if (paths = opt_paths.compact).empty?
- paths = check_tk_NG_path(default_paths)
- end
- incflags = ($INCFLAGS ||= "").dup
- libpath = ($LIBPATH ||= []).dup
- libs_param = ($libs ||= "").dup
- tcllibs = nil
- exts = "(" + get_ext_list.join('|') + ")"
- paths.map{|path|
- lib_w_sufx = lib
- begin
- $LIBPATH |= [path]
- inc = [File.join(File.dirname(path),"include"), File.dirname(path)]
- inc.each{|f| $INCFLAGS << " -I" << f }
- if tklib
- print(".")
- if have_library(tklib, func, ["tcl.h", "tk.h"])
- return [true, path, tklib, nil, *inc]
- end
- else
- sufx_list = ['', 't', 'g', 's', 'x']
- search_vers_on_path(versions, path, lib, 'tk').find{|ver|
- dir_enum = Dir.foreach(path)
- no_dot_ver = ver.delete('.')
- libnames = ["#{lib}#{ver}", "#{lib}#{no_dot_ver}"]
- libnames << "tk#{ver}" << "tk#{no_dot_ver}" if lib != "tk"
- libnames.find{|libname|
- sufx_list.find{|sufx|
- print(".")
- dir_enum.map{|fname|
- if fname =~ /^.*(#{libname}.*#{sufx})\.(#{exts}).*$/
- [fname, $1, $2]
- end
- }.compact.find{|fname, lib_w_sufx, ext|
- if (ext != CONFIG['DLEXT'] && ext == CONFIG['LIBEXT']) ||
- ext == "a"
- # static link
- tklibs = libs_param + " -DSTATIC_BUILD " + fname.quote
- else
- tklibs = append_library($libs, lib_w_sufx)
- tklibs = "#{libpathflag([path])} #{tklibs}"
- end
- if try_func(func, tklibs, ["tcl.h", "tk.h"])
- return [true, path, nil, tklibs, *inc]
- end
- }
- }
- }
- }
- if (!version && (print(".");try_func(func, libs_param, ["tcl.h", "tk.h"])))
- return [true, path, lib_w_sufx, nil, *inc]
- end
- end
- ensure
- $LIBPATH = libpath
- $libs = libs_param
- $INCFLAGS = incflags.dup
- end
- }
- print("\n") # progress
- [false, nil, nil, nil]
- end
- def find_tcltk_library(tcllib, tklib, stubs, tclversion, tkversion,
- tcl_opt_paths, tk_opt_paths)
- st,path,lib,libs,*inc = find_tcl(tcllib, stubs, tclversion, *tcl_opt_paths)
- if !st && TkLib_Config['enable-shared'] == nil
- TkLib_Config['enable-shared'] = false
- st,path,lib,libs,*inc = find_tcl(tcllib, stubs, tclversion, *tcl_opt_paths)
- end
- unless st
- puts("Warning:: cannot find Tcl library. tcltklib will not be compiled (tcltklib is disabled on your Ruby. That is, Ruby/Tk will not work). Please check configure options.")
- return false
- else
- ($LIBPATH ||= []; $LIBPATH |= [path]) if path
- $libs = append_library($libs, lib) if lib
- ($libs ||= "") << " " << libs if libs
- $INCFLAGS ||= ""
- inc.each{|f| $INCFLAGS << " -I" << f}
- end
- st,path,lib,libs,*inc = find_tk(tklib, stubs, tkversion, *tk_opt_paths)
- if !st && TkLib_Config['enable-shared'] == nil
- TkLib_Config['enable-shared'] = false
- st,path,lib,libs,*inc = find_tk(tklib, stubs, tkversion, *tk_opt_paths)
- end
- unless st
- puts("Warning:: cannot find Tk library. tcltklib will not be compiled (tcltklib is disabled on your Ruby. That is, Ruby/Tk will not work). Please check configure options.")
- return false
- else
- ($LIBPATH ||= []; $LIBPATH |= [path]) if path
- $libs = append_library($libs, lib) if lib && !lib.empty?
- ($libs ||= "") << " " << libs if libs
- $INCFLAGS ||= ""
- inc.each{|f| $INCFLAGS << " -I" << f}
- 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)}.map{|dir| File.expand_path(dir)}
- if !CROSS_COMPILING && is_win32?
- base_dir.concat [
- "c:/Tcl/include","c:/Program Files/Tcl/include",
- "c:/Program Files (x86)/Tcl/include",
- "/Tcl/include","/Program Files/Tcl/include",
- "/Program Files (x86)/Tcl/include"
- ].find_all{|dir| File.directory?(dir)}.map{|dir| File.expand_path(dir)}
- if ENV['CPATH']
- base_dir |= ENV['CPATH'].split(';').find_all{|dir| File.directory?(dir)}.map{|dir| File.expand_path(dir)}
- end
- end
- base_dir |= TkLib_Config["checked_shlib_dirs"]
- unless TkLib_Config["space-on-tk-libpath"]
- base_dir.delete_if{|path| path =~ / /}
- end
- # tcl.h
- if TclConfig_Info['MKMF_PARAMS']
- # already checked existence of tcl headers based on tclConfig.sh
- have_tcl_h = true
- else
- print "\nSearch tcl.h"
- if enable_config("tcl-h-ver-check", true) &&
- tclver && tclver =~ /^\D*(\d)\.?(\d)/
- major = $1; minor = $2
- else
- major = minor = nil
- end
- print(".") # progress
- if major && minor
- # version check on tcl.h
- version_check = proc {|code|
- code << ("#if TCL_MAJOR_VERSION != #{major} || TCL_MINOR_VERSION != #{minor}\n" \
- "#error VERSION does not match\n" \
- "#endif")
- }
- else
- version_check = nil
- end
- have_tcl_h = have_header('tcl.h', &version_check)
- unless have_tcl_h
- 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 + '/include',
- dir + '/tcl' + ver.delete('.'),
- dir + '/tcl' + ver.delete('.') + '/include'
- ]
- }.flatten)
- }
- paths = paths.map{|dir|
- (File.directory?(dir))? File.expand_path(dir): nil
- }.compact.uniq
- if major || minor
- version_check = proc {|code|
- code << "#if TCL_MAJOR_VERSION != #{major}\n#error MAJOR_VERSION does not match\n#endif\n" if major
- code << "#if TCL_MINOR_VERSION != #{minor}\n#error MINOR_VERSION does not match\n#endif\n" if minor
- code
- }
- else
- version_check = nil
- end
- have_tcl_h = paths.find{|path|
- print(".") # progress
- inc_opt = " -I#{path.quote}"
- if try_header("tcl", inc_opt, &version_check)
- ($INCFLAGS ||= "") << inc_opt
- true
- else
- false
- end
- }
- end
- end
- # tk.h
- if TkConfig_Info['MKMF_PARAMS']
- # already checked existence of tk headers based on tkConfig.sh
- have_tk_h = true
- else
- print "\nSearch tk.h"
- if enable_config("tk-h-ver-check", true) &&
- tkver && tkver =~ /^\D*(\d)\.?(\d)/
- major = $1; minor = $2
- else
- major = minor = nil
- end
- print(".") # progress
- if major && minor
- # version check on tk.h
- version_check = proc {|code|
- code << ("#if TK_MAJOR_VERSION != #{major} || TK_MINOR_VERSION != #{minor}\n" \
- "#error VERSION does not match\n" \
- "#endif")
- }
- else
- version_check = nil
- end
- have_tk_h = have_header('tk.h')
- unless have_tk_h
- 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 + '/include',
- dir + '/tk' + ver.delete('.'),
- dir + '/tk' + ver.delete('.') + '/include'
- ]
- }.flatten)
- }
- paths = paths.map{|dir|
- (File.directory?(dir))? File.expand_path(dir): nil
- }.compact.uniq
- if major || minor
- version_check = proc {|code|
- code << "#if TK_MAJOR_VERSION != #{major}\n#error MAJOR_VERSION does not match\n#endif\n" if major
- code << "#if TK_MINOR_VERSION != #{minor}\n#error MINOR_VERSION does not match\n#endif\n" if minor
- code
- }
- else
- version_check = nil
- end
- have_tk_h = paths.find{|path|
- print(".") # progress
- inc_opt = " -I#{path.quote}"
- if try_header(%w'tcl.h tk.h', inc_opt, &version_check)
- ($INCFLAGS ||= "") << inc_opt
- true
- else
- false
- end
- }
- end
- end
- puts "Can't find \"tcl.h\"." unless have_tcl_h
- puts "Can't find \"tk.h\"." unless have_tk_h
- have_tcl_h && have_tk_h
- end
- def setup_for_macosx_framework(tclver, tkver)
- # use framework, but no tclConfig.sh
- unless $LIBS && $LIBS.include?('-framework')
- ($LIBS ||= "") << ' -framework Tk -framework Tcl'
- end
- if TkLib_Config["tcl-framework-header"]
- TclConfig_Info['TCL_INCLUDE_SPEC'][0,0] =
- " -I#{TkLib_Config["tcl-framework-header"].quote} "
- else
- 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
- …
Large files files are truncated, but you can click here to view the full file