Packages Used |
Active Perl: http://www.activestate.com/ActivePerl/download.htm DCOM: http://www.microsoft.com/com/dcom/dcom1_2/download.asp DMAKE: http://www-personal.umich.edu/~gsar/dmake-4.1-win32.zip WinZip: http://www.winzip.com |
I'm composing this text in Emacs, which is running on my Linux PC. At the same time, I'm developing and testing Perl/Tk code for this article on the PC and another machine running Windows 95. These machines are part of a LAN, so I don't race madly from machine to machine. Instead, I sit in front of my Macintosh and work in several environments simultaneously, thanks to an X11 server and a VNC viewer (Virtual Network Computing, which allows you to see one computer's desktop from another; see http://www.uk.research.att.com/vnc/.
I do this because these days you must be able to interoperate, and I want my Unix Perl/Tk programs to run on Win32 machines. Professionally, it's hard to ignore the millions of PCs running Windows and NT. That fact really hit home while reading about the Navy's new "smart ships" being deployed with systems running NT in an effort to cut costs by reducing personnel.
So, in a departure from the usual format of this column, we'll follow my trials and tribulations as I try to make a simple widget run on both Unix and Windows 95. We'll cover how to fetch and install Perl, Tk, and CPAN modules, what you can do to make your Win32 environment more Unix friendly, and what portability issues might arise.
First, we need a Win32 Perl binary. Gurusamy Sarathy's port has been around over a year and has lots of prebuilt modules, including Tk 4. Times change, however, and there's a newer Perl available (along with lots of modules, including Tk 8) called ActivePerl, which is the Perl we'll use.
The ActivePerl binary is on the Internet, ready to run on Windows 95, Windows 98, and Windows NT. All you need to do is find the web page, download the self extracting archive and double-click to install it. Windows 95 requires that DCOM 1.2 be installed first. Once DCOM is installed, reboot Windows 95. Now fetch ActivePerl; both of these can be found at the URLs in the Packages Used box above.
When the download completes, use Explorer (or the tool of your choice) to figure out where Windows placed the file; the particular version is named APi502e.EXE (Figure 1). (The 502 part of the name means Perl 5.005_02; 507 just became available as this article went to press.)
Figure 1: APi502e.EXE
As you can see, I placed it in my /tmp directory, which I created earlier. I double-click the APi502e icon, and the ActivePerl setup wizard starts. Just accept all the defaults. In particular, let it modify your AUTOEXEC.BAT file and add the Perl bin directory to your path. Then PERL, PERLDOC and PL2BAT (more on PL2BAT later) can be invoked by name in whatever directory you happen to be in. After the install completes you are given a chance to read the release notes, which you should do at least once. When finished, reboot the machine.
Now let's see what we have. Figure 2 is an Explorer window displaying the contents of Perl's bin directory, which is now part of your standard path. The actual Perl executable resides in the directory ...\5.00502\bin\MSWin32-x86-object. The file of particular importance to us is PPM, the Perl Package Manager. We'll run it shortly.
Figure 2: Contents of Perl's bin directory
INSTALLING PERL MODULES
PPM is like the CPAN module, CPAN.pm, which downloads and installs modules from the Comprehensive Perl Archive Network. PPM downloads and installs Win32 modules from the ActivePerl repository. To learn how to use PPM, either run the program and type help, or read the online documentation: bring up the Start menu and select Programs -> ActivePerl -> Online Documentation. Your browser will activate and display an extensive table of contents. Key sections are the Perl Package Manager, the Win32 FAQ, and the documentation on Perl and all the modules on your system (Figure 3).
Figure 3: Welcome to ActivePerl
To install Tk, double-click the PPM icon in the Explorer window. A DOS window similar to Figure 4 appears. As you can see, the interface is very straightforward.
Figure 4: DOS Window to Install TK
By default, package names are case sensitive, so make sure you type install Tk. When you hit <Return>, go get some coffee, because PPM is downloading Tk over the net from ActiveState, and this can take a long time depending on how you're connected (perhaps twenty minutes on a 28.8 line). PPM gives absolutely no feedback whatsoever during this time, so avoid the temptation to abort the command. Eventually install messages fly by, and the PPM prompt appears. Type quit and you're ready to rock.
Besides installing Tk proper, PPM places two new executables in the Perl bin directory: PTKSH and WIDGET. Try them both by typing their names in a DOS window (remember, all executables in the Perl bin directory are now in your path), or by double-clicking them from an Explorer window. Note that Perl/Tk applications always have a DOS window for STDIN, STDOUT, and STDERR. The window will stay iconified on the task bar, but you can open it at any time to look for messages or enter input. The WIDGET program (Figure 5) is helpful if you're learning Perl/Tk; it demonstrates common widgets and displays the source code used to render them.
Figure 5: Perl/TK Widget Demonstrations
Now that we have Perl and Tk installed, what's next? Let's say I want to install a Frog widget provided in a module downloadable from the CPAN. The CPAN is designed for Unix, with gzipped tar files and makefiles. Is the following installation sequence still viable in Win32?
gtar -zxvf distribution.tar.gz cd distribution perl Makefile.PL make make test make install
As it happens, the answer is yes - once we collect the requisite tools. We'll assume that the module is Perl only - no C code - since regrettably few Windows 95 machines have a compiler.
For unpacking CPAN distributions, I use WinZip 7.0, a nifty utility that handles not only zip files, but many other common formats like tar, gzip, and binhex. It integrates nicely with Netscape, is easy to use, and performs flawlessly. Once the distribution is unpacked simply run perl Makefile.PL to generate your Makefile.
The hardest part of this project was locating a working make substitute. Long story short: cygwin (a Unix-like API for Windows; http://sourceware.cygnus.com) has its own make, but I was saved by Gurusamy Sarathy, who pointed me to his DMAKE executable.
Once unpacked, just move DMAKE.EXE and STARTUP to some directory in your path. You could use Perl's bin directory, but I'd recommend using a directory of your own. There are two caveats that Sarathy points out:
C:\ DMAKE DMAKE
Success! Next step:
C:\ DMAKE test DMAKE test C:\PERL\5.00502\BIN\MSWIN3~1\ ... test.pl The getpwuid function is unimplemented at blib\lib/Tk/Frog.pm line 86. at C:\PERL\site\5.005\lib/Tk/Widget.pm line 186
Darn, failure! But the error makes perfect sense - Windows 95 has no concept of multiple users and passwords (Novell Client 32 excepted), so why should any of the getpw() functions work? Indeed, there are even more Perl functions unavailable in Win32, all listed in the "ActivePerl FAQ/Quirks" section of the online documentation.
Okay, let's look at the code, but I want a familiar editor. NotePad is a disaster since it has no concept of a Unix end-of-line character and can't handle any but the tiniest files. WordPad is acceptable - in fact, that's what I edited Config.pm with - but I want my Emacs! (Sorry, vi folks, you're on your own. [both vim and vile are available for Win32. -editor])
There is a very nice Emacs implementation at ftp://ftp.cs.washington.edu/pub/ntemacs/latest/i386/emacs -20.3.1-bin-i386.tar.gz.
Once unpacked, you install it with one command at a DOS prompt. Assuming the Emacs source tree is c:\emacs, enter this:
c:\emacs\bin\addpm c:\emacs
At this point we have a comfortable, albeit minimal, development environment. The online documentation details other repositories of Unix tools in the section "ActivePerl FAQ/Windows 95/NT."
Now, back to the DMAKE test failure - here's the offending code:
if (not $user = getlogin) { die "Can't get user name." if not $user = getpwuid($<); }
As porting problems go, this one has no real fix because the code does not apply to Windows 95. Since I wrote the code, I know why it needs a user name - for authentication later in the program. But for Windows, a fake user name is okay, so all we need to do is add one:
if (not $user = getlogin) { if ($^O eq 'MSWin32') { $user = $^O; } else { die "Can't get user name." if $user != getpwuid($<); } }
The Perl special variable $^O contains the operating system name, and I've used it with the assumption that the new code will function properly on any OS other than Windows. That may not be a good assumption (what about NT?),(Once I have access to an NT machine, I'll use Win32::IsWinNT() and Win32::IsWin95() to tune this code further. but it's the best I can do. At least I can proceed with testing the widget.)
The next DMAKE test worked perfectly, as did DMAKE install. My Tk module installed in the ...site\5.00502\lib\Tk hierarchy, and I used PTKSH to try it out. No problems, although there was one more detail to investigate - the install will have placed a Perl script called FROG in my path. In Unix the script is copied to the directory containing the Perl executable. Is the same true in Windows?
Yes. In fact, two files are stored in the Perl bin directory, the original script (FROG) and the script wrapped (by pl2bat) in a DOS batch file (FROG.BAT). Try perldoc pl2bat, pl2bat -h or read the online documentation for details. The pl2bat wrapper is clever - it's a valid Perl program and a valid DOS batch file.
These statements are designed so that two programs can parse them properly, DOS and Perl. This trickery was devised so the script would run from a variety of incantations.
To DOS, the first line, @rem = '--*-Perl-*--, is a comment (remark), which it ignores. The fourth line executes Perl, passing -x (which discards any text prior to the #! line and begins executing the program from that point), -S (which searches through your path, emulating what #! does on Unix), the script's name, and up to nine command line parameters. When the script terminates, the batch file jumps to the label endofperl.
To Perl, these statements assign a large multiline string to @rem, beginning with '--*-Perl-*-- and ending with the solitary ' ten lines later. Nothing is ever done with @rem; it just gets the DOS batch commands out of the way so Perl can do its business, starting with the #! line after that final apostrophe.
So FROG will launch whether you type it in from a DOS prompt or a double-click its icon in an Explorer window. But will it run correctly? Alas, the script fails:
Bad command or file name
It's my widget, so I know that the system() invocation in FROG.BAT is the culprit. system() works perfectly well in Win32, but FROG uses it to call the klog program, which is Unix-specific. A quick modification yields:
if ($^O eq 'MSWin32') { ($pw eq $^O) ? exit(0) : return(0); } else { system "/usr/afsws/bin/klog $user " . quotemeta($pw) . " 2> /dev/null"; ($? == 0) ? exit(0) : return(0); }
But when I run FROG again the error reoccurs. Eventually, you'll realize that Perl isn't running the file you think it is! What's wrong?
Think -S (it's in the .BAT file). This command line option tells Perl to search our path for the script. So Perl finds the FROG file in the Perl bin directory - the other file installed by DMAKE install. Two separate programs, both of which need to be fixed.
In my Win32 testing I've found that almost all of Perl/Tk works. The few outstanding bugs I know about involve fontFamilies() and fileevent(). No doubt there are others. When I see patches that look important, I test them, and if they check out I make them available at
Until next time, use Tk;
__END__