Pre-compiled libraries are very useful if you want to provide users with functions while keeping the implementation source code secret.
In computer science, a static library or statically-linked library is a set of routines, external functions and variables which are resolved in a caller at compile-time and copied into a target application by a compiler, linker, or binder, producing an object file and a stand-alone executable.[1] This executable and the process of compiling it are both known as a static build of the program. Historically, libraries could only be static. Static libraries are either merged with other static libraries and object files during building/linking to form a single executable or loaded at run-time into the address space of their corresponding executable at a static memory offset determined at compile-time/link-time. https://en.wikipedia.org/wiki/Static_library
A library is cooked in the context of a particular project. From the main menu, select:
File→New→C Project
In the C Project form, choose a name for your library (e.g. 'pomadlib') and select Static Library→Embedded C Library as Project type:
Click Next, and then select the target device:
Click Finish.
Your workspace now includes a new project 'pomadlib' with a pretty empty structure:
Build-up a minimal project structure including:
A this step, you may already try to reach the build button. If everything goes well, you'll get a clean build report:
Note that a new Debug\ folder has been created together with the compiled library 'libpomadlib.a':
So far, the library is pretty useless, so let us write a basic function.
First, edit the build setting (project properties) :
Then edit the pomad.c source file. Let-us write a simple demo function that computes the cumulative sum of n bytes, the latter beeing provided by means of a pointer:
/*
* pomad.c
*
* Created on: 30 mars 2020
* Author: Laurent
*/
#include "stm32f0xx.h"
uint16_t pomad_csum(uint8_t* byte_array, uint8_t n)
{
uint8_t i; // Loop counter
uint16_t csum; // Cumulative sum
csum = 0;
for (i=0; i<n; i++)
{
csum += byte_array[i];
}
return csum;
}
Build the project and make sure there are no warnings or errors.
The 'libpomadlib.a' file is now ready for use in another project. Yet, you have to provide future users with information regarding available functions in the library, and how to use it. Remember that the source code will not be available. Common practice is to write a well commented header file:
/*
* pomad.h
*
* Created on: 31 mars 2020
* Author: Laurent
*/
#ifndef POMAD_H_
#define POMAD_H_
/*
* Compute the cumulative sum of n bytes in a array
*
* Parameters:
* - pointer to the byte array
* - 8-bit number of bytes to sum up (max 255)
*
* Returns
* - The 16-bit cumulative sum
*/
uint16_t pomad_csum(uint8_t* byte_array, uint8_t n);
#endif /* POMAD_H_ */
The compiled library is now ready for distribution. You only need to provide:
You can copy/paste those two files from the library project directory to some other location on your file system for sharing among several projects. For instance, I created a mylibs\ folder beside my workspaces folders under C:\Atollic\:
If you like, you can try to open the 'libpomadlib.a' file with a text editor. You would see that your precious intellectual property is safely protected!
Close the 'pomadlib' library project and open the now usual 'my_project' tutorial project. Time has come to sum-up some bytes...
Open the build settings dialog.
Apply these changes and then close the project properties dialog. Verify that the project explorer displays the 'pomad.h' header in the Includes category:
That's it, you can now use the library functions in your own project:
Edit the main() function as follows:
#include "stm32f0xx.h"
#include "main.h"
#include "bsp.h"
// Include library header
#include "pomad.h"
// Static functions
static void SystemClock_Config (void);
// Main program
int main()
{
uint8_t my_array[6] = {2, 8, 5, 12, 7, 9};
uint8_t i;
// Configure System Clock
SystemClock_Config();
// Initialize console
BSP_Console_Init();
my_printf("Console Ready!\r\n");
my_printf("\r\nByte array is ");
for (i=0; i<6; i++) my_printf("%d ", my_array[i]);
my_printf("\r\nCumulative Sum = %d\r\n", pomad_csum(my_array, 6));
while(1)
{
// Do nothing
}
}
By the way, look at the editor syntax coloring. Your library function is recognized just like any other function from C standard libraries. Hover the mouse over it and you'll get the header information:
Build and run the project:
That's cool stuff!
Remember that pre-compiled means... compiled! Because we selected a target before building the library, it should be re-compiled for use with another target device.
In the library cooking project, we have nothing like startup code and software entry point (i.e. main() function) that permits in-circuit debugging. A good idea would be to develop library functions within an executable project, do extensive debug, and then package validated functions into a library project.