4 ms·
> Thankfully, you don't need to reinvent the wheel, the problem of cross platform multiprocessing in C has been solved at least a dozen times by now. It should
by jcranmer 5y ago
> Thankfully, you don't need to reinvent the wheel, the problem of cross platform multiprocessing in C has been solved at least a dozen times by now. It should be trivial to use one of these many options (or even write your own, even if you don't like the idea of "reinventing the wheel" it's certainly not particularly difficult either and can likely be lighter than any other more general option).
This is basically the issue he's complaining about. The author wants to reuse a wheel, but reusing the wheel in C is difficult. What are your options?
* OpenMP: Great, now you get the fun of figuring out how to cross-platform(/compiler) enable openmp in your build system (that you have to maintain yourself because there is no standard build system. Of course, you could also go with cmake or autotools to maintain the build system for you, but now you have similar issues with meta-build system stuff. Yay platform diversity!)
* Okay, let's use another library instead. Now you just have to have the user tell you where it's located. And maybe have to provide lengthy instructions on how to find it. Or you can try having the build system automatically download it on the fly. There's a lot of potential error messages you have to deal with, just to get at what ought to be a core feature of any modern programming language.
* Maybe you might want to vendor that library in your source tree, just to be sure you always have it. Now you get the fun of having your build system invoke another build system as a subproject.
* Screw other dependencies, let's just use a newer C standard version, since it is in C11. How do you get your C compiler to compile for C11? Oh wait, that's basically the same world of pain as it is to try to use OpenMP.
> Hardly any more dreadful than rust's solution to the problem.
Contrast this with Rust's solution.
* Your build system is cargo and you specify things primarily with Cargo.toml. This is as little work as the happiest happy paths of C/C++ build systems. And note you don't really choose build system; there is one ecosystem-approved build system--for C/C++, you have at the very least hand-rolled makefiles, IDE solutions, cmake, and autotools as major candidates, and many major projects very happily choose "none of the above" (with all the pain that entails).
* If you want to add a dependency in cargo, you add a line in Cargo.toml. That's it; you're done. For the aforementioned C/C++ build systems, even the happiest happy paths aren't that happy.
This isn't to say that Rust's solution is perfect (it has a fair amount of warts), but to assert that Rust is no better than C is an indication to me that you've never really had to actually support the build system of a project before.
- Arch-TK 5y ago> that you have to maintain yourself because there is no standard build system. Since rust has no standard, how can it have a standard build system? That aside, the fact that C has no enforced/bundled/included/coupled build system is personally a major win over rust. Why would you want to be forced to do things the way cargo does it? Not everyone has the same requirements. It's also a serious misconception that cross-platform building in C is is difficult, it's not as long as simply consider it from the beginning and test it (and ignore microsoft compilers and environments since it just much easier to cross compile for windows or compile via some mingw environment). >Now you just have to have the user tell you where it's located. No? You use pkg-config with the fallback option of having the user use PKG_CONFIG_PATH to specify a custom location for .pc files. If the library sucks and doesn't support pkg-config, either pick a better library or add an option to fall back if -llibrary doesn't find it. Realistically users should be encouraged to use their system package manager rather than just installing libraries all over the place. I agree that this could be made smoother but at the end of the day, this has never really been an issue for projects. >There's a lot of potential error messages you have to deal with, just to get at what ought to be a core feature of any modern programming language. I highly disagree that programming languages should have anything to do with package management. Feel free to make a programming language, feel free to bundle with it a decoupled optional build system, and feel free to attach to that an optional and decoupled package manager (see python) but to bundle them all together is incredibly inflexible and discourages me from using that particular language. > Maybe you might want to vendor that library in your source tree, just to be sure you always have it. Unless this is a commercial proprietary internal project, you NEVER want this. > Now you get the fun of having your build system invoke another build system as a subproject. If you still DO want it, it's usually trivial to do this. Linux distributions usually publish files which automate building all packages, these files usually don't span thousands of lines. If archlinux can do this with some shell scripts then it's not that hard to do it from any build system. That being said, you DON'T want to do this, it's just the wrong way to think about the responsibilities. You document the versions of libraries that your project supports, optionally you document that your project uses pkg-config or whatnot as a way to specify unconventional locations for dependencies. The people compiling your code follow these basic instructions and they get your code built. It's actually really not that hard. > * Screw other dependencies, let's just use a newer C standard version, since it is in C11. How do you get your C compiler to compile for C11? Oh wait, that's basically the same world of pain as it is to try to use OpenMP. C11 optional supports a thread model which was never thought about. So it's not an option here. That being said, you are seriously misinformed if you think that compiling against a specific C standard version is particularly hard. It's nontrivial to get compilers to completely drop their own extensions, but as long as you make sure your code is compliant with a specific standard and explicitly make that clear to the compiler's you're invoking, it's really not difficult. Certainly not as difficult as making sure that the OpenMP version is correct. To be fair, given this completely incendiary article I would doubt that getting OpenMP to work is as hard as the article makes it sound, I've certainly never had these issues with it, but at the same time I don't have the time to look at the particular problems the project had so I will have to take it on faith that at least on that one particular point there might be an issue. > * Your build system is cargo and you specify things primarily with Cargo.toml. This is as little work as the happiest happy paths of C/C++ build systems. And note you don't really choose build system; there is one ecosystem-approved build system--for C/C++, you have at the very least hand-rolled makefiles, IDE solutions, cmake, and autotools as major candidates, and many major projects very happily choose "none of the above" (with all the pain that entails). I once again don't understand why you think having fewer choices is better. In my build system adding a new dependency is as easy as specifying the library and version number in one file. It can be like that if you want. The fact that C doesn't couple the build system to the language means that I can pick any tool I feel like being appropriate for a project and use it. It might be nice if there was some default build tool for C which could be used for the most basic projects, but I would be severely unhappy if it was as thoroughly coupled to package management and the language as cargo is. As it stands, rust is basically unusable without cargo, that doesn't really make me want to use it as a language. I also don't know of any projects which chose "none of the above". Unless you mean projects which use meson but I don't think you mean that since it just looks like you simply missed it off your list. > * If you want to add a dependency in cargo, you add a line in Cargo.toml. That's it; you're done. For the aforementioned C/C++ build systems, even the happiest happy paths aren't that happy. How do I depend on a specific C library from a cargo.toml? How do I declare a runtime dependency on grep or ps or whatever. How do I declare a compile-time dependency on python (because for example I want to run python to generate some code which gets built)? The fact that cargo.toml solves a tiny fraction of problems (at great cost) while ignoring the rest doesn't really make me particularly excited about it. In C I can pick or design a build system which suits the task at hand, if I need to depend on python, I can document it (specify it has to be in the PATH) and run it during the build. I can make this as flexible or inflexible as I need. I highly doubt that it's possible to pick any random possible executable and add in one line the information needed to document the dependency on that executable, use it in the right way and integrate that into the build process. cargo is inflexible, I agree that it's nice if your project is simple, the fact that it's so inherently tied to rust means that it's annoying at best if it is not adequate for the task at hand. >This isn't to say that Rust's solution is perfect (it has a fair amount of warts), but to assert that Rust is no better than C is an indication to me that you've never really had to actually support the build system of a project before. Rust's solution is adequate for a small subset of problems not completely overlapping with problems I like to solve. It is inadequate for what I want to do, aside from the number of other issues I have with rust, it's just not as flexible as what you can do with C. I have had to actually support the build system of a project before.