Building and Running CUPS under Solaris 8

First posted: Thu Nov 6 20:18:21 PST 2003
Last Updated: Fri Sep 16 20:47:23 PDT 2005

NOTE: According to information disseminated at the Solaris 10 BoF at LISA 2004, Solaris 10 includes and uses CUPS by default and CUPS is integrated with all the usual Solaris printing utilities.

BUT WAIT: I ran into one of Sun's printing developers at LinuxWorld Expo and she assured me that they are not using CUPS in Solaris 10. I was disappointed to hear this. Still no GUI-based printing controls in S10 or other nice CUPS features.

Note also that a precompiled CUPS package is available at Blastwave.

Building & Installing

I build CUPS to install in /opt/cups so that I can keep it separate from the Sun-supplied lp commands. This makes it easy to try out CUPS before releasing it for all users.

More details later...

First I set some environment variables that I use for all compilations. I use the gcc that Sun supplies in /opt/sfw but this version of gcc doesn't look in /opt/local (/usr/local is symlinked to /opt/local also), where I keep most local libraries and such, so I do:

setenv CFLAGS "-I/opt/local/lib -I/opt/sfw/lib"
setenv CXXFLAGS "-I/opt/local/lib -I/opt/sfw/lib"
setenv DSOFLAGS "-L/opt/local/lib:/opt/sfw/lib -R/opt/local/lib:/opt/sfw/lib"
setenv LDFLAGS "-L/opt/local/lib:/opt/sfw/lib -R/opt/local/lib:/opt/sfw/lib"

I'm not sure if this is necessary for building CUPS because I don't know which, if any, of my locally installed software CUPS requires.

I also make a few source code changes, but these are not needed for most people: By default, CUPS utilities will try to connect to a server on "localhost". This can be overridden with the CUPS_SERVER environment variable, but I don't want to rely on that, so I edit cups/usersys.c and change the line that reads

 server = "localhost";
 server = "print";

and in DNS I set host "print" to be a CNAME to our print server.

I also make a change in cups/emit.c. I make a line there read:

fprintf(fp, "@PJL JOB NAME=\"%s\"\n@PJL RDYMSG DISPLAY=\"%d %s %s\"\n", title, job_id, user, title);

By default CUPS sets the status message on the printer, but that message disappears as soon as the end-of-job is sent (at least on our main printer) so it's hard to see it. I change CUPS to instead set the RDYMSG (the "Ready" message when it's idle) so that the message with the job name and username will stay on the display until the next job.

Then I configure with

./configure --prefix=/opt/cups --sysconfdir=/etc --localstatedir=/var --enable-ssl --with-openssl-includes=/opt/local/include --with-openssl-libs=/opt/local/lib

Some of these are just personal preferences. I want to make sure that machine-specific files don't go in /opt/cups because that is distributed via rdist to every machine and any changes would be overwritten.

Then I do a "make" (my make is GNU make) and a "sudo make install" and it all gets installed.

Then it's time to configure. You need to find good PPD files for your Postscript printers and place them in /opt/cups/share/cups/model/ . The printer "drivers" distributed for Windows are usually just zip files (even if they end in .EXE) and I use unzip and then grab the PPD file and rename it (if necessary) to somethingdescriptive.ppd and place it in that directory.

The other day I was installing an HP5M and HP4000N for a client and the first PPD file I got from HP's site didn't support all the paper trays of one of those printers, so I downloaded the "XP" drivers instead of the "Win 2000" drivers (or vice-versa) and that one had a much better PPD.

Use the web interface at http://localhost:631 to add the printer. If it's an HP use the socket://printer-address type of device description. If it only has an lpd server, use lpd://printer-address

Once you've added the printer, click on "Configure Printer" and set what options the printer actually has and set defaults. This will place a modified copy of the PPD in /etc/cups/ppd/ . If you ever need to fine tune things, edit the PPD in there and send a HUP signal to cupsd (pkill -HUP cupsd) and it will reread it. You can also check your PPDs with the /opt/cups/bin/cupstestppd command.

If you have non-Postscript printers, you'll want to install ESP Ghostscript (see below) from the same people who bring you CUPS and you'll want to go to and search their database for the best way to print to your printer(s). This will usually involve installing foomatic or some other package to convert to a format your printer will understand.

You can also buy the commercial version of CUPS, ESP Print Pro. I actually tried this first before I ever tried the free version of CUPS as I figured it was worth the money to save time, but I ended up not using it. The pro version is updated far less often than CUPS, so I decided to give CUPS a try and was able to get it working. The commercial version also comes with a nice GUI for end users (see more on those later), but it also coredumps at inopportune times (like when using it), so you'll have to decide whether you want to try the commercial version or not. It claims to come with tons of drivers, but if all your printers are PostScript, that probably is of no use.

Use the "Print Test Page" button to test. If it doesn't work, debug by looking at /var/log/cups/error_log and try to figure out what's going on (easier said than done, I know).

Once it's working you have to decide how to make the programs available to your users. I install links to the common lp* commands into /opt/local/bin:

