Let's split and MAKE friends....

After a while, you'll start to find that your source files will become overly large and debugging will become a problem to say the least. This is where splitting the source files into smaller chunks and the use of a make file comes in handy. Up until now, all the sources you have seen here have been small and pretty simple to follow. This is fine, however for clarity they are better split into smaller chunks.

The key to getting a program to work is forethought and planning. Really speaking, no program should be even started before a plan and flowchart is produced and the functions defined on paper. While this is time consuming, it does cut down on the amount of problems just going headlong onto the programming will cause. Imagine writing something as complex as RISC OS without planning!

When looking at the source, it is wise to bundle all the functions pertaining to the one task in one source file. For instance, all the MessageTrans and lookup functions would be in one source file, all the quit functions in another, all window creation and icon creation in another and so on. While this may seem like a lot of sources for a small task, it does have a major advantage - ease of debugging. There is nothing worse than trawling though a mass of source code for (say) a quit error when looking simply at a quit source file makes the task simpler.

As with all that is helpful, there is a downside - the make file. In it's simplest terms, a make file is a script which compiles and links all the source files together using preset rules. A secondary problem (for us) is that there are 3 different make applications, GNUMake, Acorn Make and EasyC's own make system.

Back in Volume 13 (issue 10) Tony Houghton described in great detail the construction of a make file. I would suggest contacting Archive for a back issue or getting the double CD and reading it. The article covered everything.

Errors when linking

One problem of multiple source filed programs are linking problems. Remember, when a compiler compiles a source file, it knows absolutely nothing of the other source files unless you tell the compiler in the source file that such and such exists elsewhere. This is performed using either a header file or the extern command.

Header files

Header files should contain the function prototypes for the functions contained within that particular source file.

For instance

/* example - eg.c */

int function_a(char *file)
{
  // code
  return a_value; // can be anything!
}

char *lookup(char *token)
{
  // lookup function
  return msg_out;
}

static void print_hello(void)
{
  printf("hello\n");
}

would have in the header file

/* eg.h */

extern int function_a(char *file);
extern char *lookup(char *token);

(why would you not include the static void function?)

eg.h would be included in any of the main source files where either or both of these functions are called. The compiler then knows that these will be defined elsewhere, checks the number and type of parameters passed, reports if these are incorrect or compiles the code. The link errors occur when the linker attempts to create the full application and fails to find a function or variable not defined anywhere, but addressed via header file or extern.

Don't panic if you find a link error!

When Acorn Make attempts to link and finds errors, these are reported in the form

function_a found in o.file_create
c found in o.file_create

All you need do then is go back to c.file_create and add

#include "eg.h" or extern int c;

then re-execute the make file.

Such splitting of the sources has the added advantage of once they are working, they never need to be looked at again, they can simply sit there and be forgotten about!.

Next time : Back to the Wimp.