Single-file C/C++ public-domain/open source libraries with minimal dependencies
github.com
github.com
Package management is somewhat less useful modern code that tends to self contain things (Java/Groovy/Scala) or where you want to pin dependencies for stability and create unique environments for them (Python's virtual env, Ruby's RVM, or .. and this is kinda a stretch, but Docker containers).
For one, there are tons of universal useful libs for C/C++.
Second, not all architectures matter equally. Beyond amd64 and ARM, few give a damn.
I wouldn't mind a more dedicated tool though, especially because relying on distribution-specific packages tends to make cross platform support messy (see: heavy reliance on automake tools to correct for platform differences) and because most distributions only include the most popular, widely used libraries, and don't try to support newer or more niche tools.
The distro package managers try to supply you with a set of end user applications and then provide a consistent set of libraries to make sure the apps run. This sometimes means shipping an older version of a lib to keep an app supported. It's difficult or impossible to have two versions of the same lib, and sometimes there are hacks like python2-mylibrary vs. python3-mylibrary.
Development package managers on the other hand are intended to build your app and all its dependencies. Many versions of the same library may coexist on the same system and sometimes even in the same project. Development package managers typically build from source and do not have a repository of binary packages. And they allow pinning to specific versions with a lockfile to make builds reproducible. This may also include providing a specific version of the compiler/interpreter.
Nix and Guix may be closer to a development package manager than apt/yum/rpm/pacman, but are yet to be widely adopted.
BSD ports, and the many Linux rpm and deb package managers have source and developer packages. There was a time when Linux had no package managers. They were invented precisely to solve the problems of dependency resolution and dissemination of sources and binaries to a distributed global network.
The fact that there are so many package managers is a feature not a bug also. Just like the many distributions of Linux and BSD is intentional and strengthens the ecosystem and allows for innovation and experimentation.
Package management is also available on Windows with Msys2 (pacman) and a few others.
i have successfully used it for BSD, Linux, Solaris, HP-UX, Red-Hat Linux for the same commercial project.
Amitai Schlair: One Weird Trick To Simplify Package Management.
http://www.nycbug.org/index.cgi?action=view&id=10345
Disclaimer: i am not Amitai Schlair
> pkgsrc is a framework for building third-party software on NetBSD and other UNIX-like systems, currently containing over 17000 packages.
And Fedora/Yum has 18000+ packages.
Thats a hell of a lot of C/C++ source code thats tested and configured to compile with the system compiler.
I think this is a case of not being able to see the forest for the trees. The entire open source community and operating systems development revolve around a set of extremely robust C/C++ package managers. But they are so integral to development at this point that they have become almost invisible.
But there is something actively developed in that direction: https://build2.org and https://cppget.org
In fact, the package manager is pretty feature-complete, just the build system is still heavily developed.
Things like Eclipse have, in my mind, greatly altered the perception of source organization in modern systems. I don't think many people think of source as a file but as rather a directory/collection of files.
I'd love to see a build & package management system for C that would be able to:
* Easily configureable by the programmer for a large set of end goals.
Whether or not I want to build an executable, use a custom linker, build a specific DLL type of a specific format it needs to be easy. One example I've worked on is getting Make to output just a plain binary for embeded system development or operating system development is a right pain in the ass. I have no clue how to do it. * Build into seperate directories
Basically if I want to build a sub project and put it's output into /usr/lib or something then I should easily be able to configure that to happen. Most of the time you want to build into ./build/ or ./bin/ or something like that but don't litter my ./src/ with .obj files. * Build out of the directory structure
By default this should look for everything in ./src/ or something to find all of the source files. * Associate source file extensions to compilers.
I should be able to associate all of a certian extension to a certian compiler. For example .C->GCC, .S->GAS, .BAS->FBC, etc. A more advanced example may be me needing to compile in a lot of user (being non-programmers in my office) tables. Doing so I could make a .tlb format and a compiler for a .tlb. This .tbl compiler will just internally translate this to a bit of assembly, pass it through GAS, and then give you an object file. This can be linked to the end product and reached from any of the source files. You could also do a .* as a leftover so you can build a library that will pack extra data into the executable that can be unpacked at runtime by your program. This can be done by writing a "compiler" that reads all the data into a flat array and implements a "file system". You could then call a standard API from this compiler the same way that you could read that table. Just a thought. * Documentation AND Examples.
I cant tell you how many times I've worked with someone on a project and they've said something along the lines of "do X in make and it'll work better" and it has. There's so many undocumented tricks that it's unreasonable. This is partly because of age, how large the project is, and in my opinion how much cruft the implementation has accumulated.Scons has a number of "builders", each of which is associated with a file extension. So, for example, I could look for all files in the src directory that end with either ".c" or ".cc", compile the ".c" files as C, compile the ".cc" files as C++, then link them all together with the following command.
Program("bin/prog", [Glob('src/*.cc'), Glob('src/*.c')])
Custom builders can be added, so if you want to add any additional association (e.g. ".cu" to compile with CUDA), you can.The documentation (http://scons.org/doc/production/HTML/scons-user/index.html) is pretty good as well
Why isn't there a more generic option? Well: There's a ton of closed source C and C++ libraries out there - stuff with license fees and NDAs, tons of fiddly configuration options that are relevant to you - built with closed source and fiddly toolchains with incompatible ABIs for obscure platforms, sometimes with even more fiddly link ordering considerations... to say nothing of additional requirements for distribution. E.g. some of Microsoft's stuff prohibits "xcopy deployment" and instead requires you to run their installers instead - presumably to make their job easier when they want to roll out a security update.
To try to slay this beast with abstraction is to try to slay a hydra. For every compiler or configuration option you decapitate, two more you hadn't considered before will come into view.
Even when you constrain yourself to the single platform package managers, things are far from perfect. I've had nuget packages that can't handle the latest version of VS. I've seen apt lagging several versions behind the latest boost. They weren't built with the specific fiddly #define s that customize this for my needs. Upstream doesn't want your fiddly project-specific customizations, and legal has better things to do than verify you're not violating any NDAs by contributing back upstream...
The "easy" option is to simply get really good at wrangling absolutely terrible build chains.
Someone recommended Conan[0] to me the other day. I'm not familiar with it, so can't say more.
[0] "Conan C/C++ Package Manager" https://www.conan.io/
- there is no standard cross-platform build system and directory structure for C/C++ projects, a dependency manager either needs to be super-flexible and enable to combine projects with completely different build systems (which is impossible I guess?), or come with its own build system and enforce a directory structure (like Rusts cargo)
- complex C++ projects are not very compatible with each other since they use different subsets of the C++ language and the standard library, this makes it often hard or impossible to integrate external C++ code
This is why header-only, or single header/source pair C or (simple) C++ projects make so much sense, they are often trivial to integrate with your own code.
However, there are some movements into the right direction, cmake seems to establish itself as the standard build system, and there's also https://www.conan.io/
It would be better though if the C++ Standard Committee would get their act together and instead of stuffing more and more useless crap into the C++ standard, use the time and resources to establish a dependency manager standard (along with a proper module system), and let the language users move all the 'useless crap' there.
How does this make sense? If a project uses a certain style, that doesn't make it incompatible with another style by any measure.
We wrote a thing like this at Mapbox, try it out: https://github.com/mapbox/mason
In addition to clib[1] mentioned in this list, there's also CCAN[2]. It's another collection of small C libraries, but unlike clib and this list, the libraries are maintained as a single project (for better or worse).
I'd love to see some more convergence on library search and package management for C. I was glad to see clib and CCAN consider coordinating.[3] Hopefully that effort will eventually bear fruit.
1. https://github.com/clibs/clib 2. https://ccodearchive.net/ 3. https://github.com/clibs/clib/issues/69
The implementation design was a trade-off between minimizing redundancy and minimizing dependencies (and inter-dependencies). Ultimately I decided minimal dependencies would be more appealing to the user.
[1] shameless plug: https://github.com/duneroadrunner/SaferCPlusPlus
[1] https://github.com/duneroadrunner/SaferCPlusPlus#safercplusp...
>Q. Why isn't SQLite's amalgamated build on this list?
>A. Come on.
For the answer, look at the SQLite Amalgamation page[1]
>1. Executive Summary
>Over 100 separate source files are concatenated into a single large files of C-code named "sqlite3.c" and called "the amalgamation". The amalgamation contains everything an application needs to embed SQLite. The amalgamation file is more than 180,000 lines long and over 6 megabytes in size.
So although it's technically a single file, at 180 000 lines and 6 Megabytes, it's not really in the spirit of the page.
Edit: to be even clearer, sqlite is 100+ .c files. Yes, you can make it one "amalgamated" .c file, but no developer works on that file; they work on the 100+ smaller .c files.
The amalgamation is used for instance in the most popular Golang library to provide SQLite engine.
- Libraries must be usable from C or C++, ideally both
- Libraries should be usable from more than one platform (ideally, all major desktops and/or all major mobile)
- Libraries should compile and work on both 32-bit and 64-bit platforms
- Libraries should use at most two files
Then ya, I think it'd fit. I'm not sure why size matters here: the goal is to have libraries that are easily embedded. Anyway, I was mainly curious for the reason. If size is the reason, then that's that. Thanks!
Why would it matter if the original developer coded everything in a single, huge file or multiple small ones that get distributed as one? Seems arbitrary.
On your part, that is.
I'm not very familiar with C++ (it's been a long time ago), but a friend recently came to me with some questions about vector/matrix algebra (though at first he didn't know his questions went by those names), wanted to write a toy physics engine in C++. I kind of assumed that C++ would have at least a basic selection of your typical vec2/3/4 data types and functions in its standard library--because C++ pretty much invented (or at least made popular, right?) operator overloading, and I don't know about everybody else, but vector math would be the very first thing that comes to mind learning about operator overloading and thinking "huh, what useful thing could I do with this".
But it's not there (unless I didn't look properly?). So I told him (after explaining why vectors and matrices are nice to have in the first place) to write his own, because it's not hard if you don't need all the functionality in algebra3.h and it's a nice exercise for C++ classes and operator overloading.
Now my questions, since we're in a thread with people that know a whole lot more about C++ than I do:
Is there really no mathematical vector/matrix algebra data type with associated functions in the C++ standard libraries? (And I don't mean the one called Vector, that's really sorta-kinda like a list)
If no, what do people generally use? Lightweight, or big framework?
On the lightweight side of things, is algebra3.h a relatively good choice?
I looked through the code and saw a few things that bugged me. Angles are in degrees (math code and functions use radians internally everywhere, this is just burning some useless muls and divs for a unit change that will be mistaken and cause a bug in someone's code some day somewhere). That one I'd immediately change before using this lib :) I'd like to reserve degrees just for displaying and input.
I've been coding a lot of GLSL recently, and IMO their built-in vector math functions are pretty well thought-out, so there's some choices that differ. Like the overloaded asterisk (multiply) operator is sometimes a dot product, other times element-wise mul. From experience, I've found my code to be more readable when using an asterisk for operations just interchangeable with a scalar multiply (which is element-wise), 'dot' and 'cross' as names functions (you don't use the cross-product nearly as much to warrant its own operator, and the name 'dot' hits the sweet spot between being short enough so it doesn't matter you use it a bit more often) and preferably another operator for matrix-multiply (maybe the '@'? is that possible in C++?) to signify it's not commutative and just really really not at all what the asterisk-operator usually does with scalars and vectors (bonus, you also get an element-wise multiply for matrices, yay).
Ooh and here's a nice one, is there any nice way to implement dimension swizzling of vectors in C++ like GLSL has? Like you could say P.xzyy and get a vec4 consisting of elements 0,2,1 and 1 of vector P, respectively. Because that was like the coolest thing ever when first learning GLSL, I've never seen anything like it :)
In general, overloading operators beyond arithmetic is a bad idea. It just leads to confusion and strange mixed-mode semantics. Python suffers from this. "+" is concatenate for vectors of numbers, but addition for numpy arrays. You can add a vector to a numpy array in Python without getting an error. Guess which action takes place.
I often need some simple thing that can take input from Stdin while I'm piping stuff around in a bash script. Like telling me the db audio level of a mp3 file while reading through all the files in a directory.
An stb library is often the precise mess you need, and maybe even the one you deserve, with none of the seemingly-infinite, unbounded dependency messiness that you don't.
Sean's doing the Lord's work here, or at least the Buddha's.
I agree with you in principle though. A directory of header files is, in practice, and in my experience, no more difficult to work with than a single header file and (can) allow for more modularity.
It's because C/C++ still doesn't have a decent module system, nor a universally accepted library distribution system. You can still write the project as separate files and the concatenate them for distribution.
(See? I can do it too!)
At the same time, many of the major C++ applications we use don't use package management/external dependencies. Sometimes it's for security, but mostly it's for stability and reproducibility in bug management.
Firefox has its own embedded PNG, JPEG et. al. libraries. Professor Silvio from Australia has done a lot of work on identifying outdated libraries with security vulnerability embedded in C/C++ projects.