lrwxrwxrwx   1 root     21 May 23  2002 cancel -> ../../cups/bin/cancel*
lrwxrwxrwx   1 root     22 May 23  2002 disable -> ../../cups/bin/disable*
lrwxrwxrwx   1 root     21 May 23  2002 enable -> ../../cups/bin/enable*
lrwxrwxrwx   1 root      5 May 11  2002 lp ->*
-rwxr-xr-x   1 root   2464 Jun 20 12:25*
lrwxrwxrwx   1 root     23 May 26  2002 lpadmin -> ../../cups/sbin/lpadmin*
lrwxrwxrwx   1 root     19 May 26  2002 lpc -> ../../cups/sbin/lpc*
lrwxrwxrwx   1 root     22 May 26  2002 lpinfo -> ../../cups/sbin/lpinfo*
lrwxrwxrwx   1 root     22 May 26  2002 lpmove -> ../../cups/sbin/lpmove*
lrwxrwxrwx   1 root     24 May 12  2002 lpoptions -> ../../cups/bin/lpoptions*
lrwxrwxrwx   1 root     23 May 12  2002 lppasswd -> ../../cups/bin/lppasswd*
lrwxrwxrwx   1 root     18 May 12  2002 lpq -> ../../cups/bin/lpq*
lrwxrwxrwx   1 root      5 May 11  2002 lpr ->*
lrwxrwxrwx   1 root     19 May 12  2002 lprm -> ../../cups/bin/lprm*
lrwxrwxrwx   1 root     21 May 12  2002 lpstat -> ../../cups/bin/lpstat*

Most programs just call "lp" or "lpr" and because we have /opt/local/bin first in our users' PATH, the CUPS version will be found first. A few programs actually call "/usr/bin/lp" so you may want to eventually change /usr/bin/lp into a symlink. I did likewise for /usr/bin/lpstat because there are some programs out there that call this (like acroread, where you can also modify Reader/sparcsolaris/app-defaults/AcroRead and replace "/usr/bin/lp -c" with just "lp -c").

You'll also notice that lp and lpr actually point to a shell script. This is because I try and give my users the same experience one gets under Windows, with a GUI client for printing. So if they're on an X server, they get a pop-up that lets them choose duplexing, paper tray, etc. For this I use the gtklp program. If you use Easy Print Pro, you can use its glp program. There's also xpp, which looks nicer than gtklp but hasn't been updated in too long (it was updated on 2004-12-09 for the first time in almost three years; I have not yet tested it) and lacks many options. Some of the KDE and GNOME programs (like kups) may also do the job but I don't have much experience with them. See my just as an example. It has some nasty kludges specific to our printers and to allow use of our old printer names, so take it only as an example.

Printing From Mac OS X

Starting with 10.2, OS X uses CUPS for printing. This makes it real easy to integrate. However, for some reason, Apple decided to ship CUPS with CUPS auto browsing turned off. Usually a CUPS server will listen for CUPS broadcasts and automatically add printers it hears about. We have some Macs with printers directly attached, and when those machines come on line, their printers automatically show up in our Unix print queue. But it doesn't work the other way. To make this work, you need to edit /etc/cups/cupsd.conf on your Macs and add a line like

BrowsePoll printservername

Search for BrowsePoll in that file and add it after the example. Then HUP the cupsd on the Mac and your other printers should show up in the Print dialog box under Printer: -> Shared Printers. This will work no matter where the machines are as long as they can reach port 631.

You should be running at least version 1.1.19, as versions prior to that one could not deal with the binary PostScript that some OS X programs produce.

Printing From Windows

I'm fortunate that we have no Windows desktops in our company, so I have never had to learn how to do this. I know it's done using Samba and smbprint, or using IPP (Internet Printing Protocol) in newer versions of Windows, but that's about all I know. Sorry.

Problems With CUPS

When CUPS works, it's pretty nice. However, when it doesn't work it can be hard to get help. There's a newsgroup hosted by Easy Software, the makers of CUPS, but you'll see a lot of people with problems and not many resolutions. Many people give up and go away. I'm doing this writeup in an attempt to provide some needed help for those who want to run CUPS on Solaris (I sure wish Sun would just switch to CUPS like so many other vendors have). I don't have Solaris x86 so everything I've done has been on the SPARC platform. I know there are some problems compiling under x86. Maybe they have been solved by now. I'm running 1.1.19.

One problem in CUPS that has not been resolved as far as I know (I still see people posting this complaint) is that once CUPS decides to "stop" a printer, it takes manual intervention to get it accepting jobs again. Once in a while I find this happening and I use gtklpq to restart the printer. In fact I've given everyone on our network the ability to do printer admin because I wasn't successful at just allowing everyone to start printers. In a small company like ours that is OK, but this clearly is not an answer for a campus.

Building ESPGS

If you have non-Postscript printers, you'll want to build and install ESP Ghostscript. Here's what I use to do this under Solaris 8:

setenv LDFLAGS "-R/opt/local/lib -R/opt/sfw/lib -R /opt/cups/lib"
setenv C_INCLUDE_PATH /opt/local/include:/opt/sfw/include
Then I comment out the lines in configure #defining malloc as rpl_malloc, since Solaris doesn't seem to have rpl_malloc:
#cat >>confdefs.h <<\_ACEOF
#define malloc rpl_malloc
I run
./configure --prefix=/opt/gs
I comment out the include of stdint.h in src/gomni.c:
/* #include <stdint.h> */
I also need to move out of the way the libtiff that comes with Solaris 8 as it's a rather old version. Instead I rely on it linking with the more modern version I have in /opt/local/lib/ .
mv /usr/openwin/lib/ /usr/openwin/lib/
. Move the libtiff file back to where it was:
mv /usr/openwin/lib/ /usr/openwin/lib/

Install it, and make a symbolic link from a directory in your normal search path. I link /opt/local/bin/gs to it.

Make sure you also install the Ghostscript fonts. I just make a symbolic link from /opt/sfw/share/ghostscript/fonts to /opt/gs/fonts:

lrwxrwxrwx   1 root 30 Nov 17  2002 /opt/gs/fonts -> ../sfw/share/ghostscript/fonts

If you're frustrated with setting up CUPS and are starting to blame yourself, read Eric Raymond's rant against CUPS and open source GUI design in general.

To my home page
jimmy at TokyoJim dot com