|
|
|
|
|
by klodolph
1092 days ago
|
|
What advantages does this system provide? Could you give a motivating example? Bazel’s BUILD.bazel scripts are restricted, but that part is the middle of a “sandwich” which handles the 90% use cases. If you want unfettered execution, you get that in the repository rule phase and the actual build actions (the two slices of bread in our sandwich). This allows you to define build rules dynamically (as long as you can do it before the main part of the build runs) and allows you to run arbitrary code in your build actions (as long as you specify a superset of the inputs and output, and your outputs are disjoint). |
|
To be frank, Bazel is the build system that comes closest. The biggest selling point of mine against Bazel would be usability (I hope). So really, I would suggest people stay on Bazel if they already are.
(In fact, I would suggest that CMake users stay on CMake. I only want to capture new projects to start. If my build system then proves itself, people who need to will switch by themselves.)
About dynamic capabilities, that's not quite what I mean by defining build rules dynamically. Your qualification ("as long as you can do it before the main part of the build runs") throws out everything I meant. In addition, CMake can do that too.
However, it does sound like Bazel can otherwise run arbitrary code in build actions. Those restrictions you mention are fundamental to sandboxed build systems, so I don't include those.
Yes, my build system will be able to be hermetic and do sandboxing. It will do it in two ways, one of which will be like Bazel. The other will be a sandbox in the interpreter itself.
These will be per build rule and global. There will be no downloading stuff from the Internet if you don't allow it, and build rules will only be able to use outside commands that you allow. (For example, you could allow only the C compiler for a C project.) The sandbox could be even tighter and will be runtime-based: actions could be rejected at runtime based on runtime values.
So if there's a smaller selling point, I hope it would be better protection against malicious build scripts.
A motivating example: headers in C and C++.
What headers a file may use can depend on the build configuration (through preprocessor defines and such).
Yes, you can make a rule to run the preprocessor on the file, then make a separate rule to run the compiler on the preprocessed file. But there is no way to make the preprocessed file depend on the headers because its dependencies must be defined before the build and the list of included files is generated during the build.
"Okay, but why can't you just generate the list of files on an initial build and just use that in later builds?"
You can, and that is what DJB's redo does. But say that you change a file a header A included by a header B included by a file C. C knows it depends on B. It may know that it actually depends on header A too, but if it doesn't, it won't get rebuilt.
Motivating example 2: say you have a language with packages, like Python, except that it's compiled.
You have the main program that imports packages. It can dynamically generate targets for imported packages and dynamically depend on them. And do this recursively.
You are hard at work doing development. You already have done several builds. You change one file to import a new package you just created. Do you need to change the build file or do a clean build? Nope. The task recognizes the new dependency, suspends itself to build the new package, and then resumes. You are none the wiser.
Even better, your dependency information is contained in the actual source, not your build system. There is no duplication. And it "just works."