On a Linux system, such as Ubuntu, it is fairly easy to compile abcm2ps
with the abcCairo extension. The program makes use of a whole lot of
different libraries, but because the system largely handles these for
you, you may well not even have to consider these when building the code.
However, if you want to port the code to a different system, such as a
Windows PC or an Apple computer, you probably need to give
some thought about where the libraries come from. Because the libraries
are open-source, you can download them, but you may run into problems
compiling them on another system. I decided to try building the code
using static libraries built from the source distributions rather than
relying on my system's dynamic libraries.
The source distributions are usually available in at least two places.
Typically there will be a project maintaining a library which has its
own publicly available repository. Secondly, Linux distributions such
as Debian make the packages available for downloading individually.
Downloading everything from the Debian website is easiest because they
are all in the same place. However, these packages typically won't be
the very latest.
To build my code with static libraries, I started by taking a copy of
the no_pango Makefile with a new name and removing the -lcairo flag
so that I would not be loading the dynamic library. Having done this,
make
will cause the code to compile, but there will be linker
errors.
I then obtained a copy of the Cairo library (cairo-1.16.0), compiled it
and added a command to build abcm2ps to the Makefile
abcm2ps: $(ABCM2PS_OBJECTS)
gcc $(CFLAGS) $(ABCM2PS_OBJECTS) $(CAIRO_LIB) -o abcm2ps $(LDLIBS)
The original Makefile relies on default rules, so adding this line
makes it explicit what happens when you do make abcm2ps
.
Again, this results in linker errors. This is because the Cairo library
in turn relies on other libraries. These other libraries can generally be
downloaded from more than one place. The Debian package pages should
document all the dependencies of any particular package, but you can also
adopt a more trial and error approach, adding libraries in an iterative
process until you don't get any linker errors.
The libraries that I found I needed were
- libcairo
- libfreetype
- libpixman
- libpng
- libz
- libfontconfig
- libharfbuzz
- libexpat
I also found that I needed the pthreads (concurrency) library, which I
included with -lpthread, on the assumption that this will normally be
available on other systems.
The various source code distributions generally come with a "configure"
script which allows you to select various options for the build and also
interrogate your system to see if it has support for various features.
The "configure" script is different for every software package and is
generated by autoconf. To see the options supported, you can usually
do ./configure --help
. Building the software consists of running
./configure <options>
followed by make
.
Many, but not all, of the packages built with static libraries by default
straight away. To enable building static libraries, the option is likely to be
--enable-static
. For the HarfBuzz library, it was not enabled by
default and I needed to do ./configure --enable-static
.
The fontconfig package required autopoint
to be installed before it
would build and the "configure" script was called "autogen.sh", so I
needed to do ./autogen.sh --enable-static
for this package.
As well as being able to find all the static libraries, the compiler needs
to be able to find the header files for the cairo library that you have
downloaded. This is set up with CPPFLAGS in the Makefile.
Once I had built static versions of all the libraries, I was able to
build abcm2ps with abcCairo extensions using the following command in
the Makefile:
gcc $(CFLAGS) $(ABCM2PS_OBJECTS) $(LIBCAIRO) \ $(LIBPIXMAN) $(LIBPNG) $(LIBZ) \ $(LIBFONTCONFIG) $(LIBFREETYPE) $(LIBHARFBUZZ) \ $(LIBEXPAT) -o abcm2ps $(LDLIBS)