Add vlibc scaffold, build system, and documentation
Establish the repository layout per Vox guidelines (layouts/C.md, building/C.md): Autotools build (GCC-only, C23), five compatibility profiles (--enable-onlyposix/--enable-muslmimic/--enable-muslext/ --enable-spoof, default vlibc), alongside/overwrite install methods, vlibc-gcc/vlibc-clang drivers, static-linking requirement (except spoof), benchmark harness, and tooling (.clang-format/.clang-tidy/ .clangd + compile_commands.json).
This commit is contained in:
@@ -0,0 +1,37 @@
|
|||||||
|
# clang-format configuration for vlibc.
|
||||||
|
# Keep in sync with STYLEGUIDE.md.
|
||||||
|
|
||||||
|
BasedOnStyle: LLVM
|
||||||
|
Language: Cpp
|
||||||
|
|
||||||
|
IndentWidth: 4
|
||||||
|
TabWidth: 4
|
||||||
|
UseTab: Never
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
ColumnLimit: 100
|
||||||
|
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: true
|
||||||
|
AfterClass: true
|
||||||
|
AfterControlStatement: Always
|
||||||
|
AfterEnum: true
|
||||||
|
AfterFunction: true
|
||||||
|
AfterNamespace: true
|
||||||
|
AfterStruct: true
|
||||||
|
AfterUnion: true
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: true
|
||||||
|
BeforeElse: true
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: false
|
||||||
|
AlwaysBreakAfterReturnType: TopLevel
|
||||||
|
PointerAlignment: Right
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
|
||||||
|
SortIncludes: CaseSensitive
|
||||||
|
ReflowComments: false
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
# clang-tidy configuration for vlibc.
|
||||||
|
# Keep in sync with STYLEGUIDE.md.
|
||||||
|
|
||||||
|
Checks: >
|
||||||
|
bugprone-*,
|
||||||
|
clang-analyzer-*,
|
||||||
|
misc-*,
|
||||||
|
performance-*,
|
||||||
|
portability-*,
|
||||||
|
readability-*,
|
||||||
|
-readability-magic-numbers,
|
||||||
|
-readability-identifier-length,
|
||||||
|
-readability-function-cognitive-complexity,
|
||||||
|
-misc-include-cleaner
|
||||||
|
|
||||||
|
WarningsAsErrors: 'bugprone-*,clang-analyzer-*'
|
||||||
|
HeaderFilterRegex: '^include/'
|
||||||
|
|
||||||
|
FormatStyle: file
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# clangd language-server configuration for vlibc.
|
||||||
|
# Provides fallback flags so the LSP reports errors on valid code even before
|
||||||
|
# compile_commands.json is regenerated (see layouts/C.md).
|
||||||
|
|
||||||
|
CompileFlags:
|
||||||
|
CompilationDatabase: .
|
||||||
|
Add:
|
||||||
|
- -std=c23
|
||||||
|
- -Iinclude
|
||||||
|
|
||||||
|
Diagnostics:
|
||||||
|
UnusedIncludes: Strict
|
||||||
|
ClangTidy:
|
||||||
|
Add:
|
||||||
|
- bugprone-*
|
||||||
|
- clang-analyzer-*
|
||||||
|
|
||||||
|
Index:
|
||||||
|
Background: Build
|
||||||
+51
@@ -52,3 +52,54 @@ Module.symvers
|
|||||||
Mkfile.old
|
Mkfile.old
|
||||||
dkms.conf
|
dkms.conf
|
||||||
|
|
||||||
|
# Autotools backup files (autoreconf/autoheader).
|
||||||
|
*~
|
||||||
|
*.orig
|
||||||
|
*.rej
|
||||||
|
|
||||||
|
# ---> vlibc / Autotools
|
||||||
|
# Generated build system. `configure` and `autogen.sh` are tracked (layouts/C.md);
|
||||||
|
# the Makefiles and other artifacts produced from configure.ac / Makefile.am are not.
|
||||||
|
Makefile
|
||||||
|
Makefile.in
|
||||||
|
.dirstamp
|
||||||
|
/aclocal.m4
|
||||||
|
/autom4te.cache/
|
||||||
|
/config.h
|
||||||
|
/config.h.in
|
||||||
|
/config.log
|
||||||
|
/config.status
|
||||||
|
/config.guess
|
||||||
|
/config.sub
|
||||||
|
/install-sh
|
||||||
|
/missing
|
||||||
|
/depcomp
|
||||||
|
/ltmain.sh
|
||||||
|
/libtool
|
||||||
|
/libtool.m4
|
||||||
|
/ltoptions.m4
|
||||||
|
/ltsugar.m4
|
||||||
|
/ltversion.m4
|
||||||
|
/lt~obsolete.m4
|
||||||
|
/stamp-h1
|
||||||
|
/build-aux/
|
||||||
|
/m4/
|
||||||
|
|
||||||
|
# Libtool build directories and artifacts.
|
||||||
|
.deps/
|
||||||
|
.libs/
|
||||||
|
*.lo
|
||||||
|
|
||||||
|
# Build outputs (bin/{release,debug}); keep the directory placeholders.
|
||||||
|
/bin/release/*
|
||||||
|
!/bin/release/.gitkeep
|
||||||
|
/bin/debug/*
|
||||||
|
!/bin/debug/.gitkeep
|
||||||
|
|
||||||
|
# Generated compiler drivers (from tools/*.in); the templates are tracked.
|
||||||
|
/tools/vlibc-gcc
|
||||||
|
/tools/vlibc-clang
|
||||||
|
|
||||||
|
# Built benchmark harnesses (benchmarks/bench_* are generated from bench_*.c).
|
||||||
|
/benchmarks/bench_vlibc
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
# Contributing
|
||||||
|
|
||||||
|
## Compiler policy
|
||||||
|
|
||||||
|
vlibc is built with **exactly one compiler: GCC**. There is no fallback to
|
||||||
|
another compiler (`building/C.md`). This lets vlibc use compiler extensions
|
||||||
|
freely while keeping behavior deterministic.
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./autogen.sh # autoreconf + configure
|
||||||
|
make # build
|
||||||
|
make debug # -O0 -g3 into bin/debug/
|
||||||
|
make release # -O3 into bin/release/
|
||||||
|
make bench # build + run benchmarks
|
||||||
|
make clean # remove artifacts
|
||||||
|
```
|
||||||
|
|
||||||
|
`autogen.sh` regenerates the build system from `configure.ac` / `Makefile.am`
|
||||||
|
and then runs `configure`. The generated `configure` script is tracked; the
|
||||||
|
Makefiles it produces are not.
|
||||||
|
|
||||||
|
### Compatibility profiles
|
||||||
|
|
||||||
|
Pick exactly one (they are mutually exclusive):
|
||||||
|
|
||||||
|
| Flag | Profile | Description |
|
||||||
|
|-----------------------|--------------|-----------------------------------|
|
||||||
|
| *(default)* | `vlibc` | glibc-extended, extended features |
|
||||||
|
| `--enable-onlyposix` | `onlyposix` | pure POSIX, nothing more |
|
||||||
|
| `--enable-muslmimic` | `muslmimic` | musl-like, light |
|
||||||
|
| `--enable-muslext` | `muslext` | musl-extended |
|
||||||
|
| `--enable-spoof` | `spoof` | glibc replica (drop-in) |
|
||||||
|
|
||||||
|
### Install methods
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./autogen.sh --with-install=alongside # default: keep system libc
|
||||||
|
./autogen.sh --with-install=overwrite # replace system libc
|
||||||
|
```
|
||||||
|
|
||||||
|
### Static linking
|
||||||
|
|
||||||
|
Full static linking is **required** for every profile except `spoof`. Configure
|
||||||
|
rejects `--disable-static` for those profiles.
|
||||||
|
|
||||||
|
## Benchmarks
|
||||||
|
|
||||||
|
Every component must be benchmarked against the software it replaces
|
||||||
|
(`musts/BENCHMARKING.md`). A component slower than glibc is failing.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./autogen.sh --with-libc=glibc # reference comparison
|
||||||
|
make bench
|
||||||
|
```
|
||||||
|
|
||||||
|
## Style and linting
|
||||||
|
|
||||||
|
- `.clang-format` — run `clang-format` before committing; it must agree with
|
||||||
|
`STYLEGUIDE.md`.
|
||||||
|
- `.clang-tidy` — `bugprone-*` and `clang-analyzer-*` are warnings-as-errors.
|
||||||
|
- Keep `compile_commands.json` fresh (`make compile-commands`) so language
|
||||||
|
servers do not report errors on valid code.
|
||||||
|
|
||||||
|
## Vendoring
|
||||||
|
|
||||||
|
Third-party code goes in `thirdparty/`, with its upstream source, version, and
|
||||||
|
license recorded alongside it. No external downloads at build time.
|
||||||
|
|
||||||
|
## Submitting changes
|
||||||
|
|
||||||
|
1. Open an issue describing the problem or feature first.
|
||||||
|
2. Keep changes small and focused; one concern per change.
|
||||||
|
3. Add or update benchmarks and documentation with the change.
|
||||||
|
4. Ensure `make debug`, `make release`, and `make bench` pass.
|
||||||
+56
@@ -0,0 +1,56 @@
|
|||||||
|
# vlibc — top-level build (see building/C.md and layouts/C.md).
|
||||||
|
|
||||||
|
SUBDIRS = benchmarks
|
||||||
|
|
||||||
|
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||||
|
AM_CFLAGS = @VLIBC_CFLAGS@
|
||||||
|
|
||||||
|
# ---- Library -------------------------------------------------------------
|
||||||
|
vlibc_include_HEADERS = include/vlibc.h
|
||||||
|
vlibc_lib_LTLIBRARIES = libvlibc.la
|
||||||
|
|
||||||
|
libvlibc_la_SOURCES = src/vlibc.c
|
||||||
|
libvlibc_la_LDFLAGS = -version-info 0:0:0 -no-undefined
|
||||||
|
|
||||||
|
# Install location depends on the install method (see configure.ac).
|
||||||
|
if INSTALL_OVERWRITE
|
||||||
|
vlibc_includedir = $(includedir)
|
||||||
|
vlibc_libdir = $(libdir)
|
||||||
|
else
|
||||||
|
vlibc_includedir = $(prefix)/lib/vlibc/include
|
||||||
|
vlibc_libdir = $(prefix)/lib/vlibc/lib
|
||||||
|
endif
|
||||||
|
|
||||||
|
# ---- Compiler drivers ----------------------------------------------------
|
||||||
|
bin_SCRIPTS = tools/vlibc-gcc tools/vlibc-clang
|
||||||
|
|
||||||
|
# ---- Targets -------------------------------------------------------------
|
||||||
|
# layouts/C.md requires `make debug`, `make release`, `make bench` and
|
||||||
|
# `make clean`; build outputs land in bin/{release,debug}.
|
||||||
|
DEBUG_CFLAGS = -O0 -g3 -DDEBUG
|
||||||
|
RELEASE_CFLAGS = -O3 -DNDEBUG
|
||||||
|
|
||||||
|
debug:
|
||||||
|
$(MAKE) clean
|
||||||
|
$(MAKE) all AM_CFLAGS="$(AM_CFLAGS) $(DEBUG_CFLAGS)"
|
||||||
|
$(MKDIR_P) bin/debug
|
||||||
|
-cp -P .libs/libvlibc.so* bin/debug/
|
||||||
|
-cp .libs/libvlibc.a bin/debug/
|
||||||
|
|
||||||
|
release:
|
||||||
|
$(MAKE) clean
|
||||||
|
$(MAKE) all AM_CFLAGS="$(AM_CFLAGS) $(RELEASE_CFLAGS)"
|
||||||
|
$(MKDIR_P) bin/release
|
||||||
|
-cp -P .libs/libvlibc.so* bin/release/
|
||||||
|
-cp .libs/libvlibc.a bin/release/
|
||||||
|
|
||||||
|
bench: all
|
||||||
|
$(MAKE) -C benchmarks bench
|
||||||
|
|
||||||
|
# Regenerate compile_commands.json (requires `bear`). Captures both the
|
||||||
|
# library sources and the on-demand benchmark harness.
|
||||||
|
compile-commands: clean
|
||||||
|
bear -- $(MAKE) all
|
||||||
|
bear --append -- $(MAKE) -C benchmarks bench_vlibc
|
||||||
|
|
||||||
|
.PHONY: debug release bench compile-commands
|
||||||
@@ -1,3 +1,72 @@
|
|||||||
# vlibc
|
# vlibc
|
||||||
|
|
||||||
A modern replacement for glibc, with modern features and extensions of the standard. Plus compatibility with glibc.
|
A modern replacement for glibc: a performant, standard-conforming C library
|
||||||
|
with modern extensions and high glibc compatibility.
|
||||||
|
|
||||||
|
vlibc is written in C (C23, with C2y/C29 opt-in), built with Autotools and a
|
||||||
|
single compiler (GCC, no fallback). Full static linking is a first-class,
|
||||||
|
required capability.
|
||||||
|
|
||||||
|
## Capabilities
|
||||||
|
|
||||||
|
- **Five compatibility profiles**, from the lightest to the most compatible:
|
||||||
|
1. `--enable-onlyposix` — pure POSIX, nothing more.
|
||||||
|
2. `--enable-muslmimic` — musl-like, light and musl-compatible.
|
||||||
|
3. `--enable-muslext` — musl-extended.
|
||||||
|
4. `--enable-spoof` — a glibc replica, for drop-in compatibility with
|
||||||
|
scripts and programs that rely on long-standing glibc behavior.
|
||||||
|
5. *(default)* — **vlibc**: glibc-extended, without the spoofing layer, but
|
||||||
|
with extended standard features and high glibc compatibility.
|
||||||
|
- **Two install methods** (`--with-install=`):
|
||||||
|
- `alongside` (default) — install next to the system libc, under a
|
||||||
|
vlibc-specific tree; the system libc is left untouched.
|
||||||
|
- `overwrite` — replace the system libc in place.
|
||||||
|
- **`vlibc-gcc` and `vlibc-clang`** compiler drivers, so consuming projects
|
||||||
|
build against vlibc with either compiler.
|
||||||
|
- **Full static linking** is required for every profile except `spoof`.
|
||||||
|
- **Compiler intent** is declared on the public API (e.g.
|
||||||
|
`__attribute__((const))`) so the compiler can fold and eliminate calls,
|
||||||
|
keeping statically linked binaries small.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./autogen.sh # regenerate build system + configure
|
||||||
|
make # build
|
||||||
|
make debug # build with -O0 -g3 into bin/debug/
|
||||||
|
make release # build with -O3 into bin/release/
|
||||||
|
make bench # build and run benchmarks
|
||||||
|
make clean # remove build artifacts
|
||||||
|
make compile-commands # regenerate compile_commands.json (needs bear)
|
||||||
|
```
|
||||||
|
|
||||||
|
Common configure options:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./autogen.sh --enable-spoof # glibc replica profile
|
||||||
|
./autogen.sh --with-install=overwrite # replace system libc
|
||||||
|
./autogen.sh --with-libc=glibc # benchmark against glibc
|
||||||
|
./autogen.sh --enable-c29 # experimental C2y (C29)
|
||||||
|
```
|
||||||
|
|
||||||
|
User-provided `CFLAGS` and `LDFLAGS` are honored.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
```
|
||||||
|
include/ public headers (mandatory)
|
||||||
|
src/ implementation sources
|
||||||
|
benchmarks/ benchmark harnesses (vs. glibc/musl)
|
||||||
|
docs/ behavior and glibc-difference documentation
|
||||||
|
thirdparty/ vendored third-party libraries
|
||||||
|
tools/ vlibc-gcc / vlibc-clang driver templates
|
||||||
|
bin/{release,debug}/ build outputs
|
||||||
|
```
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
- `docs/overview.md` — what vlibc is and how it behaves.
|
||||||
|
- `docs/compatibility.md` — the five profiles and glibc differences.
|
||||||
|
- `docs/install.md` — the two install methods.
|
||||||
|
- `CONTRIBUTING.md` — how to contribute.
|
||||||
|
- `STYLEGUIDE.md` — how code should look.
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
# Styleguide
|
||||||
|
|
||||||
|
This file is the source of truth for how vlibc code looks. `.clang-format` is
|
||||||
|
generated from / kept in sync with it.
|
||||||
|
|
||||||
|
## Language
|
||||||
|
|
||||||
|
- C23 is the default standard; C2y (C29) is opt-in via `--enable-c29`.
|
||||||
|
- GCC only. Compiler extensions (`__attribute__`, statement expressions,
|
||||||
|
`defer` under C2y) are permitted and encouraged where they improve clarity
|
||||||
|
or performance.
|
||||||
|
|
||||||
|
## Formatting
|
||||||
|
|
||||||
|
- 4-space indent, no tabs.
|
||||||
|
- 100-column limit.
|
||||||
|
- Allman braces: opening brace on its own line, for functions and blocks.
|
||||||
|
- Always use braces, even for single-statement blocks (avoids `goto fail`-style
|
||||||
|
bugs and matches `.clang-tidy`).
|
||||||
|
- Pointer and qualifier attach to the name: `const char *s`, `int *p`.
|
||||||
|
- Spaces around binary operators; no space after unary operators.
|
||||||
|
|
||||||
|
The one exception to Allman braces is the C++ linkage guard: `extern "C" {`
|
||||||
|
keeps its opening brace attached (encoded as `AfterExternBlock: false` in
|
||||||
|
`.clang-format`), because that is the idiomatic form every C header uses.
|
||||||
|
|
||||||
|
```c
|
||||||
|
int
|
||||||
|
foo(const char *s, size_t n)
|
||||||
|
{
|
||||||
|
if (n == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int)(s[0] == 'x');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Naming
|
||||||
|
|
||||||
|
- Functions and variables: `snake_case`.
|
||||||
|
- Types: `snake_case` (struct tags); typedefs avoid the POSIX-reserved `_t`
|
||||||
|
suffix.
|
||||||
|
- Macros and constants: `UPPER_SNAKE_CASE`.
|
||||||
|
- Public identifiers are prefixed `vlibc_` to avoid collisions.
|
||||||
|
- Identifiers beginning with `_` (or `__`, or `_[A-Z]`) are reserved for the
|
||||||
|
implementation and the C/POSIX standards — do not introduce new ones.
|
||||||
|
|
||||||
|
## Include guards
|
||||||
|
|
||||||
|
Public headers use traditional include guards:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#ifndef VLIBC_H
|
||||||
|
#define VLIBC_H
|
||||||
|
...
|
||||||
|
#endif /* VLIBC_H */
|
||||||
|
```
|
||||||
|
|
||||||
|
`#pragma once` is a widely supported extension but is deliberately not used:
|
||||||
|
it relies on compiler-specific path canonicalization and can mis-deduplicate
|
||||||
|
headers reachable through symlinks or bind mounts. For a libc whose headers are
|
||||||
|
consumed in many toolchain configurations, explicit guards are the robust
|
||||||
|
default.
|
||||||
|
|
||||||
|
## Compiler intent
|
||||||
|
|
||||||
|
Public declarations annotate *intent* so the compiler can optimize statically
|
||||||
|
linked binaries (see `docs/overview.md`):
|
||||||
|
|
||||||
|
- `__attribute__((const))` — result depends only on arguments.
|
||||||
|
- `__attribute__((pure))` — no side effects; may read memory.
|
||||||
|
- `__attribute__((always_inline))`, `__attribute__((leaf))`,
|
||||||
|
`__attribute__((malloc))`, `__attribute__((access, ...))` — as appropriate.
|
||||||
|
|
||||||
|
Every public function carries the tightest correct attribute.
|
||||||
|
|
||||||
|
## Error handling
|
||||||
|
|
||||||
|
- No empty blocks; no silent failure.
|
||||||
|
- Library functions return errors via return codes or `errno`; they never
|
||||||
|
terminate the caller's process.
|
||||||
Executable
+16
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# vlibc — Autotools bootstrap (layouts/C.md).
|
||||||
|
#
|
||||||
|
# Regenerates the build system (configure, Makefile.in, ...) from the
|
||||||
|
# *.ac / *.am sources and then runs configure, passing through any
|
||||||
|
# arguments. The generated `configure` script is tracked; the Makefiles
|
||||||
|
# it produces are not (see .gitignore).
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
srcdir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||||
|
cd "$srcdir"
|
||||||
|
|
||||||
|
autoreconf -i -f
|
||||||
|
|
||||||
|
./configure "$@"
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
# vlibc — benchmark harnesses (musts/BENCHMARKING.md).
|
||||||
|
|
||||||
|
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||||
|
AM_CFLAGS = @VLIBC_CFLAGS@
|
||||||
|
|
||||||
|
# Built only on demand (via `make bench`), so `make all` does not need the
|
||||||
|
# library to be built first.
|
||||||
|
EXTRA_PROGRAMS = bench_vlibc
|
||||||
|
bench_vlibc_SOURCES = bench_vlibc.c
|
||||||
|
|
||||||
|
# By default benchmarks link against vlibc itself. --with-libc=glibc links the
|
||||||
|
# same harness against the system glibc; --with-libc=musl builds it with
|
||||||
|
# musl-gcc for the musl reference.
|
||||||
|
if BENCH_LINK_VLIBC
|
||||||
|
bench_vlibc_LDADD = ../libvlibc.la
|
||||||
|
else
|
||||||
|
bench_vlibc_LDADD =
|
||||||
|
endif
|
||||||
|
|
||||||
|
if BENCH_LINK_MUSL
|
||||||
|
CC = $(MUSL_CC)
|
||||||
|
endif
|
||||||
|
|
||||||
|
bench: bench_vlibc
|
||||||
|
./bench_vlibc
|
||||||
|
|
||||||
|
.PHONY: bench
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
# Benchmarking
|
||||||
|
|
||||||
|
Every vlibc component is benchmarked against the software it replaces, per
|
||||||
|
`musts/BENCHMARKING.md`. A component that is slower or worse at its task than
|
||||||
|
the software it replaces is considered failing.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
- Each benchmark harness is a standalone C program in this directory, named
|
||||||
|
`bench_<component>.c`.
|
||||||
|
- `bench_vlibc.c` is the skeleton that per-component benchmarks build on.
|
||||||
|
|
||||||
|
## Running
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./autogen.sh # configure (default: link against vlibc)
|
||||||
|
make bench # build and run the harnesses
|
||||||
|
|
||||||
|
# Reference comparison against the libc vlibc replaces:
|
||||||
|
./autogen.sh --with-libc=glibc
|
||||||
|
make bench
|
||||||
|
|
||||||
|
# musl reference (requires musl-gcc):
|
||||||
|
./autogen.sh --with-libc=musl
|
||||||
|
make bench
|
||||||
|
```
|
||||||
|
|
||||||
|
## Adding a benchmark
|
||||||
|
|
||||||
|
1. Add `bench_<component>.c` here and list it in `benchmarks/Makefile.am`.
|
||||||
|
2. Measure the component against the equivalent glibc (and musl) call.
|
||||||
|
3. Report wall-clock time, throughput, and any binary-size difference.
|
||||||
|
4. If vlibc is slower, the benchmark fails — fix the implementation.
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Benchmark harness for vlibc (musts/BENCHMARKING.md).
|
||||||
|
*
|
||||||
|
* Every vlibc component is benchmarked against the software it replaces.
|
||||||
|
* This stub times vlibc_version() and is the skeleton that per-component
|
||||||
|
* benchmarks build on. Reconfigure with --with-libc=musl or --with-libc=glibc
|
||||||
|
* to link the same harness against a reference libc for comparison.
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <vlibc.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#define ITERATIONS 100000000ULL
|
||||||
|
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
volatile const char *version = NULL;
|
||||||
|
struct timespec start;
|
||||||
|
struct timespec end;
|
||||||
|
double whole;
|
||||||
|
double frac;
|
||||||
|
double seconds;
|
||||||
|
|
||||||
|
if (clock_gettime(CLOCK_MONOTONIC, &start) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned long long i = 0; i < ITERATIONS; i++)
|
||||||
|
{
|
||||||
|
version = vlibc_version();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clock_gettime(CLOCK_MONOTONIC, &end) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
whole = (double)(end.tv_sec - start.tv_sec);
|
||||||
|
frac = (double)(end.tv_nsec - start.tv_nsec) / 1000000000.0;
|
||||||
|
seconds = whole + frac;
|
||||||
|
|
||||||
|
printf("vlibc_version() x %llu: %.3f s (%.2f ns/call), version=%s\n", ITERATIONS, seconds,
|
||||||
|
seconds * 1000000000.0 / ITERATIONS, (const char *)version);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
# vlibc
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
# vlibc
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"file": "bench_vlibc.c",
|
||||||
|
"arguments": [
|
||||||
|
"/usr/sbin/gcc",
|
||||||
|
"-DHAVE_CONFIG_H",
|
||||||
|
"-I.",
|
||||||
|
"-I..",
|
||||||
|
"-I../include",
|
||||||
|
"-std=c23",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-g",
|
||||||
|
"-O2",
|
||||||
|
"-MT",
|
||||||
|
"bench_vlibc.o",
|
||||||
|
"-MD",
|
||||||
|
"-MP",
|
||||||
|
"-MF",
|
||||||
|
".deps/bench_vlibc.Tpo",
|
||||||
|
"-c",
|
||||||
|
"-o",
|
||||||
|
"bench_vlibc.o",
|
||||||
|
"bench_vlibc.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/specter/vox/vlibc/benchmarks",
|
||||||
|
"output": "bench_vlibc.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "src/vlibc.c",
|
||||||
|
"arguments": [
|
||||||
|
"/usr/sbin/gcc",
|
||||||
|
"-DHAVE_CONFIG_H",
|
||||||
|
"-I.",
|
||||||
|
"-I./include",
|
||||||
|
"-std=c23",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-g",
|
||||||
|
"-O2",
|
||||||
|
"-MT",
|
||||||
|
"src/vlibc.lo",
|
||||||
|
"-MD",
|
||||||
|
"-MP",
|
||||||
|
"-MF",
|
||||||
|
"src/.deps/vlibc.Tpo",
|
||||||
|
"-c",
|
||||||
|
"src/vlibc.c",
|
||||||
|
"-fPIC",
|
||||||
|
"-DPIC",
|
||||||
|
"-o",
|
||||||
|
"src/.libs/vlibc.o"
|
||||||
|
],
|
||||||
|
"directory": "/home/specter/vox/vlibc",
|
||||||
|
"output": "src/.libs/vlibc.o"
|
||||||
|
}
|
||||||
|
]
|
||||||
File diff suppressed because it is too large
Load Diff
+180
@@ -0,0 +1,180 @@
|
|||||||
|
# -*- Autoconf -*-
|
||||||
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
#
|
||||||
|
# vlibc — build configuration (see building/C.md and layouts/C.md).
|
||||||
|
|
||||||
|
AC_PREREQ([2.71])
|
||||||
|
|
||||||
|
AC_INIT([vlibc],
|
||||||
|
[0.1.0],
|
||||||
|
[https://vox.dev/vlibc],
|
||||||
|
[vlibc],
|
||||||
|
[https://vox.dev/])
|
||||||
|
|
||||||
|
AC_CONFIG_SRCDIR([include/vlibc.h])
|
||||||
|
AC_CONFIG_AUX_DIR([build-aux])
|
||||||
|
AC_CONFIG_HEADERS([config.h])
|
||||||
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
|
||||||
|
AM_INIT_AUTOMAKE([foreign subdir-objects])
|
||||||
|
|
||||||
|
# ---- Language / compiler -------------------------------------------------
|
||||||
|
# vlibc is implemented in C. Exactly one compiler is selected, with no fallback
|
||||||
|
# to another (building/C.md): GCC.
|
||||||
|
#
|
||||||
|
# Note: AC_PROG_CC sets $GCC to "yes" for any __GNUC__-compatible compiler
|
||||||
|
# (including clang), so it cannot be used to enforce the single-compiler rule.
|
||||||
|
# Verify the compiler is genuinely GCC, not a compatible one.
|
||||||
|
AC_PROG_CC
|
||||||
|
AC_MSG_CHECKING([whether the compiler is GCC])
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [
|
||||||
|
#if !defined(__GNUC__) || defined(__clang__)
|
||||||
|
#error "vlibc requires GCC"
|
||||||
|
#endif
|
||||||
|
])],
|
||||||
|
[AC_MSG_RESULT([yes])],
|
||||||
|
[AC_MSG_RESULT([no])
|
||||||
|
AC_MSG_ERROR([vlibc must be built with GCC (building/C.md). The active compiler is not GCC; re-run with CC=gcc. No fallback to another compiler is provided.])])
|
||||||
|
|
||||||
|
# Enable standard library extensions / POSIX declarations in the host toolchain.
|
||||||
|
AC_USE_SYSTEM_EXTENSIONS
|
||||||
|
|
||||||
|
# ---- C standard ----------------------------------------------------------
|
||||||
|
# The latest stable C standard is used by default (C23). C2y (C29) is opt-in
|
||||||
|
# until it is ratified (languages/C.md).
|
||||||
|
AC_ARG_ENABLE([c29],
|
||||||
|
[AS_HELP_STRING([--enable-c29],
|
||||||
|
[Enable experimental C2y (C29) mode, incl. defer statements (default: C23)])])
|
||||||
|
|
||||||
|
vlibc_cstd=c23
|
||||||
|
AS_IF([test "x$enable_c29" = "xyes"], [vlibc_cstd=c2y])
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([whether $CC supports -std=$vlibc_cstd])
|
||||||
|
vlibc_save_CFLAGS=$CFLAGS
|
||||||
|
CFLAGS="$CFLAGS -std=$vlibc_cstd"
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])],
|
||||||
|
[AC_MSG_RESULT([yes])],
|
||||||
|
[AC_MSG_RESULT([no])
|
||||||
|
AC_MSG_ERROR([$CC does not support -std=$vlibc_cstd])])
|
||||||
|
CFLAGS=$vlibc_save_CFLAGS
|
||||||
|
|
||||||
|
AC_SUBST([VLIBC_CFLAGS], ["-std=$vlibc_cstd -Wall -Wextra"])
|
||||||
|
|
||||||
|
# ---- Compatibility profile ----------------------------------------------
|
||||||
|
# Exactly one of the five profiles is active. They are mutually exclusive;
|
||||||
|
# the default is "vlibc" (glibc-extended, but without the spoofing layer).
|
||||||
|
#
|
||||||
|
# 1 --enable-onlyposix pure POSIX, nothing more
|
||||||
|
# 2 --enable-muslmimic musl-like, light
|
||||||
|
# 3 --enable-muslext musl-extended
|
||||||
|
# 4 --enable-spoof glibc replica (drop-in compatibility)
|
||||||
|
# 5 (default) vlibc (glibc-extended)
|
||||||
|
AC_ARG_ENABLE([onlyposix],
|
||||||
|
[AS_HELP_STRING([--enable-onlyposix],
|
||||||
|
[Build the lightest vlibc: pure POSIX, nothing more])])
|
||||||
|
AC_ARG_ENABLE([muslmimic],
|
||||||
|
[AS_HELP_STRING([--enable-muslmimic],
|
||||||
|
[Build a musl-like vlibc: light, musl-compatible])])
|
||||||
|
AC_ARG_ENABLE([muslext],
|
||||||
|
[AS_HELP_STRING([--enable-muslext],
|
||||||
|
[Build musl-extended vlibc: musl plus more])])
|
||||||
|
AC_ARG_ENABLE([spoof],
|
||||||
|
[AS_HELP_STRING([--enable-spoof],
|
||||||
|
[Build a glibc replica: drop-in glibc compatibility])])
|
||||||
|
|
||||||
|
vlibc_profile=vlibc
|
||||||
|
vlibc_profiles=0
|
||||||
|
AS_IF([test "x$enable_onlyposix" = "xyes"],
|
||||||
|
[vlibc_profile=onlyposix; vlibc_profiles=$((vlibc_profiles + 1))])
|
||||||
|
AS_IF([test "x$enable_muslmimic" = "xyes"],
|
||||||
|
[vlibc_profile=muslmimic; vlibc_profiles=$((vlibc_profiles + 1))])
|
||||||
|
AS_IF([test "x$enable_muslext" = "xyes"],
|
||||||
|
[vlibc_profile=muslext; vlibc_profiles=$((vlibc_profiles + 1))])
|
||||||
|
AS_IF([test "x$enable_spoof" = "xyes"],
|
||||||
|
[vlibc_profile=spoof; vlibc_profiles=$((vlibc_profiles + 1))])
|
||||||
|
|
||||||
|
AS_IF([test "$vlibc_profiles" -gt 1],
|
||||||
|
[AC_MSG_ERROR([--enable-onlyposix, --enable-muslmimic, --enable-muslext and --enable-spoof are mutually exclusive])])
|
||||||
|
|
||||||
|
case "$vlibc_profile" in
|
||||||
|
onlyposix) vlibc_level=1 ;;
|
||||||
|
muslmimic) vlibc_level=2 ;;
|
||||||
|
muslext) vlibc_level=3 ;;
|
||||||
|
spoof) vlibc_level=4 ;;
|
||||||
|
vlibc) vlibc_level=5 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
AC_DEFINE_UNQUOTED([VLIBC_PROFILE], ["$vlibc_profile"],
|
||||||
|
[Active compatibility profile name])
|
||||||
|
AC_DEFINE_UNQUOTED([VLIBC_LEVEL], [$vlibc_level],
|
||||||
|
[Active compatibility level (1..5)])
|
||||||
|
AS_CASE([$vlibc_profile],
|
||||||
|
[onlyposix], [AC_DEFINE([VLIBC_PROFILE_ONLYPOSIX], [1], [Pure POSIX profile])],
|
||||||
|
[muslmimic], [AC_DEFINE([VLIBC_PROFILE_MUSLMIMIC], [1], [musl-like profile])],
|
||||||
|
[muslext], [AC_DEFINE([VLIBC_PROFILE_MUSLEXT], [1], [musl-extended profile])],
|
||||||
|
[spoof], [AC_DEFINE([VLIBC_PROFILE_SPOOF], [1], [glibc spoof profile])],
|
||||||
|
[vlibc], [AC_DEFINE([VLIBC_PROFILE_VLIBC], [1], [vlibc (glibc-ext) profile])])
|
||||||
|
|
||||||
|
AC_SUBST([vlibc_profile])
|
||||||
|
|
||||||
|
# ---- Install method ------------------------------------------------------
|
||||||
|
# "alongside" installs vlibc next to the system libc: headers and libraries go
|
||||||
|
# under a vlibc-specific tree, used via the vlibc-gcc / vlibc-clang drivers.
|
||||||
|
# "overwrite" replaces the system libc in place.
|
||||||
|
AC_ARG_WITH([install],
|
||||||
|
[AS_HELP_STRING([--with-install=@<:@alongside|overwrite@:>@],
|
||||||
|
[Install method: alongside (default) keeps the system libc; overwrite replaces it])],
|
||||||
|
[],
|
||||||
|
[with_install=alongside])
|
||||||
|
|
||||||
|
AS_CASE([$with_install],
|
||||||
|
[alongside|overwrite], [],
|
||||||
|
[AC_MSG_ERROR([--with-install must be 'alongside' or 'overwrite'])])
|
||||||
|
|
||||||
|
AC_DEFINE_UNQUOTED([VLIBC_INSTALL_MODE], ["$with_install"], [Install mode])
|
||||||
|
AM_CONDITIONAL([INSTALL_OVERWRITE], [test "x$with_install" = "xoverwrite"])
|
||||||
|
AC_SUBST([vlibc_install_mode], ["$with_install"])
|
||||||
|
|
||||||
|
# ---- Static linking ------------------------------------------------------
|
||||||
|
# Full static linking is a hard requirement for every profile except spoof
|
||||||
|
# (the spoofing layer needs dynamic facilities a static build cannot provide).
|
||||||
|
AS_IF([test "x$vlibc_profile" != "xspoof" && test "x$enable_static" = "xno"],
|
||||||
|
[AC_MSG_ERROR([the '$vlibc_profile' profile requires static linking; remove --disable-static])])
|
||||||
|
|
||||||
|
# ---- Reference libc for benchmarks --------------------------------------
|
||||||
|
# Benchmarks are built against the software vlibc replaces (musts/BENCHMARKING.md).
|
||||||
|
# By default they link against vlibc itself; --with-libc selects musl or glibc
|
||||||
|
# for the reference comparison.
|
||||||
|
AC_ARG_WITH([libc],
|
||||||
|
[AS_HELP_STRING([--with-libc=@<:@vlibc|musl|glibc@:>@],
|
||||||
|
[Select the libc that benchmark binaries link against (default: vlibc)])],
|
||||||
|
[],
|
||||||
|
[with_libc=vlibc])
|
||||||
|
|
||||||
|
AS_CASE([$with_libc],
|
||||||
|
[vlibc], [],
|
||||||
|
[glibc], [],
|
||||||
|
[musl],
|
||||||
|
[AC_CHECK_PROG([MUSL_CC], [musl-gcc], [musl-gcc], [])
|
||||||
|
AS_IF([test -z "$MUSL_CC"],
|
||||||
|
[AC_MSG_ERROR([--with-libc=musl requires musl-gcc to be in PATH])])],
|
||||||
|
[AC_MSG_ERROR([--with-libc must be 'vlibc', 'musl', or 'glibc'])])
|
||||||
|
|
||||||
|
AM_CONDITIONAL([BENCH_LINK_VLIBC], [test "x$with_libc" = "xvlibc"])
|
||||||
|
AM_CONDITIONAL([BENCH_LINK_MUSL], [test "x$with_libc" = "xmusl"])
|
||||||
|
|
||||||
|
# ---- Libtool -------------------------------------------------------------
|
||||||
|
LT_INIT
|
||||||
|
|
||||||
|
AC_CONFIG_FILES([Makefile
|
||||||
|
benchmarks/Makefile
|
||||||
|
tools/vlibc-gcc
|
||||||
|
tools/vlibc-clang])
|
||||||
|
|
||||||
|
# Make the generated compiler drivers executable. This must run after the
|
||||||
|
# files are created, so it lives in AC_CONFIG_COMMANDS (not the AC_CONFIG_FILES
|
||||||
|
# trailing command, which runs before generation).
|
||||||
|
AC_CONFIG_COMMANDS([chmod-vlibc-drivers],
|
||||||
|
[chmod +x tools/vlibc-gcc tools/vlibc-clang])
|
||||||
|
|
||||||
|
AC_OUTPUT
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# Compatibility
|
||||||
|
|
||||||
|
vlibc offers five compatibility profiles, selected at configure time. They are
|
||||||
|
mutually exclusive; the default is `vlibc`.
|
||||||
|
|
||||||
|
| Level | Flag | Profile | What it provides |
|
||||||
|
|-------|----------------------|-------------|---------------------------------------------------------|
|
||||||
|
| 1 | `--enable-onlyposix` | `onlyposix` | Pure POSIX, nothing more — the lightest possible build. |
|
||||||
|
| 2 | `--enable-muslmimic` | `muslmimic` | musl-like, still light, with musl-compatible features. |
|
||||||
|
| 3 | `--enable-muslext` | `muslext` | An extension of musl, adding more. |
|
||||||
|
| 4 | `--enable-spoof` | `spoof` | A glibc replica: emulates glibc for drop-in compatibility, higher than `muslext` or `vlibc` full. |
|
||||||
|
| 5 | *(default)* | `vlibc` | glibc-extended: glibc minus its baggage, plus extended standard features. High (but not spoof-level) glibc compatibility. |
|
||||||
|
|
||||||
|
## Differences from glibc
|
||||||
|
|
||||||
|
- **No legacy baggage.** vlibc targets modern, standard-conforming behavior and
|
||||||
|
drops glibc's deprecated and non-standard behaviors unless a profile
|
||||||
|
explicitly restores them.
|
||||||
|
- **Extended standard features.** The `vlibc` profile adds extensions on top of
|
||||||
|
the C and POSIX standards that glibc does not provide.
|
||||||
|
- **Spoofing is opt-in.** The `--enable-spoof` profile re-enables the
|
||||||
|
long-standing legacy behaviors that scripts rely on, for drop-in
|
||||||
|
compatibility with existing binaries and build systems.
|
||||||
|
|
||||||
|
## Full static linking
|
||||||
|
|
||||||
|
Every profile except `spoof` must be able to link fully statically. The
|
||||||
|
`spoof` profile is exempt: its glibc-emulation layer depends on dynamic
|
||||||
|
facilities (e.g. `dlopen`-based compatibility shims) that a static build cannot
|
||||||
|
provide.
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
# Install methods
|
||||||
|
|
||||||
|
vlibc has two install methods, selected with `--with-install=`.
|
||||||
|
|
||||||
|
## Alongside (default)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./autogen.sh --with-install=alongside
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
```
|
||||||
|
|
||||||
|
- Does **not** replace the system libc.
|
||||||
|
- Installs headers and libraries under a vlibc-specific tree:
|
||||||
|
`$prefix/lib/vlibc/include` and `$prefix/lib/vlibc/lib`.
|
||||||
|
- Consuming projects use the shipped drivers:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
vlibc-gcc -o app app.c # GCC backend
|
||||||
|
vlibc-clang -o app app.c # Clang backend
|
||||||
|
```
|
||||||
|
|
||||||
|
## Overwrite
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./autogen.sh --with-install=overwrite
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
```
|
||||||
|
|
||||||
|
- Replaces the system libc in place: headers go to `$prefix/include`, libraries
|
||||||
|
to `$prefix/lib`.
|
||||||
|
- The shipped drivers then use the system include/lib paths directly.
|
||||||
|
|
||||||
|
## Compiler drivers
|
||||||
|
|
||||||
|
`vlibc-gcc` and `vlibc-clang` are thin wrappers generated by `configure`. They
|
||||||
|
add vlibc's include and library paths (according to the install method) and
|
||||||
|
delegate to `gcc` / `clang`.
|
||||||
|
|
||||||
|
> **Note:** the drivers are currently stubs. Full sysroot handling for
|
||||||
|
> `overwrite` installs and cross-compilation, and the `-static`/`-lvlibc`
|
||||||
|
> wiring, are added as the library's ABI matures.
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
# Overview
|
||||||
|
|
||||||
|
vlibc is Vox's replacement for glibc: a C and POSIX library that is modern,
|
||||||
|
standard-conforming, and fast. The behavior of the software and its
|
||||||
|
differences from glibc are documented here so they can be understood without
|
||||||
|
reading optimized source.
|
||||||
|
|
||||||
|
## Goals
|
||||||
|
|
||||||
|
- **Replace glibc** for the programs that want a lighter, faster, and cleaner
|
||||||
|
libc, while retaining high compatibility.
|
||||||
|
- **Be benchmarkable**: every component is measured against glibc (and musl);
|
||||||
|
a component slower than what it replaces is considered failing
|
||||||
|
(`musts/BENCHMARKING.md`).
|
||||||
|
- **Static-linking first**: fully static linking is a hard requirement for
|
||||||
|
every profile except `spoof`.
|
||||||
|
- **Honor user flags**: `CFLAGS` and `LDFLAGS` are respected; the build uses
|
||||||
|
exactly one compiler (GCC) with no fallback.
|
||||||
|
|
||||||
|
## Compatibility profiles
|
||||||
|
|
||||||
|
See `docs/compatibility.md` for the five profiles (`onlyposix`, `muslmimic`,
|
||||||
|
`muslext`, `spoof`, `vlibc`) and their differences from glibc.
|
||||||
|
|
||||||
|
## Install methods
|
||||||
|
|
||||||
|
See `docs/install.md` for the `alongside` and `overwrite` install methods and
|
||||||
|
the `vlibc-gcc` / `vlibc-clang` drivers.
|
||||||
|
|
||||||
|
## Compiler intent
|
||||||
|
|
||||||
|
Static linking pulls a whole library into every binary, which is expensive in
|
||||||
|
size. To offset this, the public API declares *intent* to the compiler via
|
||||||
|
attributes such as `__attribute__((const))` and `__attribute__((pure))`. When
|
||||||
|
the compiler knows a call has no side effects and a predictable result, it can
|
||||||
|
fold or eliminate it during optimization, shrinking the final binary even when
|
||||||
|
vlibc is statically linked in full.
|
||||||
|
|
||||||
|
This is a deliberate design constraint: every public function carries the
|
||||||
|
tightest correct intent attribute (see `STYLEGUIDE.md`).
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
This repository is currently a stub — the layout, build system, documentation,
|
||||||
|
and a minimal public API (`vlibc_version()`) are in place. Individual library
|
||||||
|
components are added incrementally, each with benchmarks.
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
#ifndef VLIBC_H
|
||||||
|
#define VLIBC_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vlibc — public API.
|
||||||
|
*
|
||||||
|
* vlibc is Vox's modern replacement for glibc. This header is the public entry
|
||||||
|
* point for vlibc's own extensions; the C and POSIX standard headers
|
||||||
|
* (<stdio.h>, <string.h>, ...) are provided separately and are gated by the
|
||||||
|
* active compatibility profile.
|
||||||
|
*
|
||||||
|
* Compatibility profiles (build-time; see configure.ac and docs/compatibility.md):
|
||||||
|
* 1 onlyposix pure POSIX, nothing more
|
||||||
|
* 2 muslmimic musl-like, light
|
||||||
|
* 3 muslext musl-extended
|
||||||
|
* 4 spoof glibc replica (drop-in compatibility)
|
||||||
|
* 5 vlibc glibc-extended, the default
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define VLIBC_VERSION_MAJOR 0
|
||||||
|
#define VLIBC_VERSION_MINOR 1
|
||||||
|
#define VLIBC_VERSION_PATCH 0
|
||||||
|
|
||||||
|
#define VLIBC_VERSION_STRING "0.1.0"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the vlibc version string ("MAJOR.MINOR.PATCH").
|
||||||
|
*
|
||||||
|
* Declared with __attribute__((const)): the result is a compile-time constant
|
||||||
|
* and the call has no observable side effects. Declaring this intent lets the
|
||||||
|
* compiler fold and eliminate the call, which keeps fully statically linked
|
||||||
|
* binaries small (see docs/overview.md, "Compiler intent").
|
||||||
|
*/
|
||||||
|
__attribute__((const)) const char *
|
||||||
|
vlibc_version(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* VLIBC_H */
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <vlibc.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The version string is defined here, in a single translation unit, rather
|
||||||
|
* than in the header, so that only the library owns the object. Consumers use
|
||||||
|
* the VLIBC_VERSION_STRING macro for compile-time access.
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
vlibc_version(void)
|
||||||
|
{
|
||||||
|
return VLIBC_VERSION_STRING;
|
||||||
|
}
|
||||||
Vendored
+14
@@ -0,0 +1,14 @@
|
|||||||
|
# Third-party
|
||||||
|
|
||||||
|
Third-party libraries are vendored here, per `layouts/C.md`.
|
||||||
|
|
||||||
|
## Policy
|
||||||
|
|
||||||
|
- Vendoring is required to prevent dependency hell: vlibc must build from a
|
||||||
|
checked-out tree with no external downloads.
|
||||||
|
- Every vendored dependency records its upstream source, version, and license
|
||||||
|
in a `README` (or `UPSTREAM`) file alongside its sources.
|
||||||
|
- Vendored code is patched in-tree where necessary; patches are documented.
|
||||||
|
|
||||||
|
This directory is intentionally empty for now — the current stub has no
|
||||||
|
third-party dependencies.
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# vlibc-clang — compile and link against vlibc using Clang.
|
||||||
|
#
|
||||||
|
# Generated by configure from tools/vlibc-clang.in. Do not edit directly.
|
||||||
|
# This is the compiler driver that vlibc ships for its consumers.
|
||||||
|
|
||||||
|
prefix='@prefix@'
|
||||||
|
install_mode='@vlibc_install_mode@'
|
||||||
|
profile='@vlibc_profile@'
|
||||||
|
|
||||||
|
case "$install_mode" in
|
||||||
|
overwrite)
|
||||||
|
vlibc_includedir="$prefix/include"
|
||||||
|
vlibc_libdir="$prefix/lib"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
vlibc_includedir="$prefix/lib/vlibc/include"
|
||||||
|
vlibc_libdir="$prefix/lib/vlibc/lib"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# TODO: full sysroot handling for `overwrite` installs and cross-compilation,
|
||||||
|
# and -static/-lvlibc wiring once the library exports its full ABI.
|
||||||
|
exec clang -isystem "$vlibc_includedir" -L"$vlibc_libdir" "$@"
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# vlibc-gcc — compile and link against vlibc using GCC.
|
||||||
|
#
|
||||||
|
# Generated by configure from tools/vlibc-gcc.in. Do not edit directly.
|
||||||
|
# This is the compiler driver that vlibc ships for its consumers.
|
||||||
|
|
||||||
|
prefix='@prefix@'
|
||||||
|
install_mode='@vlibc_install_mode@'
|
||||||
|
profile='@vlibc_profile@'
|
||||||
|
|
||||||
|
case "$install_mode" in
|
||||||
|
overwrite)
|
||||||
|
vlibc_includedir="$prefix/include"
|
||||||
|
vlibc_libdir="$prefix/lib"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
vlibc_includedir="$prefix/lib/vlibc/include"
|
||||||
|
vlibc_libdir="$prefix/lib/vlibc/lib"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# TODO: full sysroot handling for `overwrite` installs and cross-compilation,
|
||||||
|
# and -static/-lvlibc wiring once the library exports its full ABI.
|
||||||
|
exec gcc -isystem "$vlibc_includedir" -L"$vlibc_libdir" "$@"
|
||||||
Reference in New Issue
Block a user