Page 1 of 1

What is your vision of ideal build system script?

Posted: Thu Sep 27, 2012 4:00 pm
by Griwes
I'm going to create my very own build system for my project, and I don't want to do it in SCons-style or Waf-style way, i.e. not with build scripts as Python or any other language files. I had few ideas of my own format, few that understood what .c or .cpp file is, few that didn't, few that were just obfuscated versions of Makefile, few that weren't, and I can't really come up with easy to learn and use format for it.

The build system is meant to require Makefile-like files, but providing sane way to call filesystem functions (no moar $(shell) hell), to get current architecture/OS, to access command line switches and allow users to write `if-else` blocks in it. I want something like this:

Code: Select all

if (linux and -rose) // we are cross-compiling on Linux for ReaverOS
// command line: build -rose .
{
    CXX = /usr/reaver/cross/bin/clang++ // or: load_preset(/usr/reaver/cross) or something like that
}

if (linux and -exclude includes builder)
// command line: build -exclude=builder ., but also build -exclude=builder,kernel,utilities
{
    // ...
}
Those are meant just to show how I'd like to get switch handling and architecture handling done; I know there isn't much in this example, but I want to get some opinions from you.


So: how would your "ideal" Makefile-ish file format look like?

---------

Edit: I know Brendan will say something like "In my perfect world, you don't need build scripts"; yet I'm asking about opinions of us, non-perfect-worlders ;)

Re: What is your vision of ideal build system script?

Posted: Thu Sep 27, 2012 7:38 pm
by Brendan
Hi,
Griwes wrote:Edit: I know Brendan will say something like "In my perfect world, you don't need build scripts"; yet I'm asking about opinions of us, non-perfect-worlders ;)
You're right.

Think of it as a big compromise between 2 very different extremes. At one extreme there's "nothing" where you have to manually type commands into a shell in a precise order each time you want to build anything. This is extremely tedious. At the other extreme there's "nothing" (my perfect world), where the hassle of building is minimised to the point where you don't need to write or maintain anything that describes how things are built.

The question is, how far can you get from the first extreme (or, how much hassle can you avoid) without inventing your own world?

Bash/python/whatever scripts are an obvious first step. Something like makefiles (which are basically just scripts in a language intended to be more suitable) are a slightly better second step. I don't think you can go much further than this; as going further means avoiding the need for languages and files/scripts to describe what to do, which is the beginning of inventing your own world.


Cheers,

Brendan

Re: What is your vision of ideal build system script?

Posted: Thu Sep 27, 2012 8:26 pm
by Love4Boobies
An optimal build system cannot exist by itself; it needs to be tightly integrated with the compiler (make and other tools are designed to be compiler-independent and do not care about the language the code was written in). The reason for this is that these legacy tools work on a file basis when dependencies actually happen within translation units. This causes unnecessary work. E.g., consider the following:

Code: Select all

// foo.h

void hello(void);
void world(void);

// foo.c

#include <foo.h>

void bar(void)
{
    hello();
}
If you were to change the return type of world to int, the build system should not rebuild foo.c. But not only will it do that; it will also rebuild everything that depends on either it or foo.h. A whole tree of extra rebuilding follows.

Re: What is your vision of ideal build system script?

Posted: Fri Sep 28, 2012 12:15 am
by bluemoon
I use shell script to generate Makefile, It's portable and easy (ie. it works on Linux and Mac, and perhaps cygwin)

To process argument it's simple:

Code: Select all

for i in $*
do
  case $i in
      --arch=i586   )
          ARCH=i586
      ;;
      --arch=x86_64 )
          ARCH=x86_64
      ;;
  esac
done
To detect the host platform:

Code: Select all

case $(uname -a) in
    *BSD* )
        PLATFORM=BSD
    ;;
    *Linux* )
        PLATFORM=LINUX
    ;;
    *Darwin\ Kernel* )
        PLATFORM=MACOSX
    ;;
    *SunOS* )
        PLATFORM=SOLARIS
    ;;
esac
*Note: You might be actually using darwin instead of Mac OS, but it is practically working for me.

The script can setup parameters for Makefile, scan entries of drivers and output their entry on Makefile, etc
And like the Makefile itself, once it's done you never need to care it again.