Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Speaking of Bazel, I wanted to try it out for a Java project, but it felt a bit more complex than expected.

Would you recommend using it even for mono languages projects?



Bazel is probably at its simplest in a monolingual codebase. Toolchains have a lot of complexity.

It's like that Churchill quote about democracy: Bazel is the worst build system except for all those others.


Used bazel for years, now using pants[0] and really enjoying it as a tool that is good in the same ways, but better in some smaller ways.

0: https://www.pantsbuild.org/


While maven and gradle may lack the architectural purity of bazel, they work much in the same way.

Plan and execute steps, building a graph of the required build tasks, only executing the tasks that have changed inputs.

With that said, it's quite common to see maven/gradle builds that are misconfigured and execute tasks unnecessarily.


I would use choose it for a C++ only project, but that’s because the alternatives are so horrible.


Why not Gradle or Maven?


If you haven't already committed, consider Nix instead.


I'm still trying to understand why people recommend Nix in place of a build system. Nixpkgs stdlib by default expects an autotools project. It will happily integrate with other build systems, as long as you've spelled out your dependencies in both. I've yet to see it generate a Makefile or make any decisions about compilition that weren't spelled out in a "traditional" build system. Could you shed some light on what I've missed?


So.. it's sort of a battle over territory between build system and package manager.

Bazel is there becoming ever more complex and unwieldy in an attempt to provide supposed reproducibility - taking control of the provision of ever more of a project's dependencies (in often very janky ways). But to Nix people it's clear that what people are actually doing here is slowly building a linux/software distribution around their project, but in a very ad-hoc and unmaintainable way. And bazel projects will continue to grow in that direction because until you have control of the whole dependency stack (down to the kernel), you're going to struggle to get robust reproducibility.

I don't think many Nix people would suggest actually using Nix as the build system, but probably to use a comparatively simple cmake/meson/whatever build-system and use Nix to provide dependencies for it in a reproducible and manageable way.


You call blaze side janky and ad-hoc but to me (as complete outsider) using monorepo+build tool seems more principled and working more with fundamentals, while nix feels more ad-hoc and trying to fix stuff post-facto.

> And bazel projects will continue to grow in that direction because until you have control of the whole dependency stack (down to the kernel), you're going to struggle to get robust reproducibility.

This is bit weird statement, considering that it's not where bazel is growing to, but where bazel is growing from. The whole starting point for bazel is having full control (via monorepo) of the dependency stack


> You call blaze side janky and ad-hoc but to me (as complete outsider) using monorepo+build tool seems more principled and working more with fundamentals, while nix feels more ad-hoc and trying to fix stuff post-facto.

The Nix side is a maintained software distribution, which is a lot more than a bunch of random versions of tarballs pulled down from random urls, wrapped in minimal build scripts and forgotten about for years on end. It's also work that is shared across packages in the distribution and it produces consistent results that don't have dependency conflicts - if you have two bazel projects that each build against their own cpython, I can guarantee that they will have chosen different versions of cpython. Which one wins when they're used together? Who knows...

Every project building-out their own separate pseudo-linux-distribution cannot produce good results.

> The whole starting point for bazel is having full control (via monorepo) of the dependency stack

I'm not aware of a bazel project that builds its own glibc (I imagine there are some which people could point out...). But then.. do they ship that glibc with the end result? Or just shrug and hope it works fine on whatever glibc the target system happens to have?


I haven't worked at google, but my understanding is that their monorepo does contain everything, including kernel and libc etc. So it's not bunch of random tarballs, its complete in-house maintained source tree.

> But then.. do they ship that glibc with the end result? Or just shrug and hope it works fine on whatever glibc the target system happens to have?

That's the whole point of monorepo, you don't have some random target systems, it's all included in the same repository.


Thanks for the summary. I've been using Meson + Nix, so the comments about using Nix as a build system have been confusing. I think what I've been seeing though are "use Nix instead of Bazel", not "use Nix as your build system".


What I mean is use a relatively simple build system instead of Bazel, and deal with dependencies and reproducibility through a Nix development environment.


You lose out on some of the incremental compilation speed that Bazel offers doing this. I think many in the Bazel space suggest using Bazel inside of a Nix environment.


I'm not sure why you'd want to generate a Makefile if you're using nix. Unlike make, nix understands the inputs to a build step and won't bother rerunning it unless their inputs have changed. You would lose that you generated a Makefile instead of having nix build whatever it is that the Makefile builds.

Otherwise it does the same things as make: this bunch of commands depends on this other bunch of commands... It just makes you express that as a function so it can be smarter about memoization.

I've not used it for large complex builds, so maybe there's some itch it fails to scratch at finer granularity which I'm overlooking. I liked this artical about where it shines and where it fails to be a build system: https://www.tweag.io/blog/2018-03-15-bazel-nix/. I've been waiting for the problem to arise that encourages me to learn Bazel so I can use it alongside nix, and it just hasn't yet.


> I'm still trying to understand why people recommend Nix in place of a build system.

Probably because Nix is a build system. After using it for a decade, I dislike that it describes itself as a "purely functional package manager"; that causes all sorts of confusion, since it has far more in common with something like Make (e.g. see my "Nix from the bottom up" page http://www.chriswarbo.net/projects/nixos/bottom_up.html )

> Nixpkgs stdlib by default expects an autotools project

Ah, I see the confusion. Nixpkgs is not Nix; they are different things!

Nix is a build tool, similar to Make. It has some differences, like caching results using their hash instead of timestamp, but the main advantage is that its build receipes are composable (thanks to the FP nature of their definitions).

For example, say I run `make` in some project repo, like Firefox. Make will read that project's Makefile, which contains elaborate rules for how the various build products depend on each other. Yet despite all that care and attention, I get an error: `cc: command not found`. Oops, I don't have a C compiler! So I grab a copy of the GCC source, and what do I find inside? Another Makefile! The `cc` command required by the Firefox Make rules is itself defined with Make rules; but the Firefox Makefile can't refer to them, since Make is not composable.

In contrast, Nix is composable: Nix definitions can `import` other files, including from build outputs! For example, we can write a build receipe which imports its definition from a build output; where that build fetches a git commit; and the definitions inside import things from some other builds; and those download and extract a bunch of .tar.gz files; and so on.

Nixpkgs is the most obvious example of this composability, with mountains of build receipes, built up from a relatively small "bootstrap" (pre-built binaries for a few basic tools, like parts of GNU). It's also a testament to backwards-compatibility, since it features build receipes (and helper functions) which act as wrappers around all sorts of legacy tools like Make, PIP, NPM, Cargo, Cabal, etc. (if you're working on a project that's stuck on such things).

Whilst Nixpkgs provides support for all of these things; Nix itself is only capable of invoking a single `exec` syscall (see "Nix from the bottom up"). Everything else is built up on that foundation, and isn't tied to any particular tool, language, framework, etc.

Hence it's not so much that Nix is a "package manager", or "orchestration" tool, or "configuration manager", etc. It's more like: those categories of tools are workarounds for crappy, non-composable build tools like Make. Nix is a composable build tool, so all of those other things turn out to be unnecessary.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: