PS2 Linux Programming
The Development Process
The following programs are used in the development
process:
emacs This is a common text editor which is
available for just about any platform, Linux included.
gcc This is the GNU C compiler. The PS2
Linux kit comes with a special version of gcc that knows about the PS2
hardware.
g++ This is the C++ version of gcc.
make This program automates the build
process.
The starting point will be the standard “hello world”
Program. Create a file called “main.c”. At the Linux command prompt, type:
$ emacs main.c
This will open emacs and start editing “main.c
Enter the basic “hello world” program.
#include <stdio.h>
int main (void)
{
printf (“hello world\n”);
return 0;
}
Save the file using Ctrl-X,Ctrl-S, then quit using
Ctrl-X,Ctrl-C.
The compiler is called with a few arguments telling it
what to build, and how to built it. Type the following at the command prompt:
$ gcc –o main main.c
The “-o main” part tells gcc what to call the
output file. Assuming the program was correct, gcc will make a file
called “main”.
To run the program, type the following command at the prompt:
$ ./ main
The “./” at the start tells Linux to look for the program
in the current folder.
If everything went to plan, the program should output
“hello world”.
All the above is just fine if there is only a single
source file, but for multiple source file things need to be treated
differently. In the above examples, gcc performed the compile and link
steps in a single shot. With more than one file, things need to be done
separately. Intermediate object files are explicitly created (which have the
extension “.o”) for all the source files, and then linked together to form the
final executable binary file. For instance, to compile a program that resides
in “file1.c”, “file2.c” and “file3.c”, the following commands could be used:
$ gcc –c file1.c
$ gcc –c file2.c
$ gcc –c file3.c
$ gcc –o big_program file1.o file2.o file3.o
The “-c” option tells gcc to compile the file but
to go no further. By default, this will generate an output file called
“<filename>.o”.
As can be imagined, running gcc with a string of
arguments for each source file will get tedious and prone to error. The make
utility can be used to improve the process. Make works out what needs to be
built and in what order to perform the build. Make then builds the executable
program.
Before make can proceed, it needs to be told how to build
the executable. Make reads its input commands from a file called “Makefile”
(note the capital 'M') in the current directory. This file contains rules on
how to build files. See 'info make' (at the command prompt) for
more information.
Creating makefiles will not be covered in detail in this
tutorial. The makefile given at the end of these notes can be used to build
executables from most of the C files that will be used in this tutorial series.
Note that lines beginning with # are comment lines in a makefile.
Save this makefile into the working directory directory
along with the source files. Type:
$ make
Messages should appear as make runs various programs to
build the executable. Run the program using:
$ make run
or it can still be run with:
$ ./main
The comment lines in the make file outlines what is going
on.
Make files are well documented and it is possible to find
out exactly what is going on by reading the documentation. All that needs to be
know for now is that to add new files to the project, simply add the file name
to the OBJS list. For example if the file goodbye.c is to be added to the
project the file name goodbye.o needs to be appended to the OBJS line within
the makefile.
Any header files that are used are included as
dependencies in this makefile. If new header files are added to any of the
source files, or the arrangement of header files is changed, the dependency
file (.depend) must be recreated by executing:
$ make depend
To start from fresh build, all the intermediate files that
have been created are deleted with:
$ make clean
Rebuild the executable file with:
$ make depend
followed by:
$ make
The CFLAGS (Compiler flags) variable in the make file is
set to the equivalent of a debug build as it tells gcc to put debug information
into the program which can be used by a debugger. Once the development of a
program has been completed, it can be made to run faster by replacing the debug
flag (-g) with something like “-O3” (a letter O then three not zero-three).
This causes gcc to optimise the code at optimisation level 3 (3 is the fastest
but will take longest to compile). Levels 1 and 2 can be used for faster
compile times at the expense of a little execution speed.
It is recommended that all compilations are performed with
the –Wall compiler flag. This is a very strict mode that treats warnings as
errors. This is a good practice as it can stop unforeseen problems from arising
( this is especially important for PS2 development as locking up the PS2 is a
hassle and generally requires a reboot). Other compiler options can be found by
reading the gcc/g++ manual – see the links below.
Debugging
Debugging on PS2 Linux can be accomplished using GDB. This
debugger is far from great and is rather buggy. It is possible to debug without
this tool with the use of printf statements to the console at any point in a
program. Experiment with the development environment to come up with a method
of debugging that is most convenient.
Assert are a very useful debugging tool. In order to use
assert in a program, conditions that must be true if the program is running
correctly are found and tested with an assert. For example, if x must be equal
to zero at a certain point in a program then the statement - assert(x == 0) – is entered into the code at
that point. If this condition is not true. the code will exit with an error
message and the program can be investigated to find out what is causing the
assertion to fail.
When writing Playstation 2 Linux programs try not to crash
the machine. With PS2 Linux there is the risk of damaging the file system if
there is a crash. Also PS2 Linux takes a long time to reboot after a crash so
it is best that the code is protected as much as possible with asserts. Always
double check the code before it is executed.
Manuals
The GNU manuals are very useful and can be found online
here:
GNU Make:
http://www.gnu.org/software/make/manual/make.html
GCC and G++:
http://gcc.gnu.org/onlinedocs/
(The version included with PS2 Linux is 2.95.2)
GDB:
http://www.gnu.org/manual/gdb-4.17/gdb.html
Manuals for certain tools can be browsed on the kit by
typing:
“$ man <program>”
e.g. “man g++” will provide the g++ manual.
A similar command is “info <program>”.
Dr Henry S Fortuna
University of Abertay Dundee
A standard Makefile
#################################################
# This makefile will build an executable made from C
files.
# Henry S Fortuna
#
# To create the dependency file:
# make depend
#
# To build the executable:
# make
#
# To execute:
# make run
#
# To clean out all objects, targets and dependencies
# make clean
#################################################
# The target name
TARGET = main
# The compiler being used
CC = gcc
# The known file extensions
.SUFFIXES: .c .o
# The object files to build
OBJS = main.o
# The libraries to link
LIBS = -lm
# The compiler flags to use
# -g - produce debugging information
# -Wall - turn most of the important warnings on
# -Werror - treat warnings as errors and abort compilation
# -ffast-math - allow less checking for faster maths
routines
# - fsingle-precision-constant - use single precision
constants
CFLAGS = -g -Wall -Werror -ffast-math
-fsingle-precision-constant
# build the target file from the objects
$(TARGET): $(OBJS)
$(CC) -o
$@ $(OBJS) $(CFLAGS) $(LIBS)
# build the object files from the c source files
.c.o:
$(CC)
-c $< $(CFLAGS) -o $@
# create the dependancy file
depend:
$(CC)
$(CFLAGS) -MM *.c > .depend
run:
./main
# remove all the built files
clean:
rm -f
$(TARGET)
rm -f
$(OBJS)
rm -f
.depend
#include the dependencies into the build
-include .depend
#################################################