Skip to content

Commit 8ae6b47

Browse files
authored
Merge pull request ZigEmbeddedGroup#362 from ZigEmbeddedGroup/foundation-libc
Foundation libc
2 parents 6c91a35 + 9eef75c commit 8ae6b47

35 files changed

+1563
-0
lines changed

modules/foundation-libc/.clang-format

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
Language: Cpp
3+
BasedOnStyle: LLVM
4+
5+
# basic indentation is 4 spaces, indented by spaces:
6+
IndentWidth: 4
7+
TabWidth: 4
8+
UseTab: Never
9+
10+
# use east const for better readability:
11+
QualifierAlignment: Right
12+
13+
# do not tack pointer to type nor value:
14+
PointerAlignment: Middle
15+
16+
# align function names and keep them apart at least one line
17+
AlignConsecutiveDeclarations: AcrossEmptyLines
18+
19+
# we sort includes to prevent merge conflicts:
20+
SortIncludes: CaseSensitive
21+
22+
# disable column limit:
23+
ColumnLimit: 0
24+
25+
---
26+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.zig text=auto eol=lf
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Continuous Integration
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
build:
11+
strategy:
12+
matrix:
13+
os: [ubuntu-latest, windows-latest, macos-latest]
14+
15+
runs-on: ${{ matrix.os }}
16+
steps:
17+
- name: Checkout
18+
uses: actions/checkout@v4
19+
20+
- name: Setup Zig
21+
uses: mlugg/setup-zig@v1
22+
with:
23+
version: 0.13.0
24+
25+
- name: Generate and validate packages
26+
working-directory: test
27+
run: |
28+
zig build validate

modules/foundation-libc/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.zig-cache/
2+
zig-out/

modules/foundation-libc/LICENCE

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2024 Felix "xq" Queißner
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18+
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
19+
OR OTHER DEALINGS IN THE SOFTWARE.

