3 ms·
> Tasks are defined and run as if you were running them in the terminal; no more abstractions like BUILD files. But abstractions are a good thing! They let yo
by haberman 4y ago
> Tasks are defined and run as if you were running them in the terminal; no more abstractions like BUILD files.
But abstractions are a good thing! They let you separate a system into layers, so that things programmed at a higher layer don't need to know all the details of the lower layers. It's the way we separate interface from implementation.
Let me give an example from Bazel. Suppose you are compiling some C or C++, and you need to define a preprocessor symbol. There are two ways of doing this, "defines" and "local_defines":
cc_library(
name = "my_lib",
srcs = ["my_lib.cc"],
hdrs = ["my_lib.h"],
# This will pass -DFOO when compiling this library
# *or* any library that depends on it.
defines = ["FOO"],
)
cc_library(
name = "my_lib",
srcs = ["my_lib.cc"],
hdrs = ["my_lib.h"],
# This will pass -DFOO when compiling this library
# only. Libraries that depend on us will *not* get
# the symbol.
local_defines = ["FOO"],
)
You can use "defines" when you have #ifdef statements in headers and "local_defines" when you only test the symbols in your .cc files.
I did not have to think about how defines will propagate to the libraries that depend on me, I just specified what I need and the build system handles the rest. I did not have to define my own CXXFLAGS variable and handle concatenating all of the right things together. The lower layer takes care of that.
What Bazel lets you do is create abstraction boundaries within the build system. People can write rules that define a self-contained set of build logic, then other people can use those abstractions without knowing all the details of how they are implemented.
Bazel is not perfect, and I have found myself banging my head against the wall many times. But overall the ability to define abstractions in a build system is, I think, one of the biggest things it gets right.
Disclosure: I work for Google, but not on Bazel.
- theamk 4y agoLook at https://moonrepo.dev/docs#supported-languages https://moonrepo.dev/docs#supported-languages They only fully support Javascript. The complex stuff, like defines, C++ toolchain, dynamic libs, etc.. is all out of scope.
- eisbaw 4y agoWow true. Claiming to be a build system yet being limited to JS... Apparently, the legions of JS developers think the web is the only thing that exists today.
- onion2k 4y agoApparently, the legions of JS developers think the web is the only thing that exists today. That's very unfair to JS devs. We're well aware that other things exist... ...because we're trying to replace them all with JS.
- pastacacioepepe 4y ago> the legions of JS developers think the web is the only thing that exists today. As if all JS developers can be grouped into a single entity with the same thoughts. This sounds a bit like saying "the legions of Makita Tools carpenters think" or "the legions of Volvo truck drivers think".
- mileswjohnson 4y agoWe'll get there eventually! Adding support for other languages in Rust is a very long process.
- jcalder 4y agoAlso, MIGRATIONS! Interfaces are VERY GOOD for migrations. If you decide that you want to stop using some compiler flag, or maybe use a different compiler, or change your python version, or... You can right a regex to go over all your shell invocations, change them, then test, or you can do something like: ``` def build_thing(name, srcs, hdrs, migration=False): if migration: ... build_thing( name = "my_lib", srcs = ["my_lib.cc"], hdrs = ["my_lib.h"], ) ``` You can then manually flip that to test stuff, write a script to flip it for every team, sending out a PR (because your targets can have oncalls) and they can land it, and then at the end you can flip the default and manually add a False to the holdouts. All this stuff gives you the ability to do hard stuff at scale.
- Aeolun 4y agoMaybe that’s more relevant for the non-js ecosystem? I never find myself wanting to modify my source while it is being built.
- underdeserver 4y agoIf I understand this correctly - This means that #ifdef FOO will be evaluate to true _inside the .cc and .h files listed in srcs_, when building this target or dependent targets, but might be something else when downstream targets' object files (.o) are built.