From: Mike Hall Date: 2003-08-03T04:21:58+09:00 Subject: Ruby 1.8.0 and Mac OS X and Tcl/Tk 8.4 Aqua (not!) My trials with Ruby and Tcl/Tk on Mac OS X Ruby is 1.8.0 preview 7 Tcl/Tk 8.4 is the recent TclTk-Aqua build for that native OSX Aqua look Mac OS X is 10.2.3 (1) 'configure' wasn't finding Tcl/Tk, so I hacked up an OSX-only version of ext/tcltklib/extconf.rb with hard-coded parameters (which might be OK because of the frameworks) ========= # extconf.rb for tcltklib # HACKED for Mac OS X !!! require 'mkmf' if RUBY_PLATFORM !~ /mswin32|mingw|cygwin|bccwin32/ have_library("nsl", "t_open") have_library("socket", "socket") have_library("dl", "dlopen") have_library("m", "log") end # these are left-over; they mean nothing dir_config("tk") dir_config("tcl") dir_config("X11") tklib = with_config("tklib") tcllib = with_config("tcllib") stubs = enable_config("tcltk_stubs") || with_config("tcltk_stubs") stubs = true # force it $CPPFLAGS += ' -DUSE_TCL_STUBS -DUSE_TK_STUBS' if stubs $CPPFLAGS += ' -D_WIN32' if /cygwin/ =~ RUBY_PLATFORM # these two are needed because #include isn't "framework" friendly $CPPFLAGS += ' -I/Library/Frameworks/Tcl.framework/Headers' $CPPFLAGS += ' -I/Library/Frameworks/Tk.framework/Headers' # tell the compiler where the libraries are $CPPFLAGS += ' -framework Tcl -framework Tk' # let the linker know where the libraries are $LDFLAGS += ' -framework Tcl -framework Tk' create_makefile("tcltklib") ========= You should be thoroughly disgusted with that. However, I was getting tired of running the following, and didn't know how to get the top-level 'make' to add all those options when it configured the extension. Would those options really get carried from the top-level "./configure" all the way down to the extension? ruby extconf.rb \ --with-tcl-include=/Library/Frameworks/Tcl.framework/Headers \ --with-tk-include=/Library/Frameworks/Tk.framework/Headers \ --with-tcl-lib=/Library/Frameworks/Tcl.framework/Tcl \ --with-tk-lib=/Library/Frameworks/Tk.framework/Tk \ --enable-tcltk_stubs --enable-tk_stubs (2) Now, the extension gets configured and compiles OK. Run-time is something else. /usr/lib/ruby/1.6/tk.rb:7:in `require': tcltklib: tcltk_stubs init error(-1) (LoadError) Debug printfs revealed that the stubs interface was looking for a library of 'libtcl8.4.bundle'. That's no-good for several reasons: - the Tcl and Tk libraries do not have a 'bundle' extension (DLEXT) - their names are much different than that I worked around this mismatch by defining two environment variables, thanks to the clear foresight of the author of 'stubs.c'! export RUBY_TCL_DLL=/Library/Frameworks/Tcl.framework/Tcl export RUBY_TK_DLL=/Library/Frameworks/Tk.framework/Tk (3) Now, when loading the 'tcltklib' extension, there was a new error: /usr/lib/ruby/1.6/tk.rb:7:in `require': tcltklib: tcltk_stubs init error(-2) (LoadError) The code showed that it couldn't find 'Tcl_CreateInterp'. After digging around 'dln.c' and the 'dl' library, I noticed a routine called 'dlsym_auto_underscore'. In the '#define' for DLSYM I used it instead of 'dlsym'. It seems to work, since the extension now loads without complaint. (4) So, I run 'demo/lines1.rb', and a big window comes up, with the translucent blue button in the Aqua style that says 'Draw'. Looks good, but there are a few problems: - every click in the window gives: "SetFrontProcess failed, -606" - the window cannot be dragged - the window cannot be closed, neither from the title bar, nor with a ^ or ^\ from the shell (a 'kill' from another window works OK, though) (5) According to some Apple documents, the correct macros to detect Mac OS X are both __DARWIN__ and __APPLE__. In some places (dln.c) I see NeXT and __APPLE__, or else it assumes OPENSTEP. I doubt that's a problem, but it had me looking cross-eyed at it for a long time! :-) FWIW, the top-level 'configure' generates: HAVE_LIBDL, HAVE_DLOPEN, and a DLEXT of ".bundle" So, I hope all this rambling will help someone else figure out what's going on.