Shared admin folder
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

detect-autoconf.pl 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. #!/usr/bin/env perl
  2. # Try to locate best version of auto*
  3. # By Michael Pyne <michael.pyne@kdemail.net>
  4. #
  5. # Copyright (c) 2005.
  6. # This code is public domain. You may use it however you like (including
  7. # relicensing).
  8. # Emulate the 'which' program.
  9. sub which
  10. {
  11. my $prog = shift;
  12. my @paths = split(/:/, $ENV{'PATH'});
  13. for $path (@paths)
  14. {
  15. return "$path/$prog" if -x "$path/$prog";
  16. }
  17. return "";
  18. }
  19. # Subroutine to lexicographically compare two version strings, a and b.
  20. # If a > b, 1 is returned.
  21. # If a == b, 0 is returned.
  22. # If a < b, -1 is returned.
  23. #
  24. # If the strings are of uneven number length then the shorter string is
  25. # prepended by enough zeroes to make the two string lengths equal in order to
  26. # allow an accurate comparison. Note that the zero-padding only occurs in
  27. # between version separators (i.e. 1.6 and 1.10, results in 1.06 vs. 1.10).
  28. # Parts of the version ending in -foo (or any other text) are not considered
  29. # when doing the compare. (i.e. 2.53a vs 2.53 doesn't end up in 2.53a vs.
  30. # 2.053)
  31. sub compareVersions
  32. {
  33. my ($a, $b) = @_;
  34. # Split the strings up by '.' (version separator) and start comparing digit
  35. # length.
  36. my @aParts = split(/\./, $a);
  37. my @bParts = split(/\./, $b);
  38. # Make the arrays equal in length by adding missing zeroes to the end of the
  39. # version.
  40. push @aParts, '0' while scalar @aParts < scalar @bParts;
  41. push @bParts, '0' while scalar @bParts < scalar @aParts;
  42. # Now compare each individual portion.
  43. for (my $i = 0; $i < scalar @aParts; ++$i)
  44. {
  45. # Make sure that any portion that has numbers is contiguous. I'm sure
  46. # there's a technique for saving stuff like 2.52a2 but I don't feel
  47. # like implementing it.
  48. if ($aParts[$i] !~ /^[^\d]*\d+[^\d]*$/ or
  49. $bParts[$i] !~ /^[^\d]*\d+[^\d]*$/)
  50. {
  51. die "Not able to compare $a to $b!\n";
  52. }
  53. my ($aDigits) = ($aParts[$i] =~ /(\d+)/);
  54. my ($bDigits) = ($bParts[$i] =~ /(\d+)/);
  55. # Perl is $MODERATELY_INSULTING_TERM, don't remove the parentheses in
  56. # the delta calculation below.
  57. my $delta = (length $aDigits) - (length $bDigits);
  58. if ($delta < 0) # b is longer
  59. {
  60. my $replacement = ('0' x (-$delta)) . $aDigits;
  61. $aParts[$i] =~ s/$aDigits/$replacement/;
  62. }
  63. elsif ($delta > 0) # a is longer
  64. {
  65. my $replacement = ('0' x $delta) . $bDigits;
  66. $bParts[$i] =~ s/$bDigits/$replacement/;
  67. }
  68. }
  69. # Arrays now have standardized version components, let's re-merge them
  70. # to strings to do the compare.
  71. my $newA = join('.', @aParts);
  72. my $newB = join('.', @bParts);
  73. return 1 if ($newA gt $newB);
  74. return -1 if ($newA lt $newB);
  75. return 0;
  76. }
  77. # Subroutine to determine the highest installed version of the given program,
  78. # searching from the given paths.
  79. sub findBest
  80. {
  81. my ($program, @paths) = @_;
  82. my $best_version_found = '0'; # Deliberately a string.
  83. my %versions;
  84. my %minimumVersions = (
  85. 'autoconf' => '2.5',
  86. 'automake' => '1.6',
  87. );
  88. my $sgn; # Used for compareVersions results.
  89. # Allow user to use environment variable to override search.
  90. return $ENV{uc $program} if $ENV{uc $program};
  91. for $prefix (@paths)
  92. {
  93. @files = glob "$prefix/$program*";
  94. for $file (@files)
  95. {
  96. # Don't check non-executable scripts.
  97. next unless -x $file;
  98. ($version) = $file =~ /$prefix\/$program-?(.*)$/;
  99. # Don't check the -wrapper ones (or any other non program one).
  100. # The real deal should start with a version number, or have no
  101. # suffix at all.
  102. next if $version =~ /^[^\d]/;
  103. # Special case some programs to make sure it has a minimum version.
  104. if (not $version and exists $minimumVersions{$program})
  105. {
  106. my $min_version = $minimumVersions{$program};
  107. my $versionOutput = `$program --version 2>/dev/null | head -n 1`;
  108. # If we can't run the script to get the version it likely won't work later.
  109. next unless $versionOutput;
  110. # Use number.number for version (we don't need the excess in general).
  111. ($versionOutput) = ($versionOutput =~ /(\d+\.\d+)/);
  112. # compareVersions returns -1 if the left argument is less than
  113. # the right argument. It can also die for invalid input so
  114. # wrap with eval.
  115. eval {
  116. $sgn = compareVersions($versionOutput, $min_version);
  117. };
  118. # $@ would be set if an error was encountered.
  119. if ($@ or not $versionOutput or $sgn == -1) {
  120. next;
  121. }
  122. }
  123. # If no version suffix then use it in favor of a versioned autotool
  124. # since the ever-popular WANT_AUTOFOO should then work (in theory).
  125. return $file unless $version;
  126. # Emulate 'which', and abort if we've already seen this version.
  127. next if exists $versions{$version};
  128. # Save filename of program.
  129. $versions{$version} = $file;
  130. # Use string comparison so that e.g. 253a will be > 253 but < 254.
  131. # See above about the need for eval.
  132. eval {
  133. $sgn = compareVersions($version, $best_version_found);
  134. };
  135. if (not $@ and $sgn == 1)
  136. {
  137. $best_version_found = $version;
  138. }
  139. }
  140. }
  141. return $versions{$best_version_found};
  142. }
  143. # Find an appropriate "which" program for later use by the shell script calling
  144. # us.
  145. sub findWhich
  146. {
  147. for $candidate ('type -p', 'which', 'type')
  148. {
  149. $test = `$candidate sh 2>/dev/null`;
  150. chomp $test;
  151. return $candidate if -x $test;
  152. }
  153. }
  154. # Uses which() to find a program unless the user provided its path in the
  155. # environment (the upper case program name is searched).
  156. sub findProgram
  157. {
  158. $suffix = ""; # For use if @_ has only one param.
  159. my ($program, $suffix) = @_;
  160. return $ENV{uc $program} if $ENV{uc $program};
  161. return which("$program$suffix");
  162. }
  163. # SCRIPT STARTS.
  164. # Search in path.
  165. @paths = split(/:/, $ENV{'PATH'});
  166. # Make sure at least /usr/bin and /usr/local/bin are in this search.
  167. unshift @paths, '/usr/local/bin' unless grep $_ eq '/usr/local/bin', @paths;
  168. unshift @paths, '/usr/bin' unless grep $_ eq '/usr/bin', @paths;
  169. $autoconf = findBest('autoconf', @paths);
  170. ($autoconf_suffix) = $autoconf =~ /.*autoconf(.*)$/;
  171. # Find matching autoconf companions.
  172. $autoheader = findProgram('autoheader', $autoconf_suffix);
  173. $autom4te = findProgram('autom4te', $autoconf_suffix);
  174. # Get best automake, and look for unsermake to possibly override it.
  175. $automake = findBest('automake', @paths);
  176. $unsermake = "";
  177. # backward compatible: if $UNSERMAKE points to a path, use it
  178. $unsermake = findProgram('unsermake') if (defined($ENV{'UNSERMAKE'}) and $ENV{'UNSERMAKE'} =~ /\//);
  179. # new compatible: if it says 'yes', use the one from path
  180. $unsermake = which('unsermake') if ($ENV{'UNSERMAKE'} ne 'no');
  181. ($automake_suffix) = $automake =~ /.*automake(.*)$/;
  182. # Find matching automake companions.
  183. $aclocal = findProgram('aclocal', $automake_suffix);
  184. # Use unsermake if we found it.
  185. $automake = "$unsermake -c" if ($unsermake and $aclocal);
  186. $which = findWhich();
  187. # Make sure we have all of the needed programs.
  188. for $i (qw'autoconf autoheader autom4te automake aclocal')
  189. {
  190. unless(${$i})
  191. {
  192. print STDERR "# Unable to find $i!!\n";
  193. }
  194. }
  195. # Print results in eval-able form.
  196. print <<EOF;
  197. AUTOCONF="$autoconf"
  198. AUTOHEADER="$autoheader"
  199. AUTOM4TE="$autom4te"
  200. AUTOMAKE="$automake"
  201. ACLOCAL="$aclocal"
  202. WHICH="$which"
  203. export AUTOCONF AUTOHEADER AUTOM4TE AUTOMAKE ACLOCAL WHICH
  204. EOF
  205. exit 0;
  206. # vim: set noet ts=8 sw=4: