Return-Path: Delivered-To: new-httpd-archive@hyperreal.org Received: (qmail 10488 invoked by uid 6000); 11 Jun 1999 07:21:49 -0000 Received: (qmail 10463 invoked from network); 11 Jun 1999 07:21:38 -0000 Received: from slarti.muc.de (193.149.48.10) by taz.hyperreal.org with SMTP; 11 Jun 1999 07:21:38 -0000 Received: (qmail 11404 invoked by uid 66); 11 Jun 1999 07:20:39 -0000 Received: from en by slarti with UUCP; Fri Jun 11 07:20:39 1999 -0000 Received: by en1.engelschall.com (Sendmail 8.9.3+3.2W) for new-httpd@apache.org id JAA19801; Fri, 11 Jun 1999 09:19:21 +0200 (CEST) Date: Fri, 11 Jun 1999 09:19:21 +0200 From: "Ralf S. Engelschall" To: new-httpd@apache.org Subject: Notes about APR's Autoconf stuff Message-ID: <19990611091921.A18164@engelschall.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailer: Mutt 0.95.6i Organization: Engelschall, Germany. X-Web-Homepage: http://www.engelschall.com/ X-PGP-Public-Key: https://www.engelschall.com/ho/rse/pgprse.asc X-PGP-Fingerprint: 00 C9 21 8E D1 AB 70 37 DD 67 A2 3A 0A 6F 8D A5 Sender: new-httpd-owner@apache.org Precedence: bulk Reply-To: new-httpd@apache.org 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 and inside the source you've ``#if defined() || defined()'' for one thing and you've ``#if defined() || defined()'' 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 configure.in 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. Greetings, Ralf S. Engelschall rse@engelschall.com www.engelschall.com