# GUM v.1.0.0

# 41

# Compiling plug-ins

In this chapter will we try to explain how to compile plug-ins so they can be used in Gimp.

## What is a plug-in?

A plug-in is a program that can't run on its own, it needs to be started by Gimp.

## Compile?

Most of the time, plug-ins are distributed in the source code. All programs have a source code (if they aren't written directly in machine code). The source code is written in a language humans can understand, like C, C++ etc...

The computer doesn't understand C or C++, so the code needs to be translated to machine code which the computer understands and can execute. This translation is called compiling.

### What way to go when you want to compile

There are three common ways to compile; Make, Configure and Plain cc. This is not totally correct, but it's good enough for now. You can also use gimp-tool to build and install a plugin if it's only one .c file see appendix B.

Make is a program which takes a specification file, commonly called Makefile, and by running this file it compiles the program with the help of the compiler.

Configure is a program that generates a Makefile. After doing this you will have to run Make in order to compile.

The most simple way is to use the compiler directly to compile the code.

We will try to explain how to handle these three types of compiling. But before we start, we must tell you that we can't cover every angle or error that can arise when you compile. We will cover the basics, but not extras like special compiler flags, debugging etc.

We really want you to try to compile a plug-in even if you aren't a programmer or hacker. If you have a friend who is a Unix programmer, we still think you should read this chapter and try to compile, and if it goes totally wrong anyway, call in your mate.

## How to obtain and install the source code

Most of the time, you will go to the plug-in registry or the `Gimp.org ftp` site to obtain/download the source code. Other sources of information are Gimp News and the Gimp developer / Gimp user mailing lists.

### Unpacking the source code

When you have downloaded the source code, you must unpack it. Usually, the code ends with `xxx.c.gz`, `xxx.tgz` or `xxx.tar.gz`. The `xxx.c.gz` can be decompressed with `gunzip xxx.c.gz`, and the `xxx.tgz` and `xxx.tar.gz` archives can be unpacked with `gunzip xxx.tgz && tar xvf xxx.tar`. Before you unpack the source, do the wise thing and move it to a new directory. Then unpack and build the plug-in. For example write: `mkdir build; mv xxx.tgz build; gunzip xxx.tgz && tar xvf xxx.tar` in an Xterm window.

If the source ends with `xxx.c`, then everything's fine. You don't need to decompress it, because it has already been done. Just save it if you use Netscape. One thing to remember if you use Netscape is that Netscape often tries to decompress the archive, and it may also fail to do this. If this is the case, check the source file `xxx.c` with a file viewer like More (for example `more xxx.c`). If you can't read what's in the file, then it's not decompressed. To fix it, write: `mv xxx.c xxx.c.gz && gunzip xxx.c.gz`.

## Compiling the code

We will use GNU tools to compile the code. If you are using a system that doesn't have GNU tools installed, then you have two options: either download and install GNU tools (beyond the scope of this book) or use the system's own tools.

There is no big difference between GNU and system tools. Some of the GNU tools can be recognized by the fact that their names start with the letter g. For example, the GNU compiler is called gcc and the system's own compiler is called cc. We think that this won't make any difference here, but we can't be sure because there are a lot of different Unix systems out there, and we cant cover them all.

### Finding out how to compile the plug-in

When you have downloaded and unpacked the plug-in source, you have to find out how to compile it. The plug-in are often packed with several other files. Sometimes there is a `README` or `INSTALL` file. If you find one of these files, always read it (write `more README`).

Most of the time, you will find information on how to compile and install the plug-in in one of these files. You can also take a look in the head of the C code file. If there is no information, then you have to follow our examples here, and even if you do find some information, you are advised to read on.

The `README` file will also hopefully tell you whether you need some additional libraries to compile the plug-in. For example, you may need the`libtif` library and header files in order to compile the plug-in. If you don't have these libraries or header files, the building of the plug-in will fail.

You can most likely find out if you have this libraries, or other required programming by reading the chapter about installing the source distribution of Gimp in Chapter 4.

Compiling a library is a bit different than compiling a plug-in., but the start is basically the same, so keep on reading.

If the plug-in you've downloaded is a single file, or if the archive you just unpacked has no Makefile (it can be named Makefile, Makefile.classic, MAKEFILE etc.) or configure file, then you have to compile it directly with gcc or you have to create a Makefile or configure script.

If there is a Makefile then you can use make to compile the plug-in. But before you begin, you have to check and perhaps edit the Makefile to find out whether it is correct for your system.

If there is a configure script, then use it to generate a Makefile

### Using GCC to compile the plug-in straight off

#### A first try

If the file is named `plugin.c`, then compile it with `gcc -o plug-in plugin.c`. The `-o` flag tells the compiler that the final output (the plug-in) should be named plug-in. If your C-compiler (GCC) is configured to search the standard directories for the include and library files, and those files are indeed in the standard directories, then the plug-in will compile cleanly. But most of the time this is not the case since you probably will need specific Gimp libraries and include files.

Here is an example of what happens if you compile the waterselect.c file this way: (only some of the lines)

    /tmp/cca017741.o(.text+0xc): undefined reference to `gimp_main'
    /tmp/cca017741.o(.text+0x87): undefined reference to `gdk_input_list_devices'
    /tmp/cca017741.o(.text+0xc5): undefined reference to `g_strcasecmp'
    /tmp/cca017741.o(.text+0x626): undefined reference to `gtk_preview_get_type'
    /tmp/cca017741.o(.text+0x632): undefined reference to `gtk_object_check_cast'
    /tmp/cca017741.o(.text+0x63d): undefined reference to `gtk_preview_draw_row'
    /tmp/cca017741.o: In function `update_buckets':
    /tmp/cca017741.o(.text+0x682): undefined reference to `gtk_widget_draw'
    /tmp/cca017741.o: In function `update_gimp_color':
    /tmp/cca017741.o(.text+0x6e2): undefined reference to `gimp_palette_set_foreground

#### Libraries

This happens when the libraries needed aren't linked to the executable that you are trying build. A library is a set of functions, for example a function which creates a window or a scrollbar. The plug-in will call different functions in these libraries, like the function `gtk_object_check_cast`. That's why you have to tell the executable where to find these libraries so they can be called by the plug-in.

#### Another try

Now let's try to compile it with `gcc -o plug-in plugin.c -L/usr/local/lib -lgtk -lgimp`. Now the plug-in compiles cleanly on the system. We work on Linux, but if I had been on my Sun Solaris system, I would have to add -`I/usr/local/include` before even starting to think about libraries.

#### Include file

The error messages telling you that an include (header file) is missing goes like this:

    waterselect.c:39: gtk/gtk.h: No such file or directory

What does this message really mean? It says that a file named `gtk.h` is missing, but this is not always the case. A more correct answer is that the compiler (more accurately the preprocessor compiler) can't find it in the directories it was configured to search.

We have to tell the compiler where to search for the file. We can do that by adding a `-I/where/to/search` Because the file is located in `/usr/local/include/gtk`, and the error was can't find `gtk/gth.h`, this tells us that the compile line will be:

    gcc -o plug-in plugin.c -L/usr/local/lib -lgimp -lgtk -I/usr/local/include

The `-I/usr/local/include` that we added tells the compiler to search that directory for include files, in our case `gtk/gtk.h`. The compiler will find the file because it will add `gtk/gtk.h` to`/usr/local/include`. This will give us `/usr/local/include/gtk/gtk.h` which is where the file is located.

#### T he -L flag and how to find out which libs to link

The -L flag works the same way. It tells the compiler where to search for libraries, in this case the libraries `libgimp.so` and `libgtk.so`. The `-lgimp` is just a short cut so we don't need to write`libgimp.so`.

How do we know which libraries to add and which directories to include? We have to take a look inside the code to get a hint about what to add (generally located in the beginning of the file). Here's an example from the `waterselect.c` file.

    #include <stdlib.h>
    #include <stdio.h>

    #include <math.h>
    #include <gtk/gtk.h>
    #include "libgimp/gimp.h"

This code tells us that the compiler will include five files when it compiles the code. The first three are ordinary standard C include files, and the other ones are special Gimp and gtk files.

#### The -I flag

The standard C header files are in located in a standard include directory, which the compiler will search. However, the `gtk.h` and `gimp.h` files aren't in a standard directory, so we need to tell the compiler (`-I flag`). If the -`I flag` is /`usr/local/include`, the compiler will try to get the `gtk.h` files in `/usr/local/include/gtk/gtk.h`.

The source code lines can also give us a hint on which libraries to link with; in this case `libgimp` and `libgtk` (the standard C library and Math library are linked by default on most systems)

#### What to do when there are several source files

Now we've hopefully learned how to compile a plug-in that is made up of a single C source code file. However, a plug-in can be contain more that one C source code file. How do we compile such plug-ins?. If the extra file is a header file, (named `plugin.h`) then we can compile the plug-in just as we did before. The header file is only a file which specifies functions, and how you should call these functions. We only have to look at the files (or just the header file) to find out what include directories to include, and which libraries we need to link.

What should you do if the plug-in is built up of several files? (like this plugin:.`h pluginmain.c pluginpart1.c pluginpart2.c` etc.) If this is the case, we will have to attack the compiling a bit differently. First, we need to compile each part separately, and then compile (or more exactly link) them to an executable plug-in.

What we need to do is to make object files out of each part. These object files will then be linked together, thus creating the final executable plug-in. We will give you an example:

    gcc -c pluginmain.c -I/usr/local/include
    gcc -c pluginpart1.c -I/usr/local/include
    gcc -c pluginpart2.c -I/usr/local/include
    gcc -o plug-in pluginmain.o pluginpart1.o pluginpart2.o -L/usr/local/lib -lgtk -lgimp -lgimpui -lmpeg

The first three lines is where we make the object files. We tell the compiler to make object files by adding the `-c` flag. When we make object files we don't need to worry about libraries, we only have to make sure that the compiler finds the include files. That's why we only need to use the `-I` flag when we create the object files.

The last line is where we make the final plug-in. Here, we don't need to worry about include files. We only have to make sure that we link the libraries needed by the plug-in. We can look at it this way: when we make the object files, we include descriptions of library function calls by including header files. The plug-in object file will happily use them, because it assumes that it will be linked to these libraries later on.

This is what happens in the last line: Here we tell the compiler that the final outcome will be a plug-in. We do this by adding `-o plug-in`, then we add all the object files we made in the first three lines. Because we have used a lot of library functions in the object files, we have to add the libraries to provide these functions to the plug-in. We do this by `-lgimp -lgimpui` etc. We also tell the compiler where to search for the libraries by adding `-L/usr/local/lib` (the directory /`usr/lib` and`/lib` are also searched by default).

A big program or plug-in can consist of several parts. If your dealing with such a plug-in, compiling the different parts manually is often the wrong way to go. The reason for this is that if something goes wrong, you will have to type all your commands again. The solution is to create a Makefile. A Makefile is a specification which the Make command uses as an input to compile the entire plug-in with the help of the compiler.

### How to create a Makefile and how to use it

Now we'll take a look at how to create a simple Makefile. This will help us understand the structure of a Makefile, so that we'll know how to edit a Makefile which comes with a plug-in. We will take a quick look at a generic Makefile

    CC = gcc
    INCDIR = -I/usr/local/include -I/usr/local/tiff/include
    CFLAGS = -O2
    LIBDIR = -L/usr/X11/lib -L/usr/local/lib
    LFLAGS = -lgimp -lgtk -lX11 -ltiff -lgimpui
    HEDERS = plugin.h plugin2.h
    SOURCES = pluginmain.c pluginpart1.c pluginpart2.c
    OBJECTS = pluginmain.o pluginpart1.o pluginpart2.o

    plug-in: $(OBJECTS) $(HEADERS)
            $(CC) $(CFLAGS) -o $@ $(OBJECTS) $(INCDIR) $(LIBDIR) $(LFLAGS)

This Makefile will first build the object files, and then link the plug-in. All you have to do if you want to use it is to replace the header, object, and source files with the correct ones. You can also change what libs to link, and what directories to search for libs and includes. The `CFLAG -O2` stands for optimization of the executable. Notice the tab at the last line. If you forgot the tab you will get this error message:

    Makefile:11: *** missing separator. Stop.

#### A Makefile example

Here's how the Makefile looked when we built the Guash plug-in at our Linux system (there is a Makefile included in the distribution of Guash, this example is only for training)

    CC = gcc
    INCDIR = -I/usr/local/include
    CFLAGS = -O2
    LIBDIR = -L/usr/local/lib
    LFLAGS = -lglib -lgdk -lgtk -lgimp
    HEADERS = guash-directory.h guash-banner.h
    SOURCES = guash.c
    OBJECTS = guash.o

    guash: $(OBJECTS) $(HEADERS)
           $(CC) $(CFLAGS) -o $@ $(OBJECTS) $(INCDIR) $(LIBDIR) $(LFLAGS)

The important thing is to change, and maybe add include and library directories so it will fit your system. We hope you're now able to edit a Makefile so it will fit your system. You have to remember that you can write a Makefile in several different ways, this is only one of many.

#### Variables

When you edit another makefile it may not look like this, but with the basic knowledge and the knowledge of how to compile by hand, you should be able to edit it. As you see, the first eight lines are variables which are called later in line 10 and 11 with `$(VARIABLE)`. The special `$@` variable is an internal variable which will expand to the first word in the line above it (i.e guash in this example).

To build the plug-in, simply invoke Make by typing `make` or `make -f WhatYouCallYourMakefile`. Make will now invoke gcc to build your object files and to link your executable.

A common error when you compile a plug-in which comes as an archive with a Makefile, is that the Make-program complains about dependencies. If so, remove the.deps directory (`rm -rf .deps`) in the building directory. Dependencies can also be included in the Makefile. If so, you will find them in the end of the file. Remove them and everything should work fine.

### Configure a way to automate the building process

The configure script that comes with the plug-in is a way to automate the process of making a Makefile. This script will try to find the include files and libraries that the plug-in needs.

If you are on a common UNIX platform like Solaris, Linux etc. then it's generally quite simple to use a configure script. To build your plug-in, type the following in the directory where you unpacked the plug-in: `./configure && make` Now the plug-in will be compiled and ready to use. Do make sure that you are in the directory where the configure script is located. Other wise you will get this error message: `bash: ./configure: No such file or directory`.

If you don't have a certain file or lib, or the script can't find it, then you have to install it or tell the script where to find it.

To find out how to tell the script where to find include files and libraries etc. invoke the script like this: `./configure --help` This will print several lines of flags that you can supply the script with. Here's an extract of the most important flags that you can include in your script:

    --libdir=DIR
    --includedir=DIR

With these two flags you can add an include/library dir like this `--includedir=/your/includedir`. If you want to add more than one include dir, you have to do it this way if you work in an ordinary shell:

    export CFLAGS="-I/one/includedir -I/another/includedir"

If you are working in a C shell, then you have to do it like this:

    setenv CFLAGS "-I/one/includedir -I/another/includedir"

If you want to add more than one libdir, type the same as for the CFLAGS, but write LDFLAGS instead.

Configure is not bullet-proof, and you may run into several problems, especially if you are using a UNIX dialect which is different from what the configure authors were working on. If you run into this kind of problems, first try to add all the lib and include dirs to the script with the FLAGS, or to add them by hand in the generated Makefile. If this still doesn't solve the problem, try writing a mail to the Gimp mailing list.

Generated by fmtoweb (v. 2.9c) written by Peter G. Martin <peterm@zeta.org.au> Last modified: 20 May 1998