Cross-Platform Development November 25th, 2009
Patrick Stein

In preparation for the upcoming TC Lispers meeting, I was testing my Sheeple-based CL-OpenGL GUI code on all of the different systems that I use. This was important because part of my goal in starting from bare-bones OpenGL was to make something that was pretty easy to port. The OpenGL libraries are the only non-Lisp dependencies, and they are pretty standard.

I run Mac OS X 10.6.2 as my primary development machine. I knew everything I had so far worked there under SBCL 1.0.30 and CMU-CL 20a. It took a little tweaking to get Sheeple built under Allegro CL 8.1 (Trial Edition), but after that I was five-by-five under Allegro, too. Unfortunately, I cannot get CL-OpenGL to run under Clozure 1.3-r11936 on Mac OS X. Also, ECL 9.10.2 doesn’t support weak key hashtables which Sheeple needs. And, my install of clisp broke somewhere along the lines, so I haven’t tried it.

I have an Ubuntu Linux box. There, I am using SBCL 1.0.11.debian (eeps). Everything ran perfectly over there (even displaying through X Windows back to my Mac).

I also run Windows Vista under VMWare Fusion on my Mac. I hadn’t done any development on it for months and months. Fortunately, in Google-ing to find out how to fix it, I stumbled upon what I had written about how I got things set up originally. Over the last two hours, I got SBCL upgraded to 1.0.29 under Vista. I got ASDF-Install set up with a bunch of help from this article. And, from there, I got CFFI and cl-opengl and ZPB-TTF and Sheeple installed.

ZPB-TTF and Sheeple both used some tar format options that archive_0.7.0 didn’t like. For those, I had to jump through some hoops to untar and retar them to get them to install.

Here was my final /Users/Patrick/.sbclrc file:

(require :asdf)

;; from Zach Beane
(defmethod asdf:perform :around ((o asdf:load-op)
                                (c asdf:cl-source-file))
  (handler-case (call-next-method o c)
    (#+sbcl sb-ext:invalid-fasl
     #+allegro excl::file-incompatible-fasl-error
     #+lispworks conditions:fasl-error
     #+cmu ext:invalid-fasl
     #-(or sbcl allegor lispworks cmu) error ()
     (asdf:perform (make-instance 'asdf:compile-op) c)
     (call-next-method))))

(dolist (pkg  '("alexandria/"
                "archive_0.7.0/"
                "asdf-install/asdf-install/"
                "babel_0.3.0/"
                "cffi_0.10.5/"
                "cl-opengl/"
                "flexi-streams-1.0.7/"
                "gzip-stream_0.2.8/"
                "salza2-2.0.7/"
                "sykopomp-sheeple-ceab213/"
                "trivial-features_0.6/"
                "trivial-gray-streams-2008-11-02/"
                "woolly/"
                "zpb-ttf-1.0/") )
  (pushnew (merge-pathnames pkg
                            (merge-pathnames "ASDF-Systems/"
                                             (user-homedir-pathname)))
           asdf:*central-registry*))

(asdf:oos 'asdf:load-op 'asdf-install)

;; for my sanity
(setf asdf-install:*locations*
      (list (list (merge-pathnames "ASDF-Systems/" (user-homedir-pathname))
                  (merge-pathnames "ASDF-Systems/" (user-homedir-pathname))
                  "My install spot")))

;; via http://sean-ross.blogspot.com/2007/05/asdf-install-windows.html
#+win32
(asdf:oos 'asdf:load-op 'gzip-stream)

#+win32
(asdf:oos 'asdf:load-op 'archive)

#+win32
(defun asdf-install-extractor (to-dir tarball)
  (let ((name nil))
    (gzip-stream:with-open-gzip-file (ins tarball)
      (archive:with-open-archive (archive ins)
        (let ((*default-pathname-defaults* (pathname to-dir)))
          (archive:do-archive-entries (entry archive name)
            (archive:extract-entry archive entry)
            (unless name (setf name (archive:name entry)))))))
    (string name)))

#+win32
(push 'asdf-install-extractor asdf-install:*tar-extractors*)

The list of packages in the middle were about half installed manually to get the archive extraction code working and half installed through ASDF-Install. If I recall correctly, I had to manually install: archive_0.7.0, flexi-streams-1.0.7, gzip-stream_0.2.8, salza2-2.0.7, trivial-gray-streams-2008-11-02, and a fresh copy of asdf-install. I also had to download a compiled version of freeglut.dll and tuck it into my Windows\system32 directory.

Getting SBCL to use the fresh copy of asdf-install was annoying. I ended up starting up a Command Prompt as Administrator (right click on the “command.exe” icon or menu-item and select “Run as Administrator”). Then, I went to the SBCL directory (“C:\Program Files\Steel Bank Common Lisp\1.0.29\”) and did the following:

% rename asdf-install asdf-install.old
% mklink /d asdf-install "C:\Users\Patrick\ASDF-Systems\asdf-install\asdf-install"

I had extracted the tar-ball from the ASDF-Install distribution into my ASDF-Systems directory.

Then, I went back and made my GUI code use double-buffered OpenGL windows because running Lisp to OpenGL to Windows Vista to VMWare to Quartz had some wicked flickering going on.

Two hours is a long time for something that’s supposed to be easily portable. But, I would have spent at least 95% of that time even if I were using an all-Lisp solution. And, this is far less time than I ever spent porting anything else to Windows.

Emacs + Slime + SBCL on Windows Vista May 27th, 2009
Patrick Stein

I just finished setting up Windows Vista to run in VMWare Fusion. Then, I finally tackled setting up Emacs with Slime and SBCL under Windows Vista.

For the most part, I followed Robert Zubek’s gameplan. However, I quickly ran into a problem with swank’s temporary files not being in a writable location. I wish I had found this thread sooner. Alas, I ended up rolling my own by tweaking the temp-file-name function in swank-sbcl.lisp. The new version looks like this:

(defun temp-file-name ()
    "Return a temporary file name to compile strings into."
  #-win32 (concatenate 'string (tmpnam nil) ".lisp")
  #+win32 (concatenate 'string
                       (sb-ext:posix-getenv "TEMP")
                       "/"
                       (symbol-name (gensym "SL"))
                       ".lisp"))
l