libc is a stripped-down C standard library implementation targeted for microcontroller-based embedded systems.
In order to conserve precious memory resources, this library does not supply the complete C standard library implementation. Instead, a subset of functions which are useful on bare-metal embedded systems has been selected. If you have a bare metal or RTOS-based embedded system, this library is for you!
Unlike many other C libraries that I've come across, this library implements unit tests and has addressed long-standing flaws in open-source implementations of the C standard library functions. We're continually adding tests and making additional improvements over the baseline implementations.
free are not included in this library. If you need dynamic memory allocation support, you will need to couple this library with something like Embedded Artistry's
libmemory, which contains implementations of
If you are interested in contributing to this project, please read the
libc is intended to provide a portable set of useful C standard library functions that allows quick bring-up of new bare-metal and RTOS-based embedded systems.
Additionally, we want to provide a high-quality
libc implementation by ensuring that each function has unit test coverage and addresses flaws exposed by the static analyzer. Many C library function implementations remain untested and contain errors. We are fighting back against poor implementations.
In order to conserve memory, this library does not supply the complete C standard library functionality. Instead, a subset of functions which are useful on bare-metal embedded systems has been selected. This selection has primarily been driven by my own experience in microcontroller-focused development. If you need additional features, please file an issue and make a feature request.
The functional implementations in this library have been selected for portability and quick bring-up of new systems. There may be more efficient implementations for these functions, but often they are architecture specific implementations. If you have suggestions for improving performance, we are always happy to hear them.
free are not included in this library. Because memory allocation schemes vary greatly with embedded systems (some not even allowing dynamic memory), you will need to supply your own implementations based on your system's needs. You can couple this library with the Embedded Artistry
libmemory, which contains implementations of
This library provides a complete-enough implementation to compile and link clang's
libc++abi (see Embedded Artistry's libcpp project). In order to achieve this, some functions are only defined in the headers but do not have an implementation. Unsupported-but-defined functions can be removed using a build option (
The following portions of the C library have been implemented:
strtoXfunctions (many via
printffamily (most via
wchartype definitions and
In addition, this library provides implementations for
The following architectures are currently supported:
The following unit tests need to be added:
These are not implemented by may be added in the future:
errnosupport (enabled as a compile-time switch)
FILEand additional stdio functions
We are currently not planning full support for:
At a minimum you will need:
git-lfs, which is used to store binary files in this repository
This project stores some files using
git-lfs on Linux:
sudo apt install git-lfs
git-lfs on OS X:
brew install git-lfs
Additional installation instructions can be found on the
The Meson build system depends on
To install on Linux:
sudo apt-get install python3 python3-pip ninja-build
To install on OSX:
brew install python3 ninja
Meson can be installed through
pip3 install meson
If you want to install Meson globally on Linux, use:
sudo -H pip3 install meson
This project uses
git-lfs, so please install it before cloning. If you cloned prior to installing
git-lfs, simply run
git lfs pull after installation.
This project is hosted on GitHub. You can clone the project directly using this command:
git clone --recursive [email protected]:embeddedartistry/libc.git
If you don't clone recursively, be sure to run the following command in the repository or your build will fail:
git submodule update --init
If Make is installed, the library can be built by issuing the following command:
This will build all targets for your current architecture.
You can clean builds using:
You can eliminate the generated
buildresults folder using:
You can also use
meson directly for compiling.
Create a build output folder:
And build all targets by running
ninja -C buildresults
Cross-compilation is handled using
meson cross files. Example files are included in the
build/cross folder. You can write your own cross files for your specific processor by defining the toolchain, compilation flags, and linker flags. These settings will be used to compile
libc. (or open an issue and we can help you).
Cross-compilation must be configured using the meson command when creating the build output folder. For example:
meson buildresults --cross-file build/cross/gcc_arm_cortex-m4.txt
Following that, you can run
make (at the project root) or
ninja to build the project.
Tests will not be cross-compiled. They will only be built for the native platform.
Full instructions for building the project, using alternate toolchains, and running supporting tooling are documented in Embedded Artistry's Standardized Meson Build System on our website.
Position Independent Code (PIC) is enabled by default, but can be disabled during the Meson configuration stage by setting the built-in option
meson buildresults -Db_staticpic=false
Link-time Optimization (LTO) can be enabled during the meson configuration stage by setting the built-in option
meson buildresults -Db_lto=true
This can be combined with other build options.
If you don't use
meson for your project, the best method to use this project is to build it separately and copy the headers and library contents into your source tree.
include/directory contents into your source tree.
Example linker flags:
If you're using
meson, you can use
libc as a subproject. Place it into your subproject directory of choice and add a
libc = subproject('libc')
You will need to promote the desired subproject dependency variable to your project:
libc_dep = libc.get_variable('libc_dep')
You can use the dependency for your target library configuration in your
executable declarations(s) or other dependencies. For example:
fwdemo_sim_platform_dep = declare_dependency( include_directories: fwdemo_sim_platform_inc, dependencies: [ fwdemo_simulator_hw_platform_dep, posix_os_dep, libmemory_native_dep, libc_dep, # <----- libc added here libcxxabi_native_dep, libcxx_full_native_dep, logging_subsystem_dep ], sources: files('platform.cpp'), )
The tests for this library are written with CMocka, which is included as a subproject and does not need to be installed on your system. You can run the tests by issuing the following command:
By default, test results are generated for use by the CI server and are formatted in JUnit XML. The test results XML files can be found in
The following meson project options can be set for this library when creating the build results directory with
meson, or by using
enable-pedantic: Turn on
enable-pedantic-error: Turn on
pedanticwarnings and errors
hide-unimplemented-libc-apis: Hides the header definitions for functions which are not actually implemented
enable-gnu-extensionswill enable GNU libc extensions that are implemented in this library
disable-builtinswill tell the compiler not to generate built-in functions, forcing it to use the library functions
disable-stack-protectionwill tell the compiler not to insert stack protection calls
stack-canary-valueenables you to customize the canary value for your application. Supply a hexadecimal string (e.g.,
'0xdeadbeef') with the same length as your processor's word size.
disable-stk-guard-runtime-configdisables the code that is used to configure
__stk_chk_guardduring program initialization. When this option is
true, the program will revert to using a hard-coded definition for the guard value.
Options can be specified using
-D and the option name:
meson buildresults -Ddisable-builtins=false
The same style works with
cd buildresults meson configure -Ddisable-builtins=false
This library provides an implementation of
__stack_chk_fail, which enables it to be used with GCC and Clang's stack protection code.
The default value for
__stack_chk_guard can be overridden with the
stack-canary-value build option.
[Documentation for the latest release can always be found here]https://embeddedartistry.github.io/libc/index.html.
Documentation can be built locally by running the following command:
Documentation can be found in
buildresults/docs, and the root page is
You can also reach out on Twitter: mbeddedartistry.
If you are interested in contributing to this project, please read our contributing guidelines.
Copyright © 2017 Embedded Artistry LLC
This project is licensed under the MIT License - see LICENSE file for details.
For other open-source licenses, please see the Software Inventory.
I'd like to thank the following individuals for their direct contributions on this project:
Many of the open-source function implementations used in this library have been pulled from two primary sources:
I have also used and improved the open-source
The initial groundwork of testing was implemented by referencing the libc-test project.