[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Improvement to admin/detect-autoconf.sh [PATCH]
From:       Michael Pyne <pynm0001 () comcast ! net>
Date:       2005-07-17 2:39:17
Message-ID: 200507162239.23041.pynm0001 () comcast ! net
[Download RAW message or body]

[Attachment #2 (multipart/mixed)]


Hi all,

A FreeBSD user had reported an error against kdesvn-build, and gave me access 
to a FreeBSD box to investigate.  After my investigation I came to the 
conclusion that it would probably be a good idea to update 
detect-autoconf.sh.  The reasons?

 1. New versions of automake and autoconf have to be added to the script as 
they are released.  So if a user upgrades the autotools to a version that is 
(presumably) better, it won't be picked up until we update the autotools.

 2. Some operating systems (notably, the FreeBSD box I have access to), have 
the autotools installed but with a different versioning scheme.  e.g. even 
though detect-autoconf.sh will search for autoconf-2.53, it will never find 
FreeBSD's autoconf253 script.

So, I went and created a Perl script to do a rather exhaustive search for the 
autotools.  Since I was at it (and it wasn't hard) I added a few things.

 1. It searches for the best installed executable version of automake and 
autoconf, and uses the version number it reads from the script to search for 
aclocal, autom4te, and autoheader just like detect-autoconf.sh does.  If 
there is no versioned script in $PATH then it will use a non-versioned script 
if available (e.g. if "automake" is the only automake* in the PATH it will 
use that).  This is also the same as the current detect-autoconf.sh, which 
seems to prefer versioned over unversioned scripts.

 2. When doing this search, it doesn't rely on a list of suffixes distributed 
with the script.  So, it will find the "best" version of auto* even if the 
user updates the autotools after downloading KDE.

 3. The programs it looks for (which, auto*, unsermake) can be overridden by 
an environment variable of the same name uppercased.  UNSERMAKE=no is still 
checked for.  This way users don't have to setup symlinks to run make -f 
Makefile.cvs.

 4. The output is in an eval-able form for shell scripts.

 5. It works both on my Linux system and the FreeBSD box I have access to. :)

One potential problem is that the attached detect-autoconf.pl doesn't do 
blacklisting.  It's not hard for me to add, but do we need it?  Or if 
blacklisting is not required, should I add a minimum version to check for 
when looking for the tools?

Also, it's written in Perl, which I *think* is required for KDE building 
anyways.  I tried starting out in sh but it quickly drove me batty.  I can 
try to get help to convert it to sh if it's absolutely necessary however.

Note that I'm *not* saying that you can't build KDE on FreeBSD without this 
patch, or you would have heard whining from people besides me. ;-)  According 
to Adrian there is a gnu-autoconf and gnu-automake port for FreeBSD that 
provides the unversioned autotools that makes KDE from SVN work.  I just 
think that if there are autotools available it should be easier to have KDE 
use them (while we're still using the autotools. >:-)

Any and all comments are appreciated.

The following patch to cvs.sh is needed to use the script after it's placed in 
the /admin dir and made executable:

Index: cvs.sh
===================================================================
--- cvs.sh      (revision 435055)
+++ cvs.sh      (working copy)
@@ -628,8 +628,9 @@
   rm -f $makefile_wo
 fi

-# Suck in the AUTOCONF detection code
-. $admindir/detect-autoconf.sh
+# Call script to find autoconf and friends.  Uses eval since the script 
outputs
+# sh-compatible code.
+eval `$admindir/detect-autoconf.pl`

 ###
 ### Main

Regards,
 - Michael Pyne

["detect.pl" (application/x-perl)]

#!/usr/bin/env perl

# Try to locate best version of auto*
# By Michael Pyne <michael.pyne@kdemail.net>
#
# Copyright (c) 2005.
# This code is public domain.  You may use it however you like (including
# relicensing).

# Emulate the 'which' program.
sub which
{
    my $prog = shift;
    my @paths = split(/:/, $ENV{'PATH'});

    for $path (@paths)
    {
	return "$path/$prog" if -x "$path/$prog";
    }

    return "";
}

# Subroutine to determine the highest installed version of the given program,
# searching from the given paths.
sub findBest
{
    my ($program, @paths) = @_;
    my $best_version_found = '0'; # Deliberately a string.
    my %versions;

    # Allow user to use environment variable to override search.
    return $ENV{uc $program} if $ENV{uc $program};

    for $prefix (@paths)
    {
	@files = glob "$prefix/$program*";
	for $file (@files)
	{
	    # Don't check non-executable scripts.
	    next unless -x $file;

	    ($version) = $file =~ /$program-?(.*)$/;
	    $version =~ s/-|\.//g;

	    # If no version suffix then just save the script unless we've already
	    # seen something better.
	    if(not $version and $best_version_found eq '0')
	    {
		$versions{$best_version_found} = $file;

		# Change best_version_found to ensure that we keep this entry
		# if we see another versionless script later.
		$best_version_found = '00';
		next;
	    }

	    # Emulate 'which', and abort if we've already seen this version.
	    next if exists $versions{$version};

	    # Save filename of program.
	    $versions{$version} = $file;

	    # Use string comparison so that e.g. 253a will be > 253 but < 254.
	    if ($version gt $best_version_found)
	    {
		$best_version_found = $version;
	    }
	}
    }

    return $versions{$best_version_found};
}

# Find an appropriate "which" program for later use by the shell script calling
# us.
sub findWhich
{
    for $candidate ('type -p', 'which', 'type')
    {
	$test = `$candidate sh 2>/dev/null`;
	chomp $test;

	return $candidate if -x $test;
    }
}

# Uses which() to find a program unless the user provided its path in the
# environment (the upper case program name is searched).
sub findProgram
{
    $suffix = ""; # For use if @_ has only one param.
    my ($program, $suffix) = @_;

    return $ENV{uc $program} if $ENV{uc $program};
    return which("$program$suffix");
}

# SCRIPT STARTS.

# Search in path.
@paths = split(/:/, $ENV{'PATH'});

# Make sure at least /usr/bin and /usr/local/bin are in this search.
unshift @paths, '/usr/local/bin' unless grep $_ eq '/usr/local/bin', @paths;
unshift @paths, '/usr/bin' unless grep $_ eq '/usr/bin', @paths;

$autoconf = findBest('autoconf', @paths);
($autoconf_suffix) = $autoconf =~ /.*autoconf(.*)$/;

# Find matching autoconf companions.
$autoheader = findProgram('autoheader', $autoconf_suffix);
$autom4te = findProgram('autom4te', $autoconf_suffix);

# Get best automake, and look for unsermake to possibly override it.
$automake = findBest('automake', @paths);
$unsermake = ($ENV{'UNSERMAKE'} ne 'no') ? findProgram('unsermake') : "";

($automake_suffix) = $automake =~ /.*automake(.*)$/;

# Use unsermake if we found it.
$automake = "$unsermake -c" if $unsermake;

# Find matching automake companions.
$aclocal = findProgram('aclocal', $automake_suffix);

$which = findWhich();

# Make sure we have all of the needed programs.
for $i (qw'autoconf autoheader autom4te automake aclocal')
{
    unless(${$i})
    {
	print "# Unable to find $i!!\n";
	exit 1;
    }
}

# Print results in eval-able form.
print <<EOF;
AUTOCONF="$autoconf"
AUTOHEADER="$autoheader"
AUTOM4TE="$autom4te"

AUTOMAKE="$automake"
ACLOCAL="$aclocal"

WHICH="$which"

export AUTOCONF AUTOHEADER AUTOM4TE AUTOMAKE ACLOCAL WHICH
EOF

exit 0;

[Attachment #6 (application/pgp-signature)]

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic