Tutorial part 1 (Using autotools):

[ Previous ] [ TOC ] [ Next ]

1.0) Introduction

 The first thing we need is to learn how to use autotools, because once it is properly
set, compiling our plugin in different environments will be less complicated. And if
nothing else, it at least looks more professional :-)
 Using autotools for the program used in this example is real overkill, but later on
we will use this template as a starting point, so try not to get frustrated. But let's
get started..
 
1.1) Making sure, you have development software installed

 First thing you might want to do, is to make sure, your system has working autotools
and gcc compiler, by executing command below. I have marked versions found from
my system using red color, so they are not part of the command.

 automake --version          1.8.5
 aclocal --version          1.8.5
 libtoolize --version          1.5.2
 autoheader--version        2.13
 gcc --version                   3.3.4

1.2) Creating folder structure for our autotools experiment
 
 Let's start this by creating simple folder structure, and although I use home directory in this
example, you can locate you project elsewhere. Create folders by executing command:
mkdir -p ~/xmms_tutorial/example1/src ~/xmms_tutorial/example1/doc
 This creates folder xmms_tutorial to your home directory, which has sub folder example1, and
it has sub folders src and doc. The -p flag means, that mkdir should make also the folders, that
are below src folder (in this case example1 and xmms_tutorial).

1.3) Filling folders with simple program

 If you do not like typing, you can also download files and place them to required directories, but
I recommend that you at least write the files concerning autotools. Why? Well, at least in my case, it
helps to understand what I am trying to learn. On the other hand, documentation used in this
example is complete nonsense, so don't waste your time with it, and the main program is at this
point, just simple helloworld example, so most likely you will not learn anything from it.
 But let's start by creating plugin_main.c file to src folder (this is the place where all source files
are stored in the future). Content of the file is following:

#include <stdio.h>
#include <math.h>

int main(int argc,char *argv[])
{
 printf("Hi there, did you know that PI = %f ?\n",M_PI);
 return(0);
}

 And also our program needs some documentation, so download usage_instructions.txt to
doc folder (this folder usually contains all sorts of documentation). Content of the file is just
lorem ipsum, so nothing special there.
 As I said before, it is quite overkill to use autotools to distribute this kind of program, but
using more complex program as example would not make any real difference (actually it
might even make it harder to understand how to use autotools).

1.4) Creating files needed by automake

 Automake assumes that you have some standard files in your toplevel directory, which
are text files, and contain various information about program/author/etc, but now we can
skip filling them, by simply typing the following in directory (~/xmms_tutorial/example1):
 touch ChangeLog README AUTHORS NEWS

 
If you are wondering what touch command does, it simply creates empty files, so that automake
does not complain about them. Next we need to tell to autotools, which subdirectories it is supposed
to process and also what to include, while creating distribution package. So what we need is a file
called Makefile.am, which is placed also the the toplevel directory, and which has the following lines:

SUBDIRS = src
EXTRA_DIST = doc

 Line beginning with SUBDIRS, means that folder contains yet another Makefile.am, which should
be processed. EXTRA_DIST is just a directory, which is included while creating distribution tar
file, but it does not contain anything that needs processing. If you had also for example skins directory
and you would like to include it automatically to distribution, you could just add it to EXTRA_DIST
line, so your Makefile.am would look like this (but do not use this right now, as we do not have skins
directory in our example):

SUBDIRS = src
EXTRA_DIST = doc skins

 Now that we have told that something has to be processed from src directory, we need to create
another Makefile.am, which tell what has to be done:

AM_CFLAGS = -Wall
bin_PROGRAMS = tutorial1
tutorial1_SOURCES = plugin_main.c

 Basically what we want to happen is that when user types: ./configure && make , our system
creates executable called tutorial1 from sourcefile plugin_main.c, and that -Wall is used as compile
time flag. But wait, something is still missing.. And that something is called configure.in, which lives in
our toplevel directory once again. Content of the file we need is following:

AC_INIT(src/plugin_main.c)
AM_INIT_AUTOMAKE([tutorial1],[1.0.0])
AC_PROG_CC
AC_PROG_INSTALL
AC_OUTPUT([Makefile src/Makefile])

 After creating this file, you are ready to run first program from autotools (do this in the toplevel
directory) called aclocal . If everything went fine, you should get no feedback from program, but
there should be new file in your toplevel directory called aclocal.m4. After this, there are still 3
programs that you should run, before we can try to compile our program.
 So continue by executing command: autoheader ; autoconf and once again, there should be
no feedback from programs, but 2 new files have appeared (config.h.in and configure). First
program creates config.h.in, and second one creates autoconf.
 Last thing we need to do, is to create files called Makefile.in (those files will serve as base for
makefiles, when you run configure later on), and it is done by giving command: automake -a -c

 Ok, now we are ready to see if our program compiles, and if it does, we can create distributable
file which contains all necessary files from this simple project. So go ahead and type in the following
and see what happens: ./configure ;  make
 You should now have executable called tutorial1 in src folder, so try to run it. And voila, we
