This is the mail archive of the guile@cygnus.com mailing list for the Guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Tired of make. Anyone interested in a guile-based replacement?


> I abandoned the whole thing long ago as the spawn of the devil.  :-)
> Seriously, though, that's how it made me feel.  It was great at first,
> but any time I tried to do something non-standard, I was faced with
> random errors, incomplete documentation, bugs, and impenetrable source
> code.

I came to the same conclusion about autoconf and I must say that I don't
like libtool either. I have some more concrete complaints though and I
have some ideas on a replacement (but my objectives are a lot more limited
than this project seems to be intending).

Firstly the bad things:

* In autoconf, symbols with the same meaning get given various different
  names depending on where they are used. For example, when they are shell
  variables they will be called one thing and when they are #defines in
  C code they will be called something else. This generates complexity where
  there is no reason to do so.

* In autoconf, symbols have short and arbitrary names without any overall
  structure. This means that you can't scan a block of code for any autoconf
  symbols because you don't know what to scan for.

* Yeah documentation is patchy, this seems to be true for everything so
  not much else can be expected. The thing is that without a well defined
  guiding structure the user is highly dependent on the docco. With a
  sensible structure around it all, the user will at least know where to
  go looking.

* autoconf depends highly on the behaviour of the system shell to get
  correct results out of its configure scripts. The shell is not actually
  particularly consistent across systems nor should shell behaviour really
  be so critical to the build process.

* libtool doesn't handle shared library dependencies properly on Linux.
  The best, easiest and most functional way to make a shared library on
  Linux is to use exactly the same command line that you would have done
  to make the executable but put in a -shared option for gcc. In some cases
  adding -fPIC will help but it is usually not required. If you do it this
  way then when a library depends on another library, it is correctly chained
  into the load.

  Libtool goes and mucks around with ld and linker options and ends up
  producing libraries that require the user of the library to know every
  dependency that the library has -- there is no need for this.

