mallard
It seems that most important reason of your script support is explained in the following:
mallard wrote:Make ... already has this logic built-in, why re-implement it?
But if there was a C based build system and it had all Make's logic implemented, then it seems you would have no viable ground for objections.
And now about less important things (as I see it).
mallard wrote:So, you build the first verison of the build system with another pre-existing build system and then "port" the build system over to itself. (At least that's how programming languages become "self-hosting"; you write an initial compiler in a pre-existing language and then port it to itself.) Does that mean there are two set of build system source code in your repository?
No. There should be just one set. The first set, which was used to build the second, now became a history, it is obsolete now and can be placed in some museum archives. And developers should care about the second set only.
mallard wrote:We have higher-level languages to reduce the cognitive burden, improve portability and separate concerns.
Yes, but why we should use two languages instead of one? We have one preferred language and one legacy language for making builds. Why ever should we be bothered with the legacy language and it's quirks? Of course, we can learn the legacy stuff, we even can find many similarities with another legacy systems like Unix's command line language and other cryptic systems. But what useful we can get from the mastering of legacy (and as I see it - obsolete) systems? Why not to extract some useful knowledge without every day efforts of using the obsolete system?
mallard wrote:You've still got to define how the files are built, with which compiler, options, etc. Most OS kernels are written in multiple languages (i.e. assembly plus a higer level language) which means you need to have different rules for different kinds of source files. Your "buildObjectFiles" funtion would need to call something resembling my "build_object" function. (My "compile_with_gcc" type functions are imagined as thin wrappers over "execve"/"system".)
The question "how" is very easy to answer to - just the same way it was done in Make's libraries. It is still possible to call C based libraries (that Make uses) from C based program. Just reuse all those "how to", but in a bit more preferred manner (by using preferred language). And all options can be passed to the library code as plain parameters.
But instead we have a layer of complexity over the preferred language. The layer requires us to get acknowledged with some new concepts, with new syntax, with new environment requirements, and after all - it binds us to the unix-style operating system just to be able to run it.
mallard wrote:C isn't very good at this sort of thing. Things like string handling and variable-length arrays are awkward. It quickly becomes apparent that a DSL (domain-specific-language) would simplify things.
Even in C we can isolate some awkward stuff using library functions, for example. The functions should be written once and then all we have to do is just provide them with useful parameters. Is it so hard to achieve?
mallard wrote:the build system doesn't need any special knowledge of the language being used.
If we use many languages, then it makes some sense. But do we really use many languages? Most often we use just one. And to reuse the build system functionality we can make some libraries and call them from different languages. Why not to go this way?
mallard wrote:Things like executable formats are generally little more than extra parameters to the linker (or maybe an extra objcopy step to convert to a flat binary) as far as the build system is concerned.
And what about system image layout? First should be 512 byte of bootloader, then should go some file system stuff, then some files, one of the files should be our kernel in flat binary form (or may be not), somewhere else should be some system data structures and helper binaries. Is there some useful stuff in make scripts that places it all in a proper order? And if it is, then to what extent it is defined in libraries (to be called from preferred language)?
mallard wrote:It's my understanding that, in Java, if you use "import static" anywhere, you'll need to rebuild the importers every time the importee is modified, just like with "#include" in C-style languages
If class names and signature of methods are not changed then it is possible to not touch the importee. I suppose something similar should be actual for C libraries, but instead of names (class or method) there should be relative addresses of functions and structures exposed to the external world.
But however, if it is about code dependencies graph and we need for some reason to decouple the graph creation from image build process then what prevents us from doing this using preferred language? It's again just a matter of preference and not a matter of some additional complexity. Even more - the complexity of build layer language is greater than the complexity of build system made using preferred language.