Sadly the C++ ABIs are standardized the way that C ABIs are (I'm OK with why but it's unfortunate in that it creates a barrier) so you have to have separate libraries compiled with g++ and clang++ if you use both on your platform (we use both because they catch different bugs, and for that matter exhibit different bugs). But it means you can't simply install, say, fmt in any system-wide directory like /usr/lib or /usr/local/lib
Just as an amusing side note: Common Lisp used to be criticized for the massive size of its libraries and later likewise C++. It was true they were quite large. Now both are criticized for their tiny libraries. Which by today's standards they are.
Yes, gcc and clang use the same platform API so if they use the same headers (libstc++ or libc++) then they will indeed use identical structure layout etc.
I meant a "gcc-native" toolchain (gcc + libstdc++) vs "llvm native" (clang++ + libc++) having different layout (and there is even some interoperability between them thanks to work by the llvm team). I realize my need to do this (to try to minimize opting bugs) is a special case, and probably unusual.
Actually I would bet that even among clang users, libstdc++ is used more commonly on GNU/Linux (IDK for sure, but it’s my hunch).
Part of "size of libraries" is "mental size of libraries".
And C++ and Lisp and have very large mental spaces for their main core libraries. A "String", for example, carries a huge amount of mental baggage in those languages. In most other languages, a string is extremely straightforward because it was designed into the language from the start.
It's essentially a std::vector<char> with a few random convenience features bolted on.
I guess some of the confusing points are: not unicode aware, string literals aren't std::strings by default, c_str returns a pointer to a buffer with length one greater than the string length, and the usual C++ quirks like why is there both data and c_str?
The usual C++ response: for backwards compatibility, because data was not required to null-terminate prior to C++11.
I think one of the classic advantages of C++ over C is that you have the option of std::string instead of char arrays.
I don't program in C++ so I don't really know but I do a lot of pure C and the strings truly are a mess (despite being VERY straightforward)
“Modern, dependency-heavy environments” are a symptom of the fact that certain ecosystems make it easy to get addicted to dependencies; I don’t think they’re a goal to strive towards.
And not only for the libraries:
Similarly, Cargo in Rust is an absolute dream to work with, you just run `cargo new <project>` and then `cargo build`. That's it. If you want to add a dependency you can do so from the public crates.io repository or a sub-path or a git repository.
No language should be without this core feature, so it'd be great to see C++ get it too.
I already have a dependency management tool for C++; it is called the Ubuntu package repositories. I don’t need another one baked into the language.
BTW modules won't address this. I'm not sure you did but some other down thread comments implied that some people thought it would.
There is also C. The tooling and the "package manager for C++" would be expected to seamlessly work for C and be expected to be accepted and used by the C community.
(personally I use CMake + OS package manager)
The cmake language might not be beautiful, but it does allow for simple sub-projects/library scripts once the main cmake script is set up properly.
This is currently really easy to do cleanly though CMake by using Hunter and toolchain files (don't use submodules or addexternalproject)
External tools like Conan are also unnecessary bc they introduce redundancy and extra maintenance
My advice about build tooling is to use buck (from Facebook) or bazel (from Google). If you have an ex-Googler nearby, use Bazel. If you have an ex-Facebooker nearby, use buck. Otherwise flip a coin.
Buck and Bazel were created for complex internal dependencies.
You'll have just as easy/hard of a time getting Boost installed with Bazel as you would for Make.
Or publishing an accessible library that depends on Boost.
> Or publishing an accessible library that depends on Boost.
This is patently false. Here is the bazel dependency for boost (put this in your workspace file):
git_repository(
name = "com_github_nelhage_rules_boost",
commit = "6d6fd834281cb8f8e758dd9ad76df86304bf1869",
shallow_since = "1543903644 -0800",
remote = "https://github.com/nelhage/rules_boost",
)
load("@com_github_nelhage_rules_boost//:boost/boost.bzl", "boost_deps")
boost_deps()
No other installation necessary. If someone has a C++ compiler and Bazel installed that will allow you to build against Boost deps (e.g. "@boost//:callable_traits"). No downloading boost by hand, no building boost by hand, no managing it's build, bazel does all of that.Bazel does have a dependency ecosystem, it's based off of hashed versions of publicly available git repos and http archives (and anything else you want really). Which means any code anywhere can be a dependency while still being reproducible. Additionally you can provide local build instructions for the external code, so you don't even need to rely on their build. The better way is to find someone who maintains a BUILD file for a repo (or mirror and maintain it yourself) but still.
To beetwenty's point, the C++ ecosystem in general lacks the the level of support for dependency ecosystems that you find in Maven, pip, gem, npm, etc.
Bazel external dependencies are in fact a real pain point. See the 3+ year old Bazel Recursive WORKSPACE proposal. [1]
I was at the first Bazel Conf in 2017, and the external dependencies meeting was quite the row.
[1] https://bazel.build/designs/2016/09/19/recursive-ws-parsing....
Also as demonstrated Boost is way easier to include in bazel than make which was the original issue under discussion.
I make a library that depends on boost, here is how you use it:
git_repository(
name="foo"
...
)
load("@foo//:foo/foo.bzl", "foo_deps")
foo_deps()
magicSo, bringing such multiple third party bandaid is currently not such a great idea. It would be a bit better if boost itself provided it.
How is this different than most other build systems? You always have to rely on others.
I also use boost when the compiler is behind (e.g. boost::variant until apple's compiler caught up).
I can't wait to have a boost-free tree. but I suspect it will be a while.