Thank to your help, here is a better version of the linux game programming howto. I've corrected the english mistakes, made a better html, added your suggestions and some new stuff. Can you check it again and give me feedback? Thanks. Alex.Title: The Linux Games Programming HOWTO - Part 1
GNUrou@linuxfan.com
, with the help of the LGDC mailing list members (http://sunsite.auc.dk/linuxgames/
)
GCC command line usefull parameters:
> The "-o <name>" option is always used and sets the executable name. If you omit it, it will be a.out.
> The "-Wall" option:GCC supports many levels of warning, all of which may be activated with the command line flag "-Wall". See the GCC documentation for further details. I recommend you to always use this flag if you want to check the quality of your code.
Now we can make the classic Hello World on Linux: Edit a hello.c file:
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Hello World! (From Linux)\n");
return(0);
}
Compile it:
[alex@bluefalcon]~/tut $gcc hello.c -Wall -o hello
(Note:[alex@bluefalcon]~/tut $ is my prompt, so don't type it ;), the command start at "gcc".)
And launch it:
[alex@bluefalcon]~/tut $./hello
Hello World! (From Linux)
> The "-O<n>" option sets the level of optimisation. GCC can optimize your code, and do it well. <n> can currently go from 0 (no optimisation) to 3 (all optimisations). Others optimisation levels will be added in next versions, so <n> can be above 3.
> "-c" tells GCC to compile but not to link. This will create a .o file that you may link later.
Example:
hello.c:
#include <stdio.h>
void print_to_screen(char * s)
{
printf("%s\n",s);
}
main.c:
#include <stdio.h>
#include <stdlib.h>
void print_to_screen(char * s); /* Used to avoid a warning */
int main()
{
char str[]="Hello World!";
print_to_screen(str);
return(0);
}
Now let's compile this:
[alex@bluefalcon]~/tut $gcc hello.c -c -o hello.o -Wall -O6
[alex@bluefalcon]~/tut $gcc main.c -c -o main.o -Wall -O6
[alex@bluefalcon]~/tut $ls *.o
hello.o main.o
[alex@bluefalcon]~/tut $gcc hello.o main.o -o hello
[alex@bluefalcon]~/tut $./hello
Hello World!
"gcc hello.o main.o -o hello" just take the two object files and link them to make an executable.
> "-l<libname>" is used to link your program to a library. Linux use shared libraries to avoid code redundany in memory. Libraries are usually in 3 directories:
main.c:
#include <stdio.h>
#include <stlib.h>
#include <math.h> /* We include maths files headers */
int main()
{
printf("%f\n",sqrt(2));
return(0);
}
If we try to compile like we used to do here is the result:
[alex@bluefalcon]~/tut $gcc main.c -o math
/tmp/ccc02939: In function `main':
/tmp/ccc02939(.text+0xb): undefined reference to `sqrt'
[alex@bluefalcon]~/tut $ls math
ls: math: No such file or directory
That's because the sqrt funtion is in the m library:
[alex@bluefalcon]~/tut $ls /usr/lib/libm.*
/usr/lib/libm.a /usr/lib/libm.so
So we have to compile like this:
[alex@bluefalcon]~/tut $gcc main.c -o mathdynamic -lm
Or if we want a static binary (Which will run even if the library is not on the system):
[alex@bluefalcon]~/tut $gcc main.c -o mathstatic -lm -static
However the static binary size is much more important than the dynamic one!
[alex@bluefalcon]~/tut $ls -l mathdynamic mathstatic
-rwxr-xr-x 1 alex alex 4194 may 13 15:45 mathdynamic
-rwxr-xr-x 1 alex alex 117691 may 13 15:45 mathstatic
To find out what shared libraries a binary program requires use the 'ldd' command:
[alex@bluefalcon]~/tut $ldd mathdynamic
libm.so.6 => /lib/libm.so.6 (0x40013000)
libc.so.6 => /lib/libc.so.6 (0x4002c000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
[alex@bluefalcon]~/tut $ldd mathstatic
statically linked (ELF)
...And if your libraries are in another directory you can add the "-L/usr/my_weird_directory/" to tell gcc to search libraries in that directory too.
The library concept is very important in Linux programming, but we'll have many occasions to work with it later, so don't worry is it doesn't seems clear.
Last thing:if you prefer c++, just change gcc by g++ in the compile command line (or better, get egcs!).
For the moment we have no Makefile, so we got this output.
An example:
We'll use 3 .c and 1 .h files, plus a Makefile:
hello.c:
#include <stdio.h>
#include "defines.h"
void say_hello()
{
printf("Hello World! The square root of 2 is %f!\n",sqrt_of(2));
}
math.c:
#include <stdio.h>
#include <math.h>
#include "defines.h"
double sqrt_of(double x)
{
return(sqrt(x));
}
main.c:
#include <stdio.h>
#include <stdlib.h>
#include "defines.h"
int main()
{
say_hello();
return(0);
}
defines.h:
/* Fonctions prototypes to avoid compilation warnings */
void say_hello();
double sqrt_of(double x);
Makefile:
CC=gcc
CFLAGS=-Wall -O6
LIBS=-lm
OBJECTS=math.o hello.o main.o
PROGRAM=hello
all:$(OBJECTS)
$(CC) $(OBJECTS) $(LIBS) -o $(PROGRAM)
clean:
rm -rf *.o $(PROGRAM)
Some explanations:
Once you have typed all the files, compile them:
[alex@bluefalcon]~/tut $ls
Makefile defines.h hello.c main.c math.c
[alex@bluefalcon]~/tut $make
gcc -Wall -O6 -c math.c -o math.o
gcc -Wall -O6 -c hello.c -o hello.o
gcc -Wall -O6 -c main.c -o main.o
gcc math.o hello.o main.o -lm -o hello
[alex@bluefalcon]~/tut $ls
Makefile hello hello.o main.o math.o
defines.h hello.c main.c math.c
[alex@bluefalcon]~/tut $./hello
Hello World! The square root of 2 is 1.414214!
[alex@bluefalcon]~/tut $make clean
rm -rf *.o hello
[alex@bluefalcon]~/tut $ls
Makefile defines.h hello.c main.c math.c
[alex@bluefalcon]~/tut $
The last thing to know on make: it can take a "-C <directory>" parameter. This will launch make in the directory you specified, and is very usefull is your program is divided into several directories.
Allright! You have the basics of linux programming! Let's now see more game-specific stuff!
That's all for this part. Please give me feedback, so I know what should be seen in the next part (I plan to make our first graphic app using svgalib and GGI). If you have problems with this part, please ask questions to GNUrou@linuxfan.com.
Thank you for reading this tutorial.