Sunday, January 20, 2008

Compiling thttpd on Mac OS X

The source for thttpd will not compile on OS X 10.3 (Panther) without tweaking. What follows is a record of the problems that occur and the various hacks I've come across, with a summary at the end. (Skip down, if you're impatient.)

After downloading version 2.25b, unzipping the source, and running configure, the first roadblock involves the host system not being recognized:

creating cache ./config.cache
checking host system type... configure: error: can not guess host type; you must specify one


This is an old, well-known problem concerning Unix compilation on OS X. The solution involves copying two files, config.sub and config.guess, from the /usr/share/libtool directory, replacing the two files that shipped with thttpd. (On earlier versions of OS X, they are located elsewhere.)

This works nicely:

cp -f /usr/share/libtool/config* .

If you've already tried running configure, delete the config.cache file that was generated.

With these files copied, configure will proceed normally. The next step is to run make. Running make will appear to go smoothly, but the Makefile needs to be edited on OS X, or make install will fail. The first failure reads:

mkdir -p /opt/sbin
/usr/bin/install -c -m 555 -o bin -g bin thttpd /opt/sbin
install: bin: Invalid argument
make: *** [installthis] Error 67


The offense is here: -o bin -g bin. This snippet indicates a user and group by the name of bin, and OS X does not ship with this user and group created. You could add both this user and group, or you could edit the Makefile to indicate users and groups that do exist. I've chosen to do the latter.

From the error above, note the second line, open the Makefile, find this line, and replace -o bin -g bin with -o root -g admin. The line should read like this:

/usr/bin/install -c -m 555 -o root -g admin thttpd /opt/sbin

A few lines below, in the install-man section, there is a similar snippet that requires the same fix:

$(INSTALL) -m 444 -o bin -g bin thttpd.8 $(DESTDIR)$(MANDIR)/man8

Replace -o bin and -g bin with -o root and -g admin, respectively.

The directories indicated in the Makefile involve executables meant to be run by the superuser and directories storing man pages. Elsewhere on the OS X file system, these directories are set to -o root -g wheel, so I see no reason not to set the above to -o root -g admin.

Now, run make clean, run make again. If at this point we give the install another try, there may be one remaining error.

I have chosen to install the package in the /opt directory, a common practice for installing third-party packages on OS X. In running make install, make will try to copy a file to a non-existent directory. The error reads:

cp makeweb.1 /opt/man/man1/makeweb.1
cp: /opt/man/man1/makeweb.1: No such file or directory
make[1]: *** [install] Error 1
make: *** [installsubdirs] Error 2


Apparently, there is no man1 directory at the install path I've chosen. We need to tell make to create one. In the install-man section, right below the line we just edited, add the following:

-mkdir -p $(DESTDIR)$(MANDIR)/man1

This will create the needed directory. Run make clean and make one last time. Then run make install. All should be well. You can check that make install exited cleanly with echo $?, which should return 0.

Summary

Here is a summary of the fixes. The code is written using monospace fonts. Follow this carefully, because your browser will likely make line breaks where there should be none:
  1. Copy config.sub and config.guess from /usr/share/libtools to the source directory, replacing the existing files
  2. Run configure
  3. Edit the Makefile, replacing the following snippet that reads -o bin -g bin to read -o root -b admin
  4. Add the following line to the end of the install-man section (if needed on your system): -mkdir -p $(DESTDIR)$(MANDIR)/man1
  5. Run make, and then make install
The install should exit with a return value of 0.

1 comment:

nellthu said...

Thank you for this awesome walkthrough! You saved me a lot of time and nerves. Also, I had some additional problems and had to google up the solution so I add my changes here for everyone who gets stuck on the same place:

1)
Problem:
While running make, I got following error:
htpasswd.c:52: error: conflicting types for 'getline'

Solution:
replace 'getline' by 'my_getline' in extras/htpasswd.c (two occurences)

2)
Problem:
/usr/bin/install -c -m 555 -o root -g admin thttpd /usr/local/sbin
install: /usr/local/sbin/thttpd: chown/chgrp: Operation not permitted
make: *** [installthis] Error 71

Solution:
instead of changing the two lines in Makefile to -o root -g admin, I had to change them to:
-o my_username -g admin

3)
Problem:
chgrp: you are not a member of group www
make[1]: *** [install] Error 1
make: *** [installsubdirs] Error 2

Solution:
sudo dseditgroup -o edit -a my_username -t user www

Note that you must replace 'my_username' in problem 2 and 3 with your actual username. You can get that by typing following to the console:
whoami

Sources:
http://pbraun.nethence.com/doc/www/thttpd.html
http://superuser.com/questions/214004/how-to-add-user-to-a-group-from-mac-os-x-command-line