Libraries in MPLAB® X IDE
Background
To understand how libraries are created and may be used in a project, it is important to understand some details about how a project is built [Figure 1]. In a typical application, source code is compiled into object files (one object file for each source file). Object files contain compiled code where none of the variables or code blocks have been assigned addresses in the device's memory map. In other words, an object file is relocatable because, in theory, all of its items may be located anywhere in the device's memory. The job of assigning addresses falls to the linker. It takes the information in the object file and device memory map information from a linker script file and assigns variables to specific addresses and arranges code blocks to best fit in the available memory. The linker script provides all of the fixed addresses of a device's registers and program memory regions. The linker is the tool that creates the HEX file that will ultimately be programmed into the device.
All of the above is true for assembly programming too, as long as you write relocatable assembly code which uses a different set of directives from absolute assembly code. Absolute assembly code specifies addresses in the code itself (using directives like org, equ, or cblock) and therefore is never passed to the linker. This means that absolute assembly projects cannot use libraries generated as outlined below or be used to implement libraries. Relocatable assembly uses directives like code and res which are handled in much the same way as C variables and functions, making it possible for code written in this fashion to be used for and with libraries.
When you create a library project [Figure 2], the build process is slightly different. After the compiler generates the object files, they are not passed to the linker. Instead, they are passed to the librarian (sometimes called the archiver). The librarian collects all of the object files generated by the compiler and puts them into a single "container" file called a library (or archive). None of these object files in the library have been through the link step, so all of their objects (variables, functions, etc.) have not been assigned an address in memory. This means that these objects can easily be mixed with another project's code where both that project's objects and the library's objects will be assigned addresses when the project is built and they are all passed through the linker.
Once you have created a library file, it is ready to be used in a project [Figure 3]. In a typical project, you will have some code specific to that project that calls functions included in the library. The glue that makes this possible is a header file associated with the library that contains function prototypes for any functions in the library that you wish to make available to users of the library. These function prototypes expose the functions to the outside world by telling the compiler what the function looks like (declaration), even though the implementation (definition) of the function is in the library and not seen by the compiler. The compiler generates its object files with names referring to these library objects, and the linker cleans up everything in the end by tying all the appropriate items together.
Everything above describes the mechanics of how the compiler, linker, and librarian interact with each other.