Implementing Static Library Compilation in Zephyr

Zephyr has encapsulated a lot of functionality in its build system around CMake, primarily through a series of macros and functions that simplify the declaration of libraries and modules, the addition of source files, the setting of include directories, and linking operations. Below are detailed explanations of some key points:

1.zephyr_library() Macro

lFunction

This macro essentially wraps the CMake add_library() command, but it automatically applies specific settings of the Zephyr build system, such as adding standard compilation options, defining macros, and setting target properties, allowing the generated static library to seamlessly integrate into Zephyr applications.

lUsage Example

In a module’s CMakeLists.txt, you can declare a library like this:

zephyr_library()

zephyr_library_sources(

src/foo.c

src/bar.c

)

zephyr_library_include_directories(include)

This not only adds the source code files to the library but also automatically adds the include directory to the compiler’s search path.

2.Conditional Compilation and Encapsulation

lConditionally Adding Source Files

Zephyr provides macros like zephyr_library_sources_ifdef() that can conditionally add source files to the library based on the value of Kconfig options. For example:

zephyr_library_sources_ifdef(CONFIG_FEATURE_X src/feature_x.c)

Only when CONFIG_FEATURE_X is enabled in Kconfig will feature_x.c be compiled in.

lEncapsulating Include Directories

Similar to adding source files, zephyr_include_directories() and its conditional versions ensure the correct setup of header file directories while remaining consistent with the overall configuration of Zephyr.

3.Module and Global Library Management

lAutomatically Added to Global List

Libraries declared using zephyr_library() are typically automatically added to the global library list (e.g., ZEPHYR_LIBS), so that during subsequent linking stages, Zephyr will link these libraries with the main application. This mechanism hides the complexity of manually managing library dependencies.

lInterface Library Encapsulation

In addition to static libraries, Zephyr also encapsulates the concept of interface libraries (e.g., zephyr_interface_library()), allowing certain modules to expose interfaces without directly participating in compilation, thus enabling more flexible management of inter-module dependencies.

4.Using Static Library Files

Using static library files in Zephyr is primarily accomplished by modifying the CMake configuration files. Below is a common method:

Importing the library in CMakeLists.txt. Add the following configuration in your project root directory (or the application’s CMakeLists.txt file) to import this static library:

# Declare an IMPORTED type static library target

add_library(foo STATIC IMPORTED)

# Set the path to the library file, be sure to modify according to the actual path

set_target_properties(foo PROPERTIES

IMPORTED_LOCATION “${CMAKE_CURRENT_LIST_DIR}/foo.a”

)

# Link the static library to the application

target_link_libraries(app PRIVATE foo)

# If there are additional include directories, they can also be set

target_include_directories(app

PRIVATE

${CMAKE_CURRENT_LIST_DIR}

)

After adding the imported CMake directory to the project, the code directory can be hidden. At this point, the static library contains all the files from the code, but any functions that need to be exposed to the outside must be written in the header file.

|—lib

|—-|—CMakeLists.txt

|—-|—foo.h

|—-|—foo.a

When calling functions from the static library in other C files, include:

#include foo.h

Leave a Comment