8 ms·
Consider that to do this you must: - Use a build system like make, you can't just `c++ build` - Understand that C++ compilers by default have no idea where mo
by duped 1y ago
Consider that to do this you must:
- Use a build system like make, you can't just `c++ build`
- Understand that C++ compilers by default have no idea where most things are, you have to tell them exactly where to search
- Use an external tool that's not your build system or compiler to actually inform the compiler what those search paths are
- Oh also understand the compiler doesn't actually output what you want, you also need a linker
- That linker also doesn't know where to find things, so you need the external tool to use it
- Oh and you still have to use a package manager to install those dependencies to work with pkg-config, and it will install them globally. If you want to use it in different projects you better hope you're ok with them all sharing the same version.
Now you can see why things like IDEs became default tools for teaching students how to write C and C++, because there's no "open a text editor and then `c++ build file.cpp` to get output" for anything except hello world examples.
- palata 1y agoI can use pkg-config just fine. Not sure how relevant the "in order to use a tool, you need to learn how to use the tool". Or from the other side: not sure what I should think about the quality of the work produced by people who don't want to learn relatively basic skills... it does not take two PhDs to understand how to use pkg-config.
- duped 1y agoI'm just pointing out that one reason devex sucks in C++ is because the fact you need a wide array of tools, that are non portable, and require learning and teaching magic incantations at the command line or in build scripts to work, doesn't foster what one could call a "good" experience. Frankly the idea that your compiler driver should not be a basic build system, package manager, and linker is an idea best left in the 80s where it belongs.
- bluGill 1y agothat idea that packages and builds belongs to simple problem, large projects need things like more than one laguage and so end up fighting the language
- duped 1y agoEvery modern language seems to have an answer to this problem that C and C++ refuse to touch because it's out of scope for their respective committees and standards orgs
- pclmulqdq 1y agoC++ has a plethora of available build and package management systems. They just aren't bundled with the compiler. IMO that is a good thing, because it keeps the compiler writers honest.
- jimbob45 1y agoYou say that as if Cargo, MSBuild, and pip aren’t massively loved by their communities.
- pclmulqdq 1y ago"Massively loved" and "good decision" are orthogonal axes. See the current npm drama. People love wantonly importing dependencies the way they love drinking. Both feel great but neither is good for you.
- asa400 1y agoNot that npm-style package management is the best we can do or anything, but I would be more sympathetic to this argument if C or C++ had a clearly better security story than JS, Python, etc. (pick your poison), but they're also disasters in this area. What happens in practice is people end up writing their own insecure code instead of using someone else's insecure code. Of course, we can debate the tradeoffs of one or the other!
- bluGill 1y agoThis isn't only about security. This is about interoperability, in the real world we mix (and should mix!) C, C++, Rust, python.... In the real world lawyers audit every dependency to ensure they can legally use it. In the real world we are responsible for our dependencies and so need to audit the code.
- jchw 1y agoI'm not going to defend the fact that the C++ devex sucks. There are really a lot of reasons for it, some of which can't sensibly be blamed on the language and some of which absolutely can be. (Most of it probably just comes down to the language and tooling being really old and not having changed in some specific fundamental ways.) However, it's definitely wrong to say that the typical tools are "non-portable". The UNIX-style C++ toolchains work basically anywhere, including Windows, although I admit some of the tools require MSys/Cygwin. You can definitely use GNU Makefiles with pkg-config using MSys2 and have a fine experience. Needless to say, this also works on Linux, macOS, FreeBSD, Solaris, etc. More modern tooling like CMake and Ninja work perfectly fine on Windows and don't need any special environment like Cygwin or MSys, can use your MSVC installation just fine. I don't really think applying the mantra of Rust package management and build processes to C++ is a good idea. C++'s toolchain is amenable to many things that Rust and Cargo aren't. Instead, it'd be better to talk about why C++ sucks to use, and then try to figure out what steps could be taken to make it suck less. Like: - Building C++ software is hard. There's no canonical build system, and many build systems are arcane. This one really might be a tough nut to crack. The issue is that creating yet another system is bound to just cause xkcd 927. As it is, there are many popular ways to build, including GNU Make, GNU Autotools + Make, Meson, CMake, Visual Studio Solutions, etc. CMake is the most obvious winner right now. It has achieved defacto standard support. It works on basically any operating system, and IDEs like CLion and Visual Studio 2022 have robust support for CMake projects. Most importantly, building with CMake couldn't be much simpler. It looks like this: $ cmake -B .build -S . ... $ cmake --build .build ... And you have a build in .build. I think this is acceptable. (A one-step build would be simpler, but this is definitely more flexible, I think it is very passable.) This does require learning CMake, and CMake lists files are definitely a bit ugly and sometimes confusing. Still, they are pretty practical, and rather easy to get started with, so I think it's a clear win. CMake is the "defacto" way to go here. - Managing dependencies in C++ is hard. Sometimes you want external dependencies, sometimes you want vendored dependencies. This problem's even worse. CMake helps a little here, because it has really robust mechanisms for finding external dependencies. However, while robust, the mechanism is definitely a bit arcane; it has two modes, the legacy Find scripts mode, and the newer Config mode, and some things like version constraints can have strange and surprising behavior (it differs on a lot of factors!) But sometimes you don't want to use external dependencies, like on Windows, where it just doesn't make sense. What can do you really do here? I think the most obvious thing to do is use vcpkg. As the name implies, it's Microsoft's solution to source-level dependencies. Using vcpkg with Visual Studio and CMake is relatively easy, and it can be configured with a couple of JSON files (and there is a simple CLI that you can use to add/remove dependencies, etc.) When you configure your CMake build, your dependencies will be fetched and built appropriately for your targets, and then CMake's find package mechanism can be used just as it is used for external dependencies. CMake itself is also capable of vendoring projects within itself, and it's absolutely possible to support all three modalities of manual vendoring, vcpkg, and external dependencies. However, for obvious reasons this is generally not advisable. It's really complicated to write CMake scripts that actually work properly in every possible case, and many cases need to be prevented because they won't actually work. All of that considered, I think the best existing solution here is CMake + vcpkg. When using external dependencies is desired, simply not using vcpkg is sufficient and the external dependencies will be picked up as long as they are installed. This gives an experience much closer to what you'd expect from a modern toolchain, but without limiting you from using external dependencies which is often unavoidable in C++ (especially on Linux.) - Cross-compiling with C++ is hard. In my opinion this is mostly not solved by the "defacto" toolchains. :) It absolutely is possible to solve this. Clang is already better off than most of the other C++ toolchains in that it can handle cross-compiling with selecting cross-compile targets at runtime rather than build time. This avoids the issue in GCC where you need a toolchain built for each target triplet you wish to target, but you still run into the issue of needing libc/etc. for each target. Both CMake and vcpkg technically do support cross-compilation to some extent, but I think it rarely works without some hacking around in practice, in contrast to something like Go. If cross-compiling is a priority, the Zig toolchain offers a solution for C/C++ projects that includes both effortless cross-compiling as well as an easy to use build command. It is probably the closest to solving every (toolchain) problem C++ has, at least in theory. However, I think it doesn't really offer much for C/C++ dependencies yet. There were plans to integrate vcpkg for this I think, but I don't know where they went. If Zig integrates vcpkg deeply, I think it would become the obvious choice for modern C++ projects. I get that by not having a "standard" solution, C++ remains somewhat of a nightmare for people to get started in, and I've generally been doing very little C++ lately because of this. However I've found that there is actually a reasonable happy path in modern C++ development, and I'd definitely recommend beginners to go down that path if they want to use C++.
- menaerus 1y agoFor most people this is a feature not a bug as you suggest. It may come across as PITA, and for many people will do, but as far as I am concerned, while also having experienced the pain of package managers in C++, this is the right way. In the end it's always about the trade-offs. And all the (large) codebases that used conan, bazel or vcpkg induced a magnitude more issues that you would have to handle which otherwise in a plain CMake you would not have. Package managers are for convenience but not all projects can afford themselves the trouble this convenience brings with it.
- palata 1y ago> For most people this is a feature not a bug as you suggest. Exactly: it makes many things nicer to use than the language package managers, e.g. when maintaining a Linux distribution. But people generally don't know how one maintains a Linux distribution, so they can't really see the use-case, I guess.
- soanvig 1y agoComing from a different ground (TypeScript) I agree, in a sense that there is a line where apparent convenience because a trouble. JS ecosystem is known for its hype for build tools. Long term all of them become a problem due to trying to be more convenient, leading to more and more abstractions and hidden behaviors, which turns into a mess impossible to debug or solve when user diverges from author's happy path. Thus I promote using only the necessities, and gluing them together by yourself. Even if something doesn't work, at least it can be tracked down and solved.
- palata 1y ago> require learning and teaching magic incantations at the command line That's exactly my point: if you think that calling `cmake --build build` is "magic", then maybe you don't have the right profile to use C++ in the first place, because you will have to learn some harder concepts there (like... pointers). To be honest, I find it hard to understand how a software developer can write code and still consider that command line instructions are "magic incantations". To me it's like saying that calling a function like `println("Some text, {}, {}", some_parameter, some_other_parameter)` is a "magic incantation". Calling a function with parameters counts as "the basics" to me.
- benreesman 1y agoclang++ $(pkg-config --cflags --libs libtorch) qwen-3-nvfp4.cpp -o ./qwen-3-infer Your move.
- deleted 1y ago[deleted]
- worik 1y agoNone of that is a problem There are a lot of problems, but having to carefully construct the build environment is a minor one time hassle. Then repeated foot guns going off, no toes left, company bankrupt and banking system crashed, again
- vlovich123 1y ago> There are a lot of problems, but having to carefully construct the build environment is a minor one time hassle. I've observed the existence in larger projects of "build engineers" whose sole job is to keep the project building on a regular cadence. These jobs predominantly seem to exist in C++ land.
- wojciii 1y agoHow is that even possible? Wasn't CI invented to solve just this problem?
- vlovich123 1y agoYou have a team of 20 engineers on a project you want to maintain velocity on. With that many coooks, you have patches on top of patches of your build system where everyone does the bare minimum to meet the near term task only and it devolves into a mess no one wants to touch over enough time. Your choice: do you have the most senior engineers spend time sporadically maintaining the build system, perhaps declaring fires to try to pay off tech debt, or hire someone full time, perhaps cheaper and with better expertise, dedicated to the task instead? CI is an orthogonal problem but that too requires maintenance - do you maintain it ad-hoc or make it the official responsibility for someone to keep maintained and flexible for the team’s needs? I think you think I’m saying the task is keeping the build green whereas I’m saying someone has to keep the system that’s keeping the build green going and functional.
- AdieuToLogic 1y ago> You have a team of 20 engineers on a project you want to maintain velocity on. With that many coooks, you have patches on top of patches of your build system ... The scenario you are describing does not make sense for the commonly accepted industry definition of "build system." It would make sense if, instead, the description was "application", "product", or "system." Many software engineers use and interpret the phrase "build system" to be something akin to make[0] or similar solution used to produce executable artifacts from source code assets. 0 - https://man.freebsd.org/cgi/man.cgi?query=make&apropos=0&sektion=0&manpath=FreeBSD+14.3-RELEASE+and+Ports&arch=default&format=html https://man.freebsd.org/cgi/man.cgi?query=make&apropos=0&sek...
- jlarocco 1y agoIt's really not that big of a deal once you know how it works, and there are tools like CMake and IDEs that will take care of it. On Windows and OSX it's even easier - if you're okay writing only for those platforms. It's more difficult to learn, and it seems convoluted for people coming from Python and Javascript, but there are a lot of advantages to not having package management and build tooling tightly integrated with the language or compiler, too.
- imtringued 1y agoI used to write a lot of C++ in 2017. Now in 2025 I have no memory of how to do that anymore. It's bespoke Makefile nonsense with zero hope of standardization. It's definitively something that doesn't grow with experience. Meanwhile my gradle setups have been almost unchanged since that time if it wasn't for the stupid backwards incompatible gradle releases.
- gpderetta 1y ago> It's bespoke Makefile nonsense with zero hope of standardization technically Makefile is standardized (by POSIX), contrary to most alternatives. /extremely pedantic
- pjmlp 1y agoI would rather deal with Makefiles than Gradle.
- saghm 1y agoI think we can afford to strive for more than just "not quite the absolute worst" (for however we decide to measure quality).
- einpoklum 1y ago> I used to write a lot of C++ in 2017... It's bespoke Makefile nonsense 1. Makefiles are for build systems; they are not C++. 2. Even for building C++ - in 2017, there was no need to write bespoke Makefiles, or any Makefiles. You could, and should, have written CMake; and your CMake files would be usable and relevant today. > Meanwhile my gradle setups have been almost unchanged since that time ... but, typically, with far narrower applicability.
- account42 1y ago> Use a build system like make, you can't just `c++ build` This is a strength not a weakness because it allows you to choose your build system independently of the language. It also means that you get build systems that can support compiling complex projects using multiple programming languages. > Understand that C++ compilers by default have no idea where most things are, you have to tell them exactly where to search This is a strength not a weakness because it allows you to organize your dependencies and their locations on your computer however you want and are not bound by whatever your language designer wants. > Use an external tool that's not your build system or compiler to actually inform the compiler what those search paths are This is a strength not a weakness because you are not bound to a particular way of how this should work. > Oh also understand the compiler doesn't actually output what you want, you also need a linker This is a strength not a weakness because now you can link together parts written in different programming languages which allows you to reuse good code instead of reinventing the universe. > That linker also doesn't know where to find things, so you need the external tool to use it This is a strength not a weakness for the reasons already mentioned above. > Oh and you still have to use a package manager to install those dependencies to work with pkg-config, and it will install them globally. If you want to use it in different projects you better hope you're ok with them all sharing the same version. This is a strength not a weakness because you can have fully offline builds including ways to distribute dependencies to air-gapped systems and are not reliant on one specific online service to do your job. Also all of this is a non-issue if you use a half-modern build system. Conflating the language, compiler, build system and package manager is one of the main reason why I stay away from "modern" programming languages. You are basically arguing against the Unix philosophy of having different tools that work together with each tool focusing on one specific task. This allows different tools to evolve independently and for alternatives to exist rather than a single tool that has to fit everyone.
- juliangmp 1y ago> This is a strength not a weakness Massive cope, there's no excuse for the lack of decent infrastructure. I mean, the C++ committee for years said explicitly that they don't care about infrastructure and build systems, so it's not really surprising.
- jandrese 1y agoYou also don't do "rustc build". Cargo is a build system too. The whole point of pkg-config is to tell the compiler where those packages are. I mean yeah, that's the point of having a tool like that. It's fine that the compiler doesn't know that, because its job is turning source into executables, not being the OS glue. I'm not sure "having a linker" is a weakness? What are talking about? It is true that you need to use the package manager to install the dependencies. This is more effort than having a package manager download them for you automatically, but on the other hand you don't end up in a situation where you need virtual environments for every application because they've all downloaded slightly different versions of the same packages. It's a bit of a philosophical argument as to what is the better solution. The argument that it is too hard for students seems a bit overblown. The instructions for getting this up and running are: 1. apt install build-essential 2. extract the example files (Makefile and c file), cd into the directory 3. type "make" 4. run your program with ./programname I'd argue that is fewer steps than setting up almost any IDE. The Makefile is 6 lines and is easy to adapt to any similar size project. The only major weakness is headers, in which case you can do something like: HEADERS=headerA.h headerB.h headerC.h file1.o: $(HEADERS) file2.o: $(HEADERS) file3.o: $(HEADERS) If you change any header it will trigger a full system rebuild, but on C projects this is fine for a long time. It's just annoying that you have to create a new entry for every c file you add to the project instead of being able to tell make to add that to every object automatically. I suspect there is a very arcane way to do this, but I try to keep it as simple as possible.
- steveklabnik 1y agoI'm not your parent, but the overall point of this kind of thing is that all of these individual steps are more annoying and error-prone than one command that just takes care of it. `cargo build` is all you need to build the vast majority of Rust projects. No need to edit the Makefile for those headers, or remember which commands you need to install the various dependencies, and name them individually, figuring out which name maps to your distro's naming scheme, etc. It's not just "one command vs five" it's "one command for every project vs five commands that differ slightly per project and per platform". `make` can come close to this, and it's why people love `./configure; make`, and there's no inherent reason why this couldn't paper over some more differences to make it near universal, but that still only gets you Unix platforms. > but on the other hand you don't end up in a situation where you need virtual environments for every application because they've all downloaded slightly different versions of the same packages. The real downside here is that if you need two different programs with two different versions of packages, you're stuck. This is often mitigated by things like foo vs foo2, but I have been in a situation where two projects both rely on different versions of foo2, and cannot be unified. The per-project dependency strategy handles this with ease, the global strategy cannot.
- 1718627440 1y ago> Understand that C++ compilers by default have no idea where most things are C, C++ compilers by default expect libraries to be installed in the correct place, which would mean that you don't need to specify flags at all. Also nothing stops you from writing: #include </home/john/../../opt/my/stupid/path/last-project/final/finalv2/work/symlink-somewhere-else/foo/quick-test/school/c-tutorial/v9/1-introduction/header-file.h>