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 similiar.
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