httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Ralf S. Engelschall" <>
Subject Notes about APR's Autoconf stuff
Date Fri, 11 Jun 1999 07:19:21 GMT

A few Autoconf related notes to the guys working on APR. Do not treat this as
an offense, please. You're doing a great job working on this stuff. I just
want to share my opinion with you about things I've recently observed. I know
that I still do not work on APR myself and so it maybe is a pain for some of
you when I nevertheless express my opinion. But I think that some feedback
cannot be wrong and at least sharing my opinion could help you to even further
improve APR. I don't know whether the Autoconf stuff is important for you.
Perhaps it isn't. At least IMHO it is important for a beast like APR when it
wants to be a successful package and be what it's P in the name indicates.

1. The "if (test ..); then" constructs

> [...] 
>   +if (test "$SYS_SW" = "FreeBSD"); then
> [...] 

Sorry when I ask (again?): What's the real intention behind these type of
if-constructs, i.e. why the parenthesis?  Sure, inside Autoconf one usually
writes "test" instead of "[" ... "]", because the square brackets are the
delimiters of m4 in Autoconf. But why the parenthesis? They create a
subshell without need IMHO.

In other words:

 if test "$SYS_SW" = "FreeBSD"; then

should be enough and will be faster. So, are the "if (test..); then"
constructs just by coincidence or accident or there a deeper intention I've
just still not understood? The only two situations where a subshell is
important is for 1. when you want to do a temporary "cd" and the old dir
cannot be assumed fixed or 2. when you want to test for the existance of a
program where you've to use constructs like var=`(program) 2>/dev/null`. But
I've to admit that although I wrote Autoconf stuff for many years I've never
seen reasons for "if (test...); then" constructs...

2. Autoconf and the feature/OS philosophy

I'm still wondering why you explicitly define the OS although you're using
Autoconf. Sure, sometimes one need an OS dependent kludge in the source (for
instance for my NPS library I've to recognize Linux and do a kludge because
Linux is the _only_ platform with a not working sigstack/sigaltstack, etc).
But usually the glory rule for Autoconf based project IMHO is: Replace all
direct OS kludges with feature-determined kludges. 

The benefit?  You're more portable, because the same kludge/situation is then
recognized for more than a single OS.  An example: When you determine the OS
in Autoconf only, create -D<OS> and inside the source you've ``#if
defined(<OS1>) || defined(<OS2>)'' for one thing and you've ``#if
defined(<OS3>) || defined(<OS4>)'' for the alternative, etc.  Then you're
program isn't _really_ portable. I personally call it then just
"semi-portable" because it was just "manually ported to a fixed set of N
operating systems". When you're on one of those N operating systems, you _can_
consider the program portable, of course. But it isn't "portable", because
when you're on the (N+1)th OS which isn't part of the already known set of
recognized OS then the program fails. And then you've to "port" it manually.  

An example is MIT-pthreads. It's considered "portable" by lots of people,
but for me it's just "semi-portable" (although it's a great package, btw).
Because it has only a fixed set of known platforms to which it was ported.
There it works great. But for every additional platform horrible porting of
assembler code and other hacks start. 

Really "portable" for me means this: Either you use only constructs which are
per definition portable (i.e. mainly only ANSI C features or functions
long known to the POSIX world) _OR_ you at least use a package like Autoconf
the _correct_ way. The correct way for me (proof me to be wrong) is this: You
test not for particular platforms for dispatching on it later in the source.
Instead you test for existing _features_ and dispatch later in the source
according to available features. Else you're program is just "semi-portable"
and for those Autoconf isn't required. Then you can avoid using it at all.

That's why I'm still confused by the APR stuff. Because I still do not
understand why it's both necessary to have subdirs for various platform
flavors (except perhaps for the reason that different build mechanisms have to
used: make vs.  a GUI-tool, etc) and specialized #defines for the platforms.
Because when APR uses Autoconf (the correct way, of course) IMHO these things
can be completely avoided.

3. Autoconf and practice experiences

I do not know whether the guys working on APR have experiences or not with
Autoconf and source trees (I only know that Ken once said that he still starts
to learn Autoconf - that's ok). At least a quick look at the current showed to me that not too much experience seem to exist (or at
least it's still not considered important). That's no problem, of course. When
you would have seen my first Autoconf scripts you would ROTFL on me ;) 

So, don't treat this as an indoctrination, but I strongly recommend you to
look at existing Autoconf stuff of _clean_ packages. I learned most of the
gory Autoconf details by studying existing Autoconf stuff. Five years ago this
was a pain, I've to admit. There were only unclean Autoconf stuff. But today
lots of good and clean Autoconf examples exists. Look at these when you want
to improve your stuff. Don't look at the large packages which use Autoconf,
they confuse because of already too much kludges which were added over time.
Look at small libraries and small packages using Autoconf. 

Although I'm now biased when I say this, but my personal recommendation is to
look at MM. For these particular reasons: 1. It has to check lots of platform
stuff, but I think it does it the correct way and the package is small enough
to not be confused by kludges; 2. it shows you how one can combine Autoconf
with libtool and shtool the manual non-Automake way (I also recommend APR to
use these tools, at least libtool); 3. it uses a nifty decision hierarchy
concept multiple times to find the best implementation approach which can be
very useful in a smimilar way for APR. Because it gives features an order
relation which is important when multiple features exists on a platform but
they cannot be treated equal in features/side-effects, etc.

There are similar packages like MM where you additionally also can find good
examples. The way to find them is to use FTPSearch and searching for the files
"aclocal.m4" on the net. Download them all(!) and concatenate them. Then when
you've a problem, _ALWAYS_ first grep inside this large example pool. For all
standard situations Autoconf's distributed macros are enough. And even for most
of the esoteric situations someone usually already has written a solution
which you can find this way.


Sorry when I cannot work on APR myself. But perhaps at least the above hints
help you a little bit to improve APR even further.

                                       Ralf S. Engelschall

View raw message