On 01.12.2017 15:42, Hans Dembinski wrote:
On 30. Nov 2017, at 14:38, Stefan Seefeld
wrote: Ah, well, now that's a fundamental limitation of Python. […] Ok, if you use a standard Python interpreter, then it wouldn't work... except perhaps with really evil hacks.
Exactly. And while I do use a few tricks (yes, Python also provides its bag of meta-programming tricks ! ;-) ), I very deliberately limited the number of tricks I use. (One trick you may appreciate is the use of "virtual actions", allowing you to use the abstract "cxx.compile" in a fabscript, but then override that with e.g. "gxx.compile" by invoking `faber cxx.name=gxx`. Enabling that required a bit of magic (I use metaclasses for both actions as well as tools to do that), but I thought that in this particular instance it's well worth it.
I was actually thinking of ways to merge the two (the name of the variable, and the intrinsic names of the library and binary artefacts) to avoid that perceived redundancy, but got in all kinds of additional complexities trying that. The main point being that I really want to take advantage of this being written in a well established language, and using its idioms. SCons is a very good (or bad, actually) example of what happens if you technically use an established language without paying tribute to its idioms and established practices. I don't want to repeat that error. You are right, of course. I am glad to hear that you thought about it. I don't have any other ideas right now.
To make the syntax very consistent (the Zen of Python says: "There should be one - preferably only one - obvious way to do it."), you could define all build items like library and binary in this way:
def binary(*inputs, attribute1=default1, attribute2=default2, …): ...
All positional arguments would always be inputs of any kind, like a source file or a library. If you always use positional arguments consistently like this, then my complaint about ambiguity is gone, because there is a clear rule which is easy to remember. Perhaps you should think this through for a while longer (the way I have thought about it for months :-) ). I believe you will come to a very similar conclusion as I have. Well, I am not an expert on how to design a build system, since I have never done that. This sounds a bit like you don't want to explain and discuss this further.
Actually, I'd be happy to. But a) there may be better places than the main Boost ML to do that and b) I'm really looking forward to a review of the workflow as a whole, the functionality, etc., rather than getting stuck in questions about whether "artefact" is a useful term, or whether "$(<)" is a good way to refer to the target of an action.
That's fine with me, but it would be a pity. I am sure everything makes sense to you, but as the creator you will invariably get "betriebsblind", it happens to everyone. A review is a chance to get a fresh new perspective.
I totally agree, and I very much appreciate people taking the time to review Faber and provide feedback.
I know next to nothing about b2 and bjam, but I do understand Makefiles, I played with SCons for a while, and I am pretty fluent in CMake. I am very fluent in Python and I love the Zen of Python, which every programmer should put up in their office IMHO. I am also not above admitting, that I am but a simple guy who just wants to have a consistent build system that makes sense, is fun to use, and easy to extend. CMake mostly fails in the latter regard IMHO.
Perhaps more importantly, CMake becomes more ugly with every version, as they try to cram in more and more features without really re-designing the whole thing (reminds me of C++). If this trend continues and eventually enough people get annoyed with CMake, then there would be a market for a new build system. A niche that Faber could potentially fill (although I believe this is hard for any competitor, as explained a few mails back).
Concerning the different perspective; like Richard, I don't understand why you despise that CMake is a build system generator rather than a build system. I don't know why they did that, it seems to make things more complicated for them, but it is not harming me, the user.
The main objection I have is that it requires me to learn two build systems (hence the "now you have two problems"), as CMake just isn't good enough to fully hide the wrapped (target) build system. It's good as long as everything works, but as soon as something breaks, I have to understand way more of the internals than I should have to. That's the fundamental flaw with all macro-based languages. On a more philosophical level, I think that CMake is an attempt to patch over the fact that the underlaying build systems aren't portable. So the real fix to that problem obviously is to write such a portable build system that would obsolete the need for something like CMake. I just happen to believe that Faber does that. (For avoidance of doubt: b2 attempts the same, but falls short in terms of usability.)
Attributes would be passed consistently via keywords. They have reasonable defaults that Faber picks for me. Like, if I want another file extension for a library than the default for the platform. For libraries, I could specify whether to build a static or shared one. Or if I really don't want to name the library "greet", I could pass the keyword name="great".
This declaration enforces the use of keywords for attributes, positional arguments are not allowed for attributes, which is a good for clarity. That's actually a good point: I can change the definition of these functions (`rule`, artefact constructors, etc.) to explicitly forbid positional arguments for anything but the required arguments. I agree that would prevent certain errors. Thanks for the tip ! At least I was able to provide something useful :).
I invite you to download Faber and play with the examples. There are plenty of ways to make more useful contributions ! ;-) Stefan -- ...ich hab' noch einen Koffer in Berlin...