modules/foundation-libc/README.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# Foundation libc
2+
3+
[![Continuous Integration](https://github.com/ZigEmbeddedGroup/foundation-libc/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/ZigEmbeddedGroup/foundation-libc/actions/workflows/build.yml)
4+
5+
A C standard library that only implements a subset of functions that can be safely used without an operating system.
6+
This is called a [freestanding environment](https://en.cppreference.com/w/cpp/freestanding).
7+
8+
This libc is primarily meant to be used with microcontrollers, hobbyist operating systems and so on.
9+
10+
## Support
11+
12+
The first goal is to reach full C11 *freestanding* support.
13+
14+
- No support for locales
15+
- No allocator (ship your own!)
16+
- No support for functions that require an operating system of sorts in the background.
17+
- No support for `wchar_t` and `wchar.h` as it isn't portable between compilers.
18+
- Multi-byte character strings are implemented as UTF-8.
19+
20+
## Customization
21+
22+
Foundation libc doesn't really support much customization/configuration except for the hard required options.
23+
24+
There is [`foundation/libc.h`](include/foundation/libc.h) which documents the behaviour of all required configurations.
25+
26+
Right now, the following configurations exist:
27+
28+
- `foundation_libc_panic_handler`, which allows users to catch detectable undefined behaviour.
29+
30+
You can also configure the libc by chosing the build mode:
31+
32+
- `Debug`: Implements additional safety checks and adds breakpoints in panics.
33+
- `ReleaseSafe`: Keeps the safety checks, but removes breakpoints.
34+
- `ReleaseSmall`: Still keeps a certain amount of safety, but drops long internal strings to reduce code and ram size.
35+
- `ReleaseFast`: Gotta go fast. Drops all safety and assumes all code behaves well.
36+
37+
There are also certain "usage" configurations that can be chosen to affect behaviour when *using* the headers. Those are implemented as C macros/defines:
38+
39+
- `FOUNDATION_LIBC_ASSERT` is a global macro that defines how `assert()` should behave:
40+
- `FOUNDATION_LIBC_ASSERT_DEFAULT=0`: Behaves like a regular assert that can print file name, assertion message and line.
41+
- `FOUNDATION_LIBC_ASSERT_NOFILE=1`: Drops the filename from the assertion to reduce code size.
42+
- `FOUNDATION_LIBC_ASSERT_NOMSG=2`: Additionally drops the assertion message from the assertion to reduce code size.
43+
- `FOUNDATION_LIBC_ASSERT_EXPECTED=3`: Replaces `assert(…)` with a construct that tells the compiler the assertion is always met. Makes code very fast. Assertions aren't checked.
44+
45+
## Development
46+
47+
Zig Version: 0.11
48+
49+
Run
50+
```sh-session
51+
user@microzig ~/foundation-libc $ zig build
52+
user@microzig ~/foundation-libc $
53+
```
54+
55+
to compile the libc and generate a lib file in `zig-out/lib` as well as the headers in `zig-out/include`.
56+
57+
## Contribution
58+
59+
Start by grabbing a header marked with ⏳ or 🛠 and implement the functions from that header. See if others already have a PR open for those functions so you don't do work twice!
60+
61+
Leverage functions from Zig `std` if possible as they are already well tested and should work.
62+
63+
Which functions belong into which header can be figured out by taking a look at the *C11 Standard Draft* document or the *IBM libc functions* list. [cppreference.com](https://en.cppreference.com/w/c) usually has the better docs though, so best check out both.
64+
65+
### Style Guides
66+
67+
- The header files are ment to be as minimal as possible
68+
- Do not use comments documenting the functions, they are well documented everywhere else.
69+
- Only insert empty lines between functions if necessarity for clarity
70+
- Keep function names sorted alphabetically
71+
- Try not to use macros at all
72+
- Use `clang-format` with the provided style file.
73+
74+
75+
## Links
76+
77+
- [C11 Standard](https://www.iso.org/standard/57853.html)
78+
- [C11 Standard Draft](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf)
79+
- [ziglibc](https://github.com/marler8997/ziglibc)
80+
- [libc-test](https://wiki.musl-libc.org/libc-test.html) by musl
81+
- [cppreference on freestanding](https://en.cppreference.com/w/cpp/freestanding)
82+
- [GCC on freestanding](https://gcc.gnu.org/onlinedocs/gcc/Standards.html#C-Language)
83+
- [IBM libc functions](https://www.ibm.com/docs/en/i/7.5?topic=extensions-standard-c-library-functions-table-by-name) (function to header map)
84+
- [cppreference](https://en.cppreference.com/w/c)
85+
- [clang-format style options](https://releases.llvm.org/16.0.0/tools/clang/docs/ClangFormatStyleOptions.html)
86+
87+
## Status
88+
89+
⏳ (not started), 🛠 (work in progress), ⚠️ (partial support), ✅ (full support), ❌ (no support), 🔮 (potential future support), 🔀 (implemented by compiler)
90+
91+
| Header File | Header Status | Implementation Status | Description |
92+
| --------------- | ------------- | --------------------- | ------------------------------------------------------------------------------------------------------- |
93+
| `assert.h` ||| Conditionally compiled macro that compares its argument to zero |
94+
| `complex.h` || | (since C99) Complex number arithmetic |
95+
| `ctype.h` ||| Functions to determine the type contained in character data |
96+
| `errno.h` ||| Macros reporting error conditions |
97+
| `fenv.h` | 🔮 | | (since C99) Floating-point environment |
98+
| `float.h` | 🔀 | | Limits of floating-point types |
99+
| `inttypes.h` ||| (since C99) Format conversion of integer types |
100+
| `iso646.h` | 🔀 | | (since C95) Alternative operator spellings |
101+
| `limits.h` | 🔀 | | Ranges of integer types |
102+
| `locale.h` || | Localization utilities |
103+
| `math.h` | 🛠 || Common mathematics functions |
104+
| `setjmp.h` | 🛠 || Nonlocal jumps |
105+
| `signal.h` || | Signal handling |
106+
| `stdalign.h` | 🔀 | | (since C11) alignas and alignof convenience macros |
107+
| `stdarg.h` | 🔀 | | Variable arguments |
108+
| `stdatomic.h` | 🔮 | | (since C11) Atomic operations |
109+
| `stdbit.h` | 🔮 | | (since C23) Macros to work with the byte and bit representations of types |
110+
| `stdbool.h` | 🔀 | | (since C99) Macros for boolean type |
111+
| `stdckdint.h` | 🔮 | | (since C23) macros for performing checked integer arithmetic |
112+
| `stddef.h` | 🔀 | | Common macro definitions |
113+
| `stdint.h` | 🔀 | | (since C99) Fixed-width integer types |
114+
| `stdio.h` || | Input/output |
115+
| `stdlib.h` | 🛠 | 🛠 | General utilities: memory management, program utilities, string conversions, random numbers, algorithms |
116+
| `stdnoreturn.h` | 🔀 | | (since C11) noreturn convenience macro |
117+
| `string.h` || 🛠 | String handling |
118+
| `tgmath.h` ||| (since C99) Type-generic math (macros wrapping math.h and complex.h) |
119+
| `threads.h` || | (since C11) Thread library |
120+
| `time.h` || | Time/date utilities |
121+
| `uchar.h` | 🛠 || (since C11) UTF-16 and UTF-32 character utilities |
122+
| `wchar.h` || | (since C95) Extended multibyte and wide character utilities |
123+
| `wctype.h` || | (since C95) Functions to determine the type contained in wide character data |
124+
125+

modules/foundation-libc/build.zig

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
const std = @import("std");
2+
3+
pub fn build(b: *std.Build) void {
4+
const validation_step = b.step("validate", "Runs the test suite and validates everything. Automatically triggered in Debug builds.");
5+
6+
const target = b.standardTargetOptions(.{});
7+
const optimize = b.standardOptimizeOption(.{});
8+
9+
const single_threaded = b.option(bool, "single_threaded", "Create a single-threaded libc implementation (default: false)") orelse false;
10+
11+
// Run validation in debug builds for convenience:
12+
if (optimize == .Debug) {
13+
b.getInstallStep().dependOn(validation_step);
14+
}
15+
16+
const libc = b.addStaticLibrary(.{
17+
.name = "foundation",
18+
.target = target,
19+
.optimize = optimize,
20+
.root_source_file = b.path("src/libc.zig"),
21+
.single_threaded = single_threaded,
22+
});
23+
24+
libc.addIncludePath(b.path("include"));
25+
for (header_files) |header_name|
26+
libc.installHeader(
27+
b.path(b.fmt("include/{s}", .{header_name})),
28+
header_name,
29+
);
30+
31+
libc.installHeadersDirectory(b.path("include/foundation"), "foundation", .{});
32+
33+
b.installArtifact(libc);
34+
}
35+
36+
const header_files = [_][]const u8{
37+
"assert.h",
38+
"ctype.h",
39+
"errno.h",
40+
"inttypes.h",
41+
"math.h",
42+
"setjmp.h",
43+
"stdlib.h",
44+
"string.h",
45+
"tgmath.h",
46+
"uchar.h",
47+
"foundation/libc.h",
48+
};

modules/foundation-libc/build.zig.zon

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
.{
2+
.name = "foundation-libc",
3+
.version = "0.0.0",
4+
.paths = .{
5+
"LICENSE",
6+
"README.md",
7+
"build.zig",
8+
"build.zig.zon",
9+
"include",
10+
"src",
11+
},
12+
}

0 commit comments

Comments
 (0)