"header-only" is the closest thing C has to a (good) package manager. The build ecosystem is terribly antiquated, so people use header only as a way to skip the integration step
I assume you are not familiar with modern C, but I think it's a good opportunity to explain.
A single header style allows you to customize the library with the preprocessor before `#include`. I use this ability to implement generics. Otherwise, you're stuck with void* or code generation (want my python script instead?).
However, you don't have to forgo the benefits of separate compilation units. You can include the declarations in a header, and the implementation in a separate C file. No other parts of the code base will be impacted.
That isn't modern C. It's the cool kids backporting a misfeature from C++ because that's what all the game devs do. Header only serves no purpose in C other than to demonstrate that you can't drive your tooling. Plus you've created a new burden to keep track of the magic define that activates the definitions in the code and the one file where it's invoked.
KISS is a feature indeed.
I like to think that I can drive my tooling, and I do appreciate not having my choice of build system being affected by this library.
I understand that some libraries are themselves so big and complex that they need a build system. Each library I want to use that doesn’t is a blessing.
The issue here is people too lazy to tell their compiler where to find a header file so instead they cook up a bespoke system that is specific to every library using this approach.
That is not why this project is header-only. It's so you can include it multiple times to produce multiple specialized types; it has to be header-only so it can produce a series of structs and functions for each specialized type into your compilation unit, with the compiler separately checking each produced specialization. You configure it before including using a series of preprocessor defines. It's a common way to handle generic types in C.
This can't be a single separate compilation unit that you link in; the generic specialization doesn't work that way. You seem to be talking about libraries that are header-only purely for convenience but this is not one of those projects.
With a library like this, you'd want to have one .c file in your project that produces all the implementations for your specialized types, then link that with the rest of your project. From a quick look at the doc, this project supports this.
> one .c file in your project that produces all the implementations for your specialized types
That depends on the compiler, linker and desired linking being static or dynamic and resource concerns. If dynamic, the entire specialized/monomorphized library could be loaded for a single function compared to static linking with the "-O2 -flto" options that removes unused functions.
If I am right, in C, it is not possible to implement fast type-safe generic algorithms without stuffing everything in headers. libc's qsort can be implemented in a separate .c file but it is a lot slower than std::sort as a result.