Embedded Artistry's 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.
malloc
and 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 malloc
and free
.
If you are interested in contributing to this project, please read the CONTRIBUTING
guide.
- About the Project
- Project Status
- Getting Started
- Configuration Options
- Formatting
- Documentation
- Need Help?
- Contributing
- Futher Reading
- Authors
- License
- Acknowledgements
Embedded Artistry's 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.
malloc
and 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 malloc
and free
.
This library provides a complete-enough implementation to compile and link clang's libc++
and 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 (hide-unimplemented-libc-apis
).
The following portions of the C library have been implemented:
assert
- Basic C runtime support (
crt.c
,exit
,atexit
, etc.) - ctype
- math (via openlibm)
- string functions
- stdlib
atoX
abs
,labs
,llabs
bsearch
calloc
div
,ldiv
,lldiv
heapsort
,heapsort_r
imaxabs
,imaxdiv
qsort
,qsort_r
rand
familyrealloc
strtoX
functions (many viagdtoa
)
- Basic stdio
printf
family (most viampaland/printf
)putchar
puts
time
types andasctime()
wchar
type definitions andwctype
functions
The following architectures are currently supported:
- x86
- x86_64
- ARM
- ARM64
The following unit tests need to be added:
bsearch
imaxdiv
div
,ldiv
realloc
rand
familystrnstr
memmove
These are not implemented by may be added in the future:
wchar
functionserrno
support (enabled as a compile-time switch)getopt
supporttime
supportFILE
and additional stdio functions
We are currently not planning full support for:
locale
- CMocka must be installed on your system to compile and run unit tests
- Doxygen must be installed to generate documentation
- Meson is the build system
git-lfs
is used to store binary files in this repositorymake
is needed if you want to use the Makefile shims- You'll need some kind of compiler for your target system.
- This repository has been tested with:
- gcc
- arm-none-eabi-gcc
- Apple clang
- Mainline clang
- This repository has been tested with:
Contributors will also need:
adr-tools
for documenting major project decisionsclang-format
for code formatting
This project stores some files using git-lfs
.
To install git-lfs
on Linux:
sudo apt install git-lfs
To install git-lfs
on OS X:
brew install git-lfs
Additional installation instructions can be found on the git-lfs
website.
The Meson build system depends on python3
and ninja-build
.
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
:
pip3 install meson
If you want to install Meson globally on Linux, use:
sudo -H pip3 install meson
This repository uses Architecture Decision Records. Please install adr-tools
to contribute to architecture decisions.
If you are using OSX, you can install adr-tools
through Homebrew:
brew install adr-tools
If you are using Windows or Linux, please install adr-tools
via GitHub.
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
The library can be built by issuing the following command:
make
This will build all targets for your current architecture.
You can clean builds using:
make clean
You can eliminate the generated buildresults
folder using:
make purify
You can also use the meson
method for compiling.
Create a build output folder:
meson buildresults
Then change into that folder and build targets by running:
ninja
At this point, make
would still work.
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 platform (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/gcc_arm_cortex-m4.txt
Following that, you can run make
(at the project root) or ninja
(within the build output directory) to build the project.
Tests will not be cross-compiled. They will be built for the native platform.
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.
- Copy the
include/
directory contents into your source tree. - Library artifacts are stored in the
buildresults/src
folder - Copy the desired library to your project and add the library to your link step.
Example linker flags:
-Lpath/to/libc.a -lc
If you're using meson
, you can use libc
as a subproject. Place it into your subproject directory of choice and add a subproject
statement:
libc = subproject('libc')
You will need to promote the subproject dependencies to your project:
libc_dep = libc.get_variable('libc_dep')
libc_native_dep = libc.get_variable('libc_native_dep')
libc_hosted_dep = libc.get_variable('libc_hosted_dep')
libc_printf_dep = libc.get_variable('libc_printf_dep')
libc_header_include = libc.get_variable('libc_header_include')
libc_native_header_include = libc.get_variable('libc_native_header_include')
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_native_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. You can run the tests by issuing the following command:
make test
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 buildresults/test/
.
The following meson project options can be set for this library when creating the build results directory with meson
, or by using meson configure
:
enable-werror
: Cause the build to fail if warnings are presentenable-pedantic-error
: Turn onpedantic
warnings and errorshide-unimplemented-libc-apis
: Hides the header definitions for functions which are not actually implemented
Options can be specified using -D
and the option name:
meson buildresults -Denable-werror=true
The same style works with meson configure
:
cd buildresults
meson configure -Denable-werror=true
This repository enforces formatting using clang-format
.
You can auto-format your code to match the style guidelines by issuing the following command:
make format
Formatting is enforced by the Jenkins build server which runs continuous integration for this project. Your pull request will not be accepted if the formatting check fails.
Documentation for the latest release can always be found here.
Documentation can be built locally by running the following command:
make docs
Documentation can be found in buildresults/doc
, and the root page is index.html
.
If you need further assistance or have any questions, please file a GitHub Issue or send us an email using the Embedded Artistry Contact Form.
You can also reach out on Twitter: mbeddedartistry.
If you are interested in contributing to this project, please read our contributing guidelines.
- Phillip Johnston - original library author - Embedded Artistry
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:
- @seekaddo (Documentation)
Many of the open-source function implementations used in this library have been pulled from two primary sources:
- Apple Open Source libc
- abs, atof, bsearch, div family, heapsort/qsort family, abs family, imax family, strtol/ll/ull
- fls, flsl, flsll
- strstr, strtok. strnstr, strnlen, strndup, strncpy, strncat, strlen, strdup, strcpy, strcat
- memmem, memcpy
- musl libc
- All ctype member functions (locale support removed)
- strrchr, strchrnul, strchr
- memset, memrchr
I have also used and improved the open-source gdtoa
library.
The initial groundwork of testing was implemented by referencing the libc-test project.