have just managed to build our first project with autotools.

1.5) Create distributable file out of project

 If you have managed to get previous project working, this part should be really easy. All you need
to do, is to type:  ./configure ; make dist  and after a while, a file called tutorial1-1.0.0.tar.gz
should appear to the toplevel folder. Try extracting the file to /tmp folder on your system, and see
what is inside :)
 If you did extract the file which we created just seconds ago, you might have noticed, that most
of the temporary stuff was left behind. Ofcourse you could just create .tgz file out from your work
directory, but that would also include lots of unneccesary files.

1.6) So how does the previous example help us with plugins?
 
 Actually the previous program would not work as xmms plugin no matter how hard you try, so we
need to make some changes. To be honest, there is actually nothing much we can take from the
previous example, so lets start by creating new folder structure, and populate it with new files.
 Create folder example2 under xmms_tutorial, and under example2 we need to create folder src, which we
had in previous example. Also you should copy Makefile.am file (the one with two lines of text), and
doc folder (after all we are not interested in writing documentation yet) with its content from example1 folder
to your example2 folder. And finally you should use touch command to create following empty files: NEWS,
README, AUTHORS, ChangeLog.

 Now after we have done all this, we are ready to begin writing our first plugin, which is actually only
a really simple skeleton for plugin. If you do not understand what plugin_main.c file does at the moment,
it does not matter, as it will be explained in chapter 2. You can either download the plugin_main.c file by
clicking on the link above, or you can write it manually. If you want to write it manually, here is the
content of the file:
 
#include <xmms/plugin.h>

VisPlugin part2_vp =
{
 NULL,NULL,0,
 "Autotools example 2",
 0,0,
 NULL,
 NULL,
 NULL,
 NULL,
 NULL,
 NULL,
 NULL,
 NULL,
 NULL
};

VisPlugin *get_vplugin_info(void) { return &part2_vp; }

 As you might have figured out, this piece of code does almost nothing. Well actually there is just
enough code, that the plugin can register itself as visualization plugin, and therefore it will appear
in plugins page. But in any case, that is really enough for us to get started on learning how to make
autotools build our plugin.
  First thing we need to do, is to create Makefile.am which is in the src folder (do not modify the
file in toplevel folder). As we are no longer compiling independent program, we need little bit
more complicated file to do the trick, as you can see below:

lib_LTLIBRARIES = libpart2.la

AM_CFLAGS = -Wall @XMMS_CFLAGS@ @CFLAGS@

libpart2_la_LDFLAGS = -module -avoid-version
libpart2_la_SOURCES = plugin_main.c

 First line tells to automake, that our output file should be called libpart2.la (although this is not the file,
that you need for xmms), second line is compile time flags (you might remember this from the previous
example) added with some additional variables. @XMMS_CFLAGS@ and @CFLAGS@ variables
will contain flags passed to c compiler.
 Next line tells linker, that we are creating module, and that we do not want version numbering to file
names, and the last line just tells what source files we need to build the module. As you can see, the last
two lines begin with the name that we defined in the first line, so if your plugin file would be called for
example libmyplugin.la, you would need to rename those lines to begin with libmyplugin_la (remember
to replace '.' with '_' ).

 Next thing we need to rewrite it is configure.in file in the toplevel folder, and as you can see, this
one is also quite much more compilicated:

AC_PREREQ(2.58)
AC_INIT(Tutorial part 2,1.0.0,[email@hotmail.com],part2)

AC_CANONICAL_TARGET([])

AM_INIT_AUTOMAKE([part2],[1.0.0])
AC_CONFIG_SRCDIR([src/plugin_main.c])
AM_CONFIG_HEADER([config.h])
AM_DISABLE_STATIC

AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_LIBTOOL

AM_PATH_XMMS(1.2.9,,AC_MSG_ERROR([XMMS >= 1.2.9 not installed]))

AC_CONFIG_FILES([Makefile src/Makefile])
AC_OUTPUT

 Now that we have done rewriting files, all we need to do, is to run autotools commands that will
generate files needed to build project. And as we are creating library module, we need to execute
the following commands in this order:

aclocal
libtoolize --force --copy
autoheader
autoconf
automake -a -c

 New command that has appeared to the sequence is libtoolize, and purpose of the command
is to add libtool infrastructure to your project. First 4 commands should not give any output, only
automake should say that is has installed some files.

 After all this, you can once again run ./configure ; make , and if you are brave enough, you can try
to copy file from src/.libs/libpart2.so to ~/.xmms/Plugins, restart xmms and open visualization plugin
page to see if this plugin shows up (it should).
 Because this plugin really does nothing, you can safely try to enable / disable it, and.. well nothing
happens, but hey atleast we have our plugin in the list.

1.7) Weblinks for autotools

http://www.amath.washington.edu/~lf/tutorials/autoconf/toolsmanual_toc.html
* This page is bit old, but still gives quite a lot of information

http://www.gnu.org/software/automake/manual/automake.html
* Manual page for automake

http://sources.redhat.com/autobook/
* Tutorial book for autotools