Using FreeBASIC Built Libraries with GCC
 
by Jeff Marshall

Shows how to create a static library with FreeBASIC and then call it from a C program using GCC as the compiler.

  • Minimum fbc version tested is v0.18.2b

This article shows Windows usage throughout, but application to FreeBASIC on other platforms is similar.

In this tutorial:
A Simple Test

For this simple test we are going to create a FreeBASIC static library, one without any dependencies. This will make it easier the first time around, and will allow us to check that the basics are working:

First we need a library, and for for this it will be just a single trivial function that will add two integers together and return the result. Notice the use of cdecl and Alias in our procedure definition. By default, C uses the cdecl calling convention. Using Alias in the FreeBASIC declaration makes matching case sensitivity between FreeBASIC and C easier. C is case sensitive, whereas FreeBASIC normally is not.

'' mylib1.bas

Function Add2Numbers cdecl Alias "Add2Numbers" _
    ( _
        ByVal x As Integer, _
        ByVal y As Integer _
    ) As Integer

    Return x + y

End Function


Create a file called mylib1.bas as above and compile it with:

fbc -lib mylib1.bas.

This will create our static library libmylib1.a. Next we need a C program that is going to call the library we just made. We must add a prototype that exactly matches the function we have in the FreeBASIC library. The C listing below is our main entry point, will set up a couple of variables to call Add2Numbers(), and print the results.

/* test1.c */

#include <stdio.h>

/* Prototype from libmylib.a */
Int Add2Numbers( Int x, Int y );

Int main ()
{
    Int a = 5;
    Int b = 7;
    Int c = Add2Numbers( a, b );

    printf( "a = %d\n", a );
    printf( "c = %d\n", b );
    printf( "a + b = %d\n", c );

    Return 0;
}


To compile this C program using the FreeBASIC library we just made we need to compile test1.c as we normally would but also tell it which libraries are needed. In our case, it is libmylib1.a.

gcc test1.c -L . -l mylib1 -o test1.exe

The '-L .' option tells the linker to search in the current directory for libraries, and the '-l mylib1' indicates that we want to link with the library we just created. This is the simplest case becase the libmylib1.a library has no dependencies. If mylib1.bas needed other libraries, for example the FreeBASIC run-time library libfb.a, we would need to specify that as well to gcc.


FreeBASIC Library With Dependencies

Here we create a FreeBASIC library that uses some features from the FreeBASIC runtime and graphics library. In this case we will have to specify any additional needed libraries to GCC.

'' mylib2.bas

Sub TestGfx cdecl Alias "TestGfx" ()

    Screen 12

    Line (0,0)-(100,100),15

    Sleep

End Sub


Create a file called mylib2.bas with the listing above and compile it with:

fbc -lib mylib2.bas.

This will create our static library libmylib2.a. Next we need a C program that is going to call the library we just made. We must add a prototype that exactly matches the function we have in the FreeBASIC library. This C listing will provide our entry point and just call TestGfx() before terminating.

/* test2.c */

void TestGfx();

Int main()
{

    TestGfx();

    Return 0;

}


To compile and link test2.c directly with gcc, not only do we need to tell gcc that we want to link with libmylib2.a, but also every other library that libmylib2.a needs.

gcc test2.c -L. -lmylib2 -L"C:\FreeBASIC\lib\win32" "C:\FreeBASIC\lib\win32\fbrt0.o" -lfbgfx -lfb -lgdi32 -o test2.exe

Depending on what our FreeBASIC library uses, it we may use several additional libraries, we must specify all the names of the libraries on the gcc command line. In this example, FreeBASIC is located in "C:\FreeBASIC", but you should specify whatever directory you installed FreeBASIC to. "C:\"FreeBASIC\lib\win32\fbrt0.o" is a special startup file that will initialize the FreeBASIC runtime library. More specifically, it is initialized after the C runtime library, but before any of our program code is called. The additional -lfbgfx, -lfb, -lgdi32, are the additional libraries needed to complete linking. The actual libraries will vary depending on which FreeBASIC runtime functions are used, and which platform, for DOS or Linux, the program is being compiled for.


Using FreeBASIC as a Smart Linker

FreeBASIC has a neat built-in feature that stores a little bit of extra information in the library indicating what compile time options were used, and which dependent libraries are needed. This is a FreeBASIC only feature, so this kind of capability won't be found when using gcc as the main compiler and linker.

If we reuse the examples from the previous section, mylib2.bas and test2.c, but just go about compiling and linking them differently, we can save ourselves a bunch of typing. Plus we usually won't have to know or remember what our FreeBASIC built library's dependencies are. Compile mylib2.bas as before in to a static library.

fbc -lib mytest2.bas

Next we compile our C test program. Notice the '-c' option for the gcc command line. This indicates that we are just going to compile the C source, but not link it yet. test2.o will still have the entry point, but we are going to put it in an object file instead of trying to create an executable right away.

gcc -c test2.c -o test2.o

Lastly, we use fbc to perform the link step. We are not compiling any basic source files here, but we are going to use the smart linking capabilities of FreeBASIC such that the command line is fairly simple:

fbc test2.o -l mylib2

This will create an executable named test2.exe because test2.o was specified first on the command line. FreeBASIC will read the extra information stored in libmylib2.a and automatically know which additional libraries to link with. That's loads easier than using gcc directly, especially when many extra FreeBASIC built libraries are needed.


See also