One thing I cannot stand about C++ is the fractured nature of everything. Compilers, build tools, package management, etc... It feels like you need to be a wizard just to get a project compiling and start writing some code.
The worst part is when you want to bring along people that are not as much of a wizard as you are. I've been prototyping some multiplayer, online video game with MMO-like sharding for a while now, mostly the backend and core stuff for the project and wanted to get two of my friends on the project to develop the gameplay logic which is largely done through a dynamic scripting language, but some features (that, say, I did not foresee needed yet), require source changes to expose the APIs to the scripting language, now, these guys are capable of doing these changes but the onboarding process for a single potential co-developer is such a pain, I basically have to explain to them how to download a compiler, a package manager like vcpkg (which wasn't even that much usable for these types of things pre-versioning, and is still not working properly - i.e. trying to pin LuaJIT version to 2.0.5 for VM bytecode compatibility will attempt to build LuaJIT with cl.exe on Linux), a build system like CMake, and so on, then guide them through all the steps to get the compiler, the build system, and the libraries working, and then hope that in the end they will actually work and not force you to spend an entire day over a remote desktop software trying to get them to become productive.
Include more of your dependencies in the repo and build them aa part of the ordinary build process. Now a package manager does not need to get involved.
Manually copy-pasting source trees around sounds like such an outdated idea from decades ago on how to approach dependency management in a modern programming language. Not to mention that you then have to hook them up to the build system that you are using and not all of them will work out of the box with the one you are using for your project, sure, if you are using CMake and your dependency uses CMake, you can add a subproject, how do you deal with it when they're mixed-and-matched aside from rewriting the builds for every dependency you're pulling in; or without manually writing glue shell scripts to build them independently and put them into a directory? How do you then ensure the said shell script works across different platforms? There are way too many issues with that approach that are solved in other languages through a standardized project management tool.
You don't have to actually copypaste. You can use CMake and FetchContent/CPM. You can specify custom build commands or inline declare a project for anything small that you pull in that doesn't use CMake (you can call add_library with a glob on the folder FetchContent pulled in, for example - I've done so here https://github.com/basis-robotics/basis/blob/main/cpp/CMakeL... for a header only lib). For large external dependencies that are either very slow to compile or for some reason aren't CMake, reach for the system package manager or similar. If you want to be really cross platform and are supporting Qt/wxwidgets/etc, vcpkg+CMake+clang is solid combo, if a bit slow and a bit disk space heavy with the build cache.
And yet that's the right approach. It's not really copying but rather onboarding.
You don't want to depend on a third-party hosting the code, so you need to copy it, and pin it to a specific version. You might also need to patch it since you'll be using it and most likely will run into problems with it.
Using third-party code means taking ownership of all the problems one might encounter when trying to use it in your project, so you might as well just adapt it for it to work with your tools and processes.
If you use a modular system this is essentially just maintaining a fork.
Have you taken a look at CPM ? https://github.com/cpm-cmake/CPM.cmake . It makes CMake project management easy - no need for separate package manager tool.
That’s similar to what vcpkg does under the covers. It clones the repo containing the dependency’s source code and then compiles it using the same compiler as the rest of your project. This avoids static libraries and ABI considerations while also avoiding having to copy/paste their entire source tree into your own.
Can't you just put that into a docker container?
This is more of a workaround than a solution; see my other comment in this thread.
you DO need to be a wizard to launch a large C++ project.
Yes, languages that are beginner friendly are ... friendlier. Yes, languages that stick to one or a small number of programming paradigms are friendlier. But if you want the "flexible efficiency and raw power of C" and "something higher level than C", C++ is your baby.
Maybe it would be better if we all used Java, Rust, and Go, but C++ sings its siren von Neumann song to the wizards, and there will always be wizard musicologists who steer their projects toward those rocks and, when they have just enough wax in their ears, they sail right past the rocks and come out the other side of the straits leading the rest of the fleet.
You can choose to follow them or not, for there's no shame in coming in 4th.
Even the wizards are moving to Rust/Zig since C++ stdlib performance is becoming terrible thanks to the ABI-frozen till heat-death of the universe decision. Even wizards don't want to build a stdlib of their own from scratch.
Feel the committee was smoking weed that day in la-la land. You can ignore all the safety stuff from Sean Baxter, but saying no to performance on the altar of permanent, un-specified ABI backward compatibility - when such was never mentioned as a design goal of C++ - means its "Goodbye C++" for a long, long list of orgs and "wizards". The ABI was NEVER specified formally by the C++ standard - so why bother sacrificing the world for its immortal existence ?
C++ is NO longer the choice of language for greenfield native projects and the committee takes the full blame.
Really looking forward to zig 1.0. I feel like C++ has become a language where professionals are fine with the historical grime but for hobbyist and people that need C++ occasionally there is just no motivation in the community to make this language more ergonomic.
ABI compatibility is one of those things that is necessary with such a long history, especially with commercial libraries that don't really have an equivalent in the newer languages. The issue with C++ that doesn't exist with it's competitors is that there is a long tail of software people use commercially that isn't source available that's incredibly important in certain use cases.
I worked in a previous role on C++ CAD/simulation software that required vendored things like solid modelling kernels and it was incredibly painful. Occasionally one of the vendors would just not do the work and you'd end up having to spend half a year ripping out the dependency that worked perfectly well. The team working on the software were generally in favour of moving up through to modern standards, while I was there we did 03 -> 17 for e.g. but that didn't finish til 4 years after the C++17 standard came out for all sorts of reasons. When VS2017 came out everyone breathed a sigh of relief because suddenly we didn't have to wait to upgrade the compiler.
So here's the thing. Almost none of the problems I have with C++ are related to "flexible efficiency and raw power of C". You could easily have language that is even more flexible and powerful, but much easier to use. Or not even use, just install.
C++ was always by far the most inefficient langauge to work with for me, because there's just so much chore and nonsense that you have to get through to get anything done, and almost none of it has any reasonable purpose, there's no efficency tradeoff. I'm pretty sure that the insane build situation or UB in uninitialized variables or unspecified argument evaluation order never really benefited anybody, they are just bad decisions in the language, and that's all.
> UB in uninitialized variables
You will be happy to learn the uninitialized variables are not UB as of C++26.
They're just initialized to some unspecified value and cause almost-as-hard-to-diagnose faults.
the unspecified value is supposed to be something really obviously wrong (in particular sanitizers will look for it.) and so be easier to diagnose with tools. Unlike 0 which is really hard to diagnose because often it is the right value and so when it isn't you won't realize what you did wrong.
> but C++ sings its siren von Neumann song to the wizards, and there will always be wizard musicologists who steer their projects toward those rocks and, when they have just enough wax in their ears, they sail right past the rocks and come out the other side of the straits leading the rest of the fleet.
beautiful, in equal parts true, sad, and endearing.
but also remember the vasa.
So much for the theory, then there is the hard reality how standard library is implemented, the variantions across implementations, and how the ongoing ABI drama is preventing any performance improvements to it.