Well, since they seem to be including collections of elements, each with dependency on one or two files, SaferCPlusPlus[1] could be added to the "data structures" category. It's a collection of safe compatible substitutes for C/C++'s unsafe elements that's generally intended to be used as a whole, but certainly supports cherry picking of individual elements. For example, you could choose to use its safe substitutes for std::vector (and std::array) while foregoing its safe pointer substitutes.
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.
There is also _GLIBCXX_DEBUG - if you have defined this symbol, glibc will use safer variant of std::vector, iterators etc, which asserts when you attempt to do bad things like reading out of range.
Yup. SaferCPlusPlus has vector and array substitutes that will also catch "use-after-free" bugs and use of invalid iterators. Clang/LLVM and gcc also provide "sanitizers" with much more comprehensive checking. But there are still situations when you'd want to use SaferCPlusPlus [1].
yes (firstly, clicking the link does not imply that you'd read the fucking intro so) they are by the same author, the link in the intro does not describe what they are for, and is easily missed
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.
IMHO it's dumb to limit the libraries to just two files. Whether or not a library is included in the list should be determined on a per-library basis. Some header-only libraries simply require more than one header file or the source code becomes an absolute mess.
You don't understand. It's OK if the source code becomes "an absolute mess." That's because it's a finite absolute mess, as opposed to most FOSS library and utility projects.
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.
Multiple parts to a header-only library can be concatenated into a single header file for easier inclusion, however. Some single header-only libraries are actually built this way.
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.
The single-file approach is to simplify including the library in your project. Just copy the file and type #include "whatever.h".
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.
It sorta does. It's just we use the packaging tools of the operating system (like apt-get and equivalent tools on other systems). That and pkg-config solves 99% of the problem on Unix-based systems. Windows on the other hand... Good luck.
In the FAQ it just says "Come on" for SQLite included in the list. Can you provide a bit more detail? This feels like a pretty great option to include here.
My theory: everybody knows sqlite can be distributed as a single-file library that you can happily embed. However, it's a pretty complex beast compared to the rest of the list and maybe it's outside the vision of the list altogether, which features much simpler projects.
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.
- 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!
Sure, why not? It's just another distribution method of a library and it seems to fit the criteria.
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.
I was puzzled by that too. I've used the SQLite amalgamation and thought it was a very clever way of avoiding the complexities of libraries. I took inspiration from it in my chess program and amalgamated all my chess primitives into a single file to avoid the pain of a library dependency. It's an inspired idea and deserves better than "come on".
This is a great list, primarily for learning and experimenting. However I would not use these for production purpose. Typically production apps require Security, Performance, handling of edge cases, Memory leaks, and reliability in addition to functionality. It is easier to implement functionality in a single file library, however the scope increases significantly when you start adding things like os/hw/api abstraction layers, and aspects other than functionality.
You've not explained how a header-only approach precludes "security, performance, handling of edge cases, memory leaks [presumably you mean the absence of] and reliability".
Leave him be, he must've just learned all those words, and in the great tradition of average human discourse, put them together to form a grammatically coherent yet nonsensical utterance that nonetheless achieves its main objective, namely making him feel good about himself.
So when you talk about security, you're usually talking about package management. The idea being, if you use official packages that are maintained, security advisories can be patched and you can get those with updates.
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.
>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.
This is so funny. BTW, even now, browser still love your JavaScript project in few large files. And before HTTP2 widely used, I think it's still the way to go.
I've lately found myself wondering why there isn't a C/C++ tool comparable to npm, cargo, cpanm, etc. There's more C/C++ code in the wild than most languages, but it's not easy to find, not easy to install, not easy to update (though that's a problem in the npm ecosystem, too), and not easy to integrate. A good package manager would go a long way toward modernizing the C ecosystem, I think.
coz c++ itself is architecture dependent. and even lots of c++ code are architecture dependent.
c++ has much longer history than js or java. It runs on bare metal machine for all kind of purpose. So it is much harder to write universal useful libs.
Totally. When you consider linking and binary compatibility, C/C++ does well with the Linux package management world that's grown up around it.
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).
I think that's because on most Linux-like systems, the distribution's built in package manager fills this role sufficiently. It's hardly perfect, but for many popular libraries you can just install the -dev package or equivalent, then include the headers from the system path and code away.
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 like apt or pacman don't really fulfill the same task as development package managers like cargo or npm.
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.
I don't think your parent was endorsing this state of affairs, but merely offering it as an explanation. I think they are correct - the platform package managers are good enough for the purpose of developers to make it hard for any proper language package manager to gain traction. Even though these approaches may be deeply flawed - by making reproducible builds impossible, among other issues - a majority of users are satisfied with it and do not suffer enough pain to move on. Indeed, I'd much rather `pacman -S boost` and be done in three minutes than wait three hours for a package manager to build it from source. Nix and Guix do get closer to the mark since they allow reproducible builds and can download binaries for me but as long as adoption remains limited I'll be packaging too many libraries myself.
A small book could probably be written on the subject, but the basic issue is that not enough stuff is standardized for it to be a very manageable problem. The situation is sort of like if npm had to support not just Node, but also all the JS engines and object models in browsers and Flash Player.
C/C++ has wonderful package managers you just have to use Linux or BSD to use them. Linux and BSD package managers sort of invented the whole idea of network package management in the first place.
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.
> 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.
I agree that there is a huge issue with finding a "good" build system for C and C++. There are thinks like Make but they were designed for entierly different mentalities of software then we have now.
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.
I've had good experience with scons. It can make shared/static libraries, executables, etc. If you need a custom linker, that is just changing one variable in the environment. Out-of-source builds take a little bit of configuring, with VariantDir, but work well once they are set up.
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.
Other people mentioned nix package managers (rpm, apt, etc.) - I'll also mention nuget is apparently an option for native code too.
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.
- 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.
> 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
How does this make sense? If a project uses a certain style, that doesn't make it incompatible with another style by any measure.
If a project disables exceptions and RTTI, other projects which uses those won't compile (at least on GCC and clang). Many low level C++ projects don't use std containers, std::string or iostreams, etc...
Dependencies may be compiled and then downloaded as package. In Java dependencies, theoretically, could be compiled during the project building, but they are provided as compiled anyway. It is faster that way. Here you have different platforms, but I guess it could be done anyway.
There is, it's called your OS' package manager. Languages having package managers is a retarded idea, descentrilizing what has always been good for being centralized - package managers. Want something your distro doesn't provide? Add a source to the sources list, etc.
I've been wondering where I can find guys to write a few dozen lines of C/C++ for my Go and/or bash scripts.
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.
Good idea, but submissions require forking the project, editing their directory file, and submitting a pull request. All this does is maintain a list. I just submitted "algebra3.h", vector functions for 2, 3, and 4 element vectors, all as inline C++. I've had that on a web site of mine since the 1990s.
That one seems to be in there now? Or at least in the recent additions section. It was the first one I clicked on :)
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 :)
The design of that library isn't mine. It's from "Graphic Gems IV". I just rewrote it in C++ as all inline, when I needed it for a physics engine in the 1990s. It's been used in a few college courses.
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 am glad that developers are willing to create truly free software under public-domain license, so one can just use it at will (for example copy just one method from the code) without worrying about licenses or needing to hire a lawyer.
68 comments
[ 2.6 ms ] story [ 88.7 ms ] threadThe 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...
You will die of shame for insulting His high priest.
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
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.
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.
(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.
>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.
[1] https://www.sqlite.org/amalgamation.html
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:
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. 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. By default this should look for everything in ./src/ or something to find all of the source files. 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. 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.
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
https://github.com/pfultz2/cget
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.
http://blog.ralch.com/tutorial/golang-command-line-pipes/
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.