* When an autoconf `configure' script goes wrong it is difficult to figure
  out why and where. There are some reasons for this: [1] The script builds
  test code on the fly and deletes it afterwards, [2] the script itself
  cannot easily be read through top to bottom, so you don't know which
  bit exactly was the bit that failed, [3] the log files are difficult to
  relate to the script.

* When you tweak something in an autoconf script or when you attempt to
  override on of its settings, you can get unexpected results. Partly
  this is because sometimes the settings files themselves are checked by
  make so that it tries to tweak your tweaks and partly because of the
  caching scheme that stores test results in more than one place.

> I really didn't like the philosophy of the whole thing.  It was all ad
> hoc names, like a bad AI program.

The autoconf documentation admits this and autoconf was never intended
to be some ultimate configuration tool. Regular rethinking and rewriting
of such tools is always healthy IMHO.

> I think having a real programming language would lead to a more open
> and comprehensible structure.  Given that, then all of the carefully
> collected rules of autoconf and automake could be imported.  Those
> rules work just fine, and they should certainly not be discarded
> completely, but I think they are too monolithic and need to be
> reorganized into a series of manageable transformations.

I agree with some of this but not all. You do want a generic
programming language for configuration descriptions but you do not
want to go and use the features of this language willy-nilly, you want
99% of cases to be handled in a consistent manner so that anyone can
walk in and know where they are.

Here are some idea from my configuration utility.

* The name of my utility is ``jexy''. I chose this name because if you
  really use your imagination it stands for ``Jett Enougher Xonfiguration
  Youtility''. It also so happens that the combination of letters ``JEXY''
  almost never occurs it intelligable writings so it is easy to know that
  you won't crowd someone else's namespace. In keeping with this wisdom,
  ALL defined symbols are prefixed JEXY_ and you can grep for them very
  reliably. It happens to also be pronounceable.

  If you want to make a useful configuration tool, don't give it a cool
  name, give it a dumb name that no one else will ever use. Give it a short
  name that will make a nice prefix but not piss people off when they type it.
  Don't use my jexy name or by the powers of heaven I'll hunt you down...

* It uses a perl script to translate a table of shell symbols into a table
  of #defines for use in C. The shell symbols look something like:

JEXY_GCC_OPTION_NO_RTTI=-fno-rtti
JEXY_GCC_OPTION_NO_EXCEPTIONS=-fno-exceptions
JEXY_LINK_SHARED_SONAME_SUN=1
JEXY_LINK_SHARED_SONAME_WHOLE_ARCHIVE_FPIC=1
JEXY_LINK_SHARED_SONAME_WHOLE_ARCHIVE=1
JEXY_LIBRARY_MATH=-lm
JEXY_LIBRARY_MATH_SCALB=1
JEXY_LIBRARY_SEARCH_DYNAMIC_LINK=-ldl
JEXY_LIBRARY_SEARCH_X11=-lX11
JEXY_LIBRARY_SEARCH_LIBGUILE=-lguile
JEXY_INCLUDE_SEARCH_LIBGUILE=libguile.h
JEXY_INCLUDE_SEARCH_XLIB=X11/Xlib.h

  Needless to say these are auto-generated but there are a few important
  points about this table format. It can be equally well be included by
  makefiles and by shell scripts so the file ``config.sh'' handles both
  jobs and thus the symbol definitions are guaranteed consistent.

  It is easy to translate into a C header like so:

/* generated by jexy/Makefile from config.sh */
#define JEXY_GCC_OPTION_NO_RTTI "-fno-rtti"
#define JEXY_GCC_OPTION_NO_RTTI_AB <-fno-rtti>
#define JEXY_GCC_OPTION_NO_EXCEPTIONS "-fno-exceptions"
#define JEXY_GCC_OPTION_NO_EXCEPTIONS_AB <-fno-exceptions>
#define JEXY_LINK_SHARED_SONAME_SUN 1
#define JEXY_LINK_SHARED_SONAME_WHOLE_ARCHIVE_FPIC 1
#define JEXY_LINK_SHARED_SONAME_WHOLE_ARCHIVE 1
#define JEXY_LIBRARY_MATH "-lm"
#define JEXY_LIBRARY_MATH_AB <-lm>
#define JEXY_LIBRARY_MATH_SCALB 1
#define JEXY_LIBRARY_SEARCH_DYNAMIC_LINK "-ldl"
#define JEXY_LIBRARY_SEARCH_DYNAMIC_LINK_AB <-ldl>
#define JEXY_LIBRARY_SEARCH_X11 "-lX11"
#define JEXY_LIBRARY_SEARCH_X11_AB <-lX11>
#define JEXY_LIBRARY_SEARCH_LIBGUILE "-lguile"
#define JEXY_LIBRARY_SEARCH_LIBGUILE_AB <-lguile>
#define JEXY_INCLUDE_SEARCH_LIBGUILE "libguile.h"
#define JEXY_INCLUDE_SEARCH_LIBGUILE_AB <libguile.h>
#define JEXY_INCLUDE_SEARCH_XLIB "X11/Xlib.h"
#define JEXY_INCLUDE_SEARCH_XLIB_AB <X11/Xlib.h>

  Note that for some jobs C needs quoteed strings for other jobs
  it needs angle brackets so I generate both. OK, some lines in this
  file are useless -- so what, it is logically consistent and the
  system is easy to implement and easy to understand. I presume that
  numerics are never going to be used as strings or filenames. Most people
  seeing numerics would be surprised if they turned into filenames so
  it is a bad idea to ever use them in such a manner.

* I write the fundamental configuration in scheme and then run a scheme
  program on this configuration file. The scheme program generates makefiles
  which are used with gnumake to do the actual build. I can't be bothered
  supporting anything more primitive than gnumake so I don't feel guilty
  about using its special features (though I don't push this to the limit).
  
* One special feature that I use is ``make -k'' which (with some care) can
  be used to attempt to build test code and report the success or failure
  of the test. Note that this is not blown up by warnings, only by success
  or failure as reported by the compiler. In many places autoconf runs the
  compiler and checks if any messages at all were produced -- any message
  at all is enough to fail the test! Also, ``make -k'' is doing the closest
  thing to a real build. Rather than search the path for something that
  looks like a C compiler, I attempt to compile a C program -- if that works
  then I decide that I must have a C compiler.

* Each test-run has one or more test C programs which are numbered
  automatically and generated along with the makefile. The user can see which
  C programs are being compiled, which options are being used and which
  symbols are being defined as a consequence. OK, a lot of crap scrolls up
  and it doesn't look as sweet as when configure runs but it is much much
  easier to figure out what is happening. Tests and results are not deleted
  after they are run so the user can check them. All this is done in a
  subdirectory.

* Test runs go in waves and partially construct the symbol table after
  each wave. This allows late waves to make use of results from earlier
  waves. You need this to handle (for example) the situation where libguile
  may or may not be compiled to depend on libreadline and unless you get
  it right, you won't be able to prove that libguile works so you can't
  find libguile on the system. Thus you have to first search for libreadline
  on the system, then search for libguile.

* I do follow the autoconf philosophy of testing for features not for brand
  names. This is explained in various places and I hope that we are all
  comfortable with those concepts at this stage.

* I have a special user-override file called ``userconf.sh''. From this
  I generate userconf.h (as above) and I always let these symbols override
  my generated symbols. Any symbol can be redefined in this manner if the
  user has some reason to do so. This also makes a convenient place for
  users to put definitions of some symbols that cannot be automatically
  guessed (such as installation target directory) and it also can be used
  to hold documentation of what the symbols are so that when the user is
  in a hurry he/she can read right then and there what  will be the expected
  effect of changing a symbol.


OK, that's enough of my comments... I dont expect everyone to rush out and
use my configurator but do please take heed of some of my suggestions before
anyone goes out to build a new behemoth.

	- Tel

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]