{"id":20332468,"url":"https://github.com/permutationlock/libaven","last_synced_at":"2025-06-14T02:03:53.571Z","repository":{"id":253861785,"uuid":"844742334","full_name":"permutationlock/libaven","owner":"permutationlock","description":"A collection of portable headers that I use in projects.","archived":false,"fork":false,"pushed_at":"2025-06-12T23:12:11.000Z","size":1432,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-13T00:25:37.243Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit-0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/permutationlock.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.MIT","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-08-19T22:08:46.000Z","updated_at":"2025-06-12T23:12:14.000Z","dependencies_parsed_at":"2024-08-29T10:03:31.396Z","dependency_job_id":"88bda6c3-4774-460d-b6ed-640f4d99a58d","html_url":"https://github.com/permutationlock/libaven","commit_stats":null,"previous_names":["permutationlock/aven.h","permutationlock/libaven"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/permutationlock/libaven","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/permutationlock%2Flibaven","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/permutationlock%2Flibaven/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/permutationlock%2Flibaven/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/permutationlock%2Flibaven/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/permutationlock","download_url":"https://codeload.github.com/permutationlock/libaven/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/permutationlock%2Flibaven/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259747195,"owners_count":22905308,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T20:26:44.344Z","updated_at":"2025-06-14T02:03:53.565Z","avatar_url":"https://github.com/permutationlock.png","language":"C","readme":"# libaven: a tiny portable C library, and build system\n\nI love programming in C, but I always need slices, optionals, and\nresult types (a.k.a. \"errors as values\").\nThe `aven.h` header contains unintrusive definitions for these types.\nIt also defines a debugger friendly `assert` macro and bounds checked slice\naccess macros.\n\nThe library has expanded to include:\n\n - optionals, results, slices, lists, queues, and pools: `aven.h`\n - arena allocation: `aven/arena.h` ([inspired by this post][2])\n - command line argument parsing: `aven/arg.h`\n - a C build system: `aven/build.h`, `aven/build/common.h`\n - simple string formatting and parsing: `aven/fmt.h`\n - portable file system interaction: `aven/fs.h`\n - simple hashing, hash sets, and hash maps: `aven/hash.h`\n - portable I/O independent of libc: `aven/io.h`\n - a tiny SIMD linear algebra library: `aven/math.h`\n - portable file path string manipulation: `aven/path.h`\n - portable process execution and management: `aven/proc.h`\n - a random number generator interface: `aven/rng.h`\n - slice-based strings: `aven/str.h`\n - a bare-bones test framework: `aven/test.h`\n - portable thread primitives: `aven/thread.h`, `aven/thread/pool.h`\n - portable high precision timing: `aven/time.h`\n - portable directory watching (Windows + Linux only): `aven/watch.h`\n\nEverything is cross-platform for Linux and Windows. Many things will work\non non-Linux POSIX systems, but not all[^1].\n\n## Minimizing namespace polution\n\nAll identifiers for functions, variables, and macros are snake case\nand begin with a prefix for the corresponding header path, except for the\ncore defined in `aven.h`. E.g. the alloc function defined in `aven/arena.h` is\n`aven_arena_alloc`.\n\nWhen built as a separate translation unit using the build system (see below),\nthe headers will only include the following C standard headers:\n`stddef.h`, `stdbool.h`, `stdint.h`, and `stdassert.h`.\nIf compiling for C11 then `stdalign.h` is also included.\nIf using the standalone `aven/time.h` portable timing header, then the libc\n`time.h` is included for `timespec` support.\n\nWhen used as a header only library via the `AVEN_IMPLEMENTATION` macro,\na small number of other C standard library headers will be included.\nFor Windows targets a few C runtime headers are included (e.g. `io.h`), but\nbespoke declarations are used in lieu of the massive unmanageable Win32\nheaders[^3].\nFor Linux targets, some files require POSIX features to be enabled\n( `_POSIX_C_SOURCE \u003e= 200112L`), and a few POSIX specific headers will be\nincluded. Linux\nspecific features are used where necessary, e.g. `sys/inotify.h` for directory\nwatching and `/proc/self/exe` for exe path discovery; such functions simply\nreturn errors on non-Linux POSIX targets.\n\nThe dependency on libc is so minimal that the Linux header-only [`nolibc`][8]\nis supported. Disable the standard libc (e.g. `-nostdlib`), define\nthe macro (e.g. `-D AVEN_LINUX_NOLIBC`), and include the `nolibc` headers\n(e.g. `-I /path/to/nolibc/include`). Even though `nolibc` seems to provide the\n`__stack_chk` symbols in `stackprotector.h`, I've never been able to get stack protection\nworking with `gcc` or `clang`. Therefore you will likely also need to disable stack\nprotection with `-fno-stack-protector`.\n\n## Aven C build system\n\nThe most prominent part of the library is the build system. I've long been\nfrustrated by the poor portability of Makefiles and the complications of\ndepending on a larger build system like CMake. I wanted a build system\nthat satisfies the following requirements:\n\n - it should depend only on the existence of a C compiler (`cc`), a linker\n   (`cc` or a separate `ld`), and (maybe) an archiver (`ar`);\n - it should include a portable API to interact with the filesystem\n   (`mkdir`, `rm`, `rmdir`, `touch`) wihtout relying on external binaries[^2];\n - builds should be acyclic directed graphs of steps;\n - the user must be able to specify exactly what executables and flags will\n   be used for each build tool, e.g. how the variables `CC` and `CFLAGS` are\n   used in Makefiles;\n - there must by a standard easy way for a parent project to build and use\n   artifacts from a dependency project.\n\nThe following toochains are fully supported, e.g. the default configuration\nshould work out-of-the-box when one is used to compile the `build.c`. \n\n - GNU (Linux + Windows w/[MinGW][3]): --cc gcc --ar ar\n - clang (Linux + Windows w/MSVC or MinGW): --cc clang --ar llvm-ar\n - MSVC (Windows): --cc cl.exe --ld link.ex --ar lib.exe\n - [tinycc][5] (Linux + Windows): --cc tcc --ccflags\n   \"-D\\_\\_BIGGEST\\_ALIGNMENT\\_\\_=16\" --ar tcc --arflags \"-ar -rcs\"\n\nThe following toolchains are undectectable from predefined macros, but have\nbeen tested with the indicated configuration.\n\n - [Zig][1] (Linux + Windows): --cc zig --ccflags \"cc\" --ldflags \"cc\" --ar zig\n   --arflags \"ar -rcs\"\n - [cproc][4] w/GNU (Linux): --cc cproc --ccflags \"-std=c11\" --ar ar\n\nHopefully many other toolchains are supported as well! The MSVC\ntoolchain is so weird that the build configuration has been expanded to be\nvery accommodating.\n\n## Building the library\n\nA linkable `aven.o` object file can built using the contained build system. \n\n### Building the build system\n\nOn Linux systems you can compile the build system with `make`.\n\n```shell\nmake\n```\n\nYou can also simply compile it manually with your favorite C compiler,\ne.g. using `gcc`\n\n```shell\ngcc -o build build.c\n```\n\nor [tinycc][5]\n\n```shell\ntcc -D__BIGGEST_ALIGNMENT__=16 -o build build.c\n```\n\nor MSVC on Windows.\n\n```shell\ncl.exe /std:c11 /Fe:build.exe build.c\n```\n\n### Showing the build system help message\n\n```shell\n./build help\n```\n\n### Building the library\n\n```shell\n./build\n```\n\n### Running the tests\n\n```shell\n./build test\n```\n\n### Cleaning up the build artifacts\n\n```shell\n./build clean\n```\n\n### Cross-compilation\n\nSince the build system is simple and flexible, cross compilation is achievable\nregardless of the host or toolchain. The commands below build the build system on a\nhost `x86_64` Linux machine with TinyCC, then create build artifacts for\nan `x86_64` Windows target using MinGW-w64.\n\n```\ntcc -D__BIGGEST_ALIGNMENT__=16 -o build build.c\n./build --cc \"x86_64-w64-mingww32-gcc\" \\\n    --ar \"x86_64-w64-mingw32-ar\" \\\n    --windres \"x86_64-w64-mingw32-windres\" \\\n    --ccflags \"-std=c11 -O3 -Werror -Wall -Wextra\" \\\n    --exext \".exe\" -soext \".dll\" \\\n    --ldwinflag \"-mwindows\" \\\n    --syslibs \"kernel32 user32 gdi32 shell32\" \\\n    --winutf8\n```\n\nTry this command in a project that produces a graphical application like\n[`libavengraph`][7].\n\n[^1]: Some things like file system notifications and detecting the path to a\n    running executable are not standard across\n    POSIX systems. Currently everything in `aven/watch.h` and the\n    `aven_path_exe` function are implemented\n    for Windows and Linux only.\n\n[^2]: If you have ever tried to write a `make clean` step that works\n    on both Linux and Windows, then you know my motivation here :(\n\n[^3]: I like to know what is in my C namespace. I am a [musl][6]\n      man and can easliy read through the simple libc and Linux headers.\n      Windows Win32 API on the other hand has massive \"inaccessible\" headers,\n      but good documentation and little variation accross architecture.\n      Thus is simply nicer to write the definitions myself.\n\n[1]: https://ziglang.org/\n[2]: https://nullprogram.com/blog/2023/09/27/\n[3]: https://www.mingw-w64.org/\n[4]: https://sr.ht/~mcf/cproc/\n[5]: https://repo.or.cz/w/tinycc.git\n[6]: https://musl.libc.org/\n[7]: https://github.com/permutationlock/libavengraph\n[8]: https://github.com/torvalds/linux/tree/master/tools/include/nolibc\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpermutationlock%2Flibaven","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpermutationlock%2Flibaven","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpermutationlock%2Flibaven/lists"}