Hacker News new | ask | show | jobs
by wilburm 1245 days ago
One big lesson that newer languages like go and rust seemed to have learned is that the tooling, building and dependency management need to be dictated as part of the language ecosystem. Dealing with tons of other C++ projects written by other people (even in the same company) - how to specify dependencies, where their build artifacts can be found, etc - is a HUGE pain in the ass and consumer of my time.
2 comments

They all get the tooling wrong though because none can stand the idea that you might want to mix languages, or add their new language to an existing project with existing tooling.
For Go, mixing languages is uncommon because its FFI suffers an impedance mismatch with its task scheduler. For Rust, mixing languages is extremely common. Rust's entire original reason for existing was to rewrite small parts of a large C++ project.
So much common that Google had to create their own integrations for Android and Fuchsia.

I bet the announced Chrome efforts will again, require another adaptation.

I'm unsure what this is trying to say. You appear to be in begrudging agreement that Rust is commonly mixed with other languages?
He's saying that Cargo doesn't really help at all with that mixing. Integrating Rust into a multi-language build system is indeed quite a pain. You have a few bad options:

* Drive everything with Cargo using `build.rs`. This sort of works but it's pretty horrible.

* Give up and just have your main build system run `cargo build`. This is what I normally do but again it's not ideal because it doesn't really integrate properly with your main build system.

* Give up on Cargo entirely. This is what Bazel does, and it's probably the most robust solution but it's still not ideal because most of the Rust ecosystem expects you to use Cargo (e.g. rust-analyzer).

I don't think any other languages have really solved this problem either but it is still an annoying problem.

> I don't think any other languages have really solved this problem either but it is still an annoying problem.

As you say, this is not a problem with an ideal solution to draw upon. (languages are unavoidably different). From that perspective, I don't see any of these approaches as problems.

If your project is mostly Rust with a little something else sprinkled in, use build.rs ("horrible" is an exaggeration IMO, it's merely not ideal, again, because there exists no ideal).

If your project is mostly something-else with a little Rust sprinkled in, invoke `cargo build` from your build system, and again this is a perfectly adequate solution to a problem with no ideal solutions.

If your project is extra-special, invoke rustc directly, and that's a deliberately supported use case. Hell, I use rustc directly sometimes just because I can.

The bottom line is, Rust provides a best-in-class opinionated build system that is overwhelmingly used by the Rust ecosystem, with best-effort escape hatches for integrating into other projects. To say that Rust cannot "stand the idea that you might want to mix languages", as alleged by the person I originally replied to, is factually incorrect.

That cargo is not enough, and polyglot codebases either use something else, or have quite extensive uses of build.rs.
No, most polyglot codebases use Cargo. For something massive like Android that has gone so far as to implement its own build system, no third-party build system would be sufficient, so focusing on Cargo is irrelevant. The fact is, Cargo has always been deliberately and consciously designed to be merely an abstraction over rustc, specifically in order to accommodate opinionated users who would be better served by invoking rustc directly. They're following exactly the workflow that the Rust developers intended, because this saves the Cargo developers from having to perfectly anticipate every potential user's needs, which would be impossible. Rust does the right thing here.
Java, JavaScript, and Ruby didn't do this, and yet they all have solid build and dependency management stories. Java and JavaScript have even managed to have multiple build and dependency management tools existing at once without there being fragmentation and ruin. So clearly, having those tools dictated by the language is not essential.

I'm not sure why C and C++ have such a bad story here. Some combination of greater intrinsic complexity (separate headers, underspecified source-object relationships, architecture dependency, zillions of build flags, etc), a longer history of idiosyncratic libraries which people still need to use, the oppressive presence of distro package managers, and C programmers just being gluttons for punishment, probably.