If you’ve ever been enthusiastic about an open source project, you’ve likely compiled a bleeding edge version of a project before. I know a many non-coders do this, and I can empathize that it is potentially confusing for people.
The basic idea of a build system is to:
- ensure that you have all the libraries, tools, and files needed for the project (configure)
- be able to compile the program with one command (make)
- install the project onto the host system so that it usable (make install)
I’m going to cover #1 today, that is, how to ensure you have what you need, and how to practically work through problems when they pop up. Just so I can give command line examples, I’m going to assume that you’re using a Debian package system (eg, Ubuntu/debian/mint/etc).
First of all, I’ll assume you’ve downloaded the source, and are moderately familiar with the build steps. Most programs use a well known open source build system (commonly Cmake or autotools), and most projects will have a page describing the steps you should take to install. (eg, “./configure && make && make install” for autotools). What I want to help you through is what to do when things go wrong. I’ve compiled a lot of things, and these are the typical errors I’ll run into…
Finding the Packages You need
Far-and-away the most numerous configure errors you’ll run into are where the build system detects that you don’t have all the packages you need. Any project needs a fair amount of infrastructure to get going. For instance, if you’re trying to build a graphics program, your system has to have two things. It has to have (1) the compiled files that contain the code that runs the gui (eg, gtk or Qt) and (2) the header files that describe how to use those software libraries. To analogize, the header files are the user manual for the car (the library) that you want to drive! Without these, your program cannot compile.
Now, for a bit of package knowledge. Not everyone needs the header files on the system, and they can take up a bit of room. On Debian packages, the header files are usually placed in the “-dev” package, and the compiled versions are placed in the package library name. For instance, you don’t need the USB header files if you never do any USB development. Most people though want to use the USB port, so the libraries (code to do this) are installed on the system. The library packages are usually named like “libusb-0.1-4” and contain the libraries. “libusb-dev” contains the header files.
Most the time, when you see an error about a package or header file not being found, that means that you need to install some more packages! I have a few ways to do this. One might be better in one situation than another, and experience will teach you which one to do when.
If you see an error about “file.h” not found, that probably means you have to install the headers (the packages that end in -dev). The tool I highly recommend for this is called apt-file. T
his tool will create an index of all the files available to you in the repositories that you have, and give the ability to search for any file. For instance, if I was missing “usb.h”, I would run
apt-file search usb.h
This will return all the files that have the string in them “usb.h”. If you get too many results back, you can search with regular expressions, or you can filter for the “dev” string using grep. If I do
apt-file search /usb.h | grep dev
I get 4 files back, and the one that makes sense is called “libusb-dev”. It will take experience to figure out which file is the most likely one to install, but its usually pretty obvious after doing it a few times.
cannot find package
Most the time, the -dev packages install something called a “.pc” file. These files are lookup tables that show where exactly all the header files and libraries in a package are. The program pkg-config can parse these files, and give them to the compiler in the way it understands. Run the command
That’s the list of all the packages that are installed. Those are all the packages that the system knows where the header files are, and how to link to that program while compiling!
Take any one of the things listed by pkg-config –list-all and run this command (libpng as example)
pkg-config libpng12 --cflags --
That is the information that your configure steps are looking for when its looking for a package.
If your compile steps say something about “Package libpng12 not found”, use apt-file to figure out where “libpng12.pc” is by doing
apt-file search libpng12.pc
and install those packages! It will likely resolve your error.
These are terrible (and thankfully, somewhat rare). I hate getting these errors. This has a lot to with backwards compatibility and what specific functions the target compile needs.
For instance say you’re compiling ProjectX. ProjectX relies on libpotato version 2.13. It cannot use version 2.14 because version 2.14 dropped support for the mega_spud() function. However, the repositories only have the 2.14 version because that is the latest version.
You will have to figure out a way to install libpotato 2.13 on your system. This sometimes requires a separate compile. You should isolate these files from your system, so that most of your system uses all the bug-fixes in libpotato 2.14 for your desktop “Potato Garden” widget.
How do I deal with these? Unfortunately, there isn’t a quick way. I keep maintained a special folder that contains all the strange libraries that I have needed, and I configure my system to know about these. Its a bit of a pain in the backside, but it keeps my filesystem clean, and isolates the older version from what most of the stuff on my system needs. I’ll blog more about how to do this when I talk about the “make install” step in compiling open source stuff.
Some programs are just funny, and have funny steps they need. Some need special tools from other packages, others need other strange things. If you run into any of these cases, you probably have to treat them on a case-by-case basis. Google a forum and see what is going on with the funny compile you’re trying to do.
This should give you a way to figure out how to work through most problems you run into during the configure step yourself! Happy coding!