Getting lhs2tex working under Win32 (was Re: ANNOUNCE: lhs2tex-1.9)

Antony Courtney antony at apocalypse.org
Fri Jan 23 17:32:55 EST 2004


Andres Loeh wrote:
 > [...]
> We are pleased to announce the first official release of
> lhs2TeX, a preprocessor to generate LaTeX code from literate
> Haskell sources.

Thanks for producing such a wonderful and useful tool!

I am pleased to report that I managed to get lhs2TeX working on Win32, 
by modifying just a single byte in the source code.  Unfortunately my 
"one byte patch" is just a short-term non-portable fix, and it's not 
entirely clear what the right long-term solution is.  I thought I'd 
share my fix for the benefit of brave souls that wish to apply it, and 
offer some thoughts about what a better long-term solution might be.

The Issue
---------

Using Cygwin on Win32, one can build and install lhs2TeX by just 
following the standard build instructions given for building on 
Unix-like systems:  ./configure ; make ; make install

However, when you actually run the lhs2TeX binary installed in 
/usr/local/bin, it will be unable to locate its lhs2TeX.fmt file, even 
if you attempt to set the LHS2TEX environment variable to point to the 
directory where this file is installed.  There are two reasons for this:

    1.  GHC does not use Cygwin, and produces executables that do not 
use the Cygwin library or understand Cygwin-style file paths.  So even 
though "make install" installed lhs2TeX.fmt in /usr/local/share/lhs2TeX, 
and even though lhs2Tex attempts to open the file 
"/usr/local/share/lhs2TeX/lhs2TeX.sty", this path ultimately just gets 
passed on unprocessed to the Win32 file open function (CreateFile). 
Unfortunately, this is not a valid Win32 path.

     2.  lhs2TeX includes its own code to look for its needed files on a 
search path constructed from some combination of a compiled-in list of 
directories and those constructed from the $LHS2TEX and $HOME 
environment variables.  This code supports both ':' and ';' as path 
component seperators, probably in an attempt at portability. 
Unfortunately, this isn't actually the right solution, as it precludes 
specifying drive letters in paths.  A value of "C:/foo/lhs2TeX/" for 
$LHS2TEX ends up being processed as two directories: "C" and 
"/foo/lhs2TeX/"!

My Quick Fix Workaround:
------------------------

1.  In the lhs2TeX sources, change line 42 of FileNameUtils.lhs from:
       > environmentSeparators         =  ";:"
     to:
       > environmentSeparators         =  ";"
     and do another "make install".

2.  Set your LHS2TEX environment variable to a path that reflects where 
doing "make install" under Cygwin actually installed the lhs2Tex.fmt 
file.  On my system, this is "c:/cygwin/usr/local/share/lhs2tex".

Of course, this solution isn't a very good one for the long term, since 
':' is the right choice for a path seperator under Unix.


Thoughts on a Robust Solution:
------------------------------

As discussed above, we are really being bitten by two seperate issues 
here.  The first is that GHC does not use Cygwin, and the second is 
that, in the absence of a portable infrastructure for locating files, 
lhs2TeX implements this itself, in an unfortunately non-portable way.

The GHC team put a great deal of effort into making ghc independent of 
Cygwin, so I won't even bother trying to make the case for ghc just 
using Cygwin for file I/O (even though I think there is a strong case to 
be made).

Instead, I propose that it would be very valuable if there were some 
standardized, portable library that Haskell programs like lhs2TeX could 
use for locating files that should be installed with the program. 
Ideally, such a library would support some notion of search paths, be 
configurable through both global and application-specific search path 
environment variables, and completely isolate the application from 
operating system-specific path name issues such as ';' vs. ':' and '/' 
vs. '\'.  It's important that this implementation be standardized and 
shipped with the Haskell compiler, so that the O.S.-dependent path and 
internal field seperators are defined internally when the Haskell 
compiler is built for a particular platform, and isn't exposed to 
applications.

This should be pretty straightforward to implement; I'm sorry I can't 
spare the day or so it would take to contribute this myself right now, 
but perhaps some enterprising soul on this list will be inspired to take 
a stab at it.

	-antony

-- 
Antony Courtney
Grad. Student, Dept. of Computer Science, Yale University
antony at apocalypse.org          http://www.apocalypse.org/pub/u/antony


More information about the Haskell mailing list