phase1: support to request specific CC / CXX versions
[buildbot.git] / phase1 / findbin.pl
1 #!/usr/bin/env perl
2
3 use strict;
4 use warnings;
5
6 sub vernum($) {
7 if ($_[0] =~ m!^((?:\d+\.)+\d+)$!) {
8 my ($maj, $min) = split /\./, $1;
9 return int($maj) * 256 + int($min);
10 }
11
12 return 0;
13 }
14
15 sub vercmp($$$) {
16 my ($op, $v1, $v2) = @_;
17
18 if ($op eq 'lt') { return $v1 < $v2 }
19 elsif ($op eq 'le') { return $v1 <= $v2 }
20 elsif ($op eq 'gt') { return $v1 > $v2 }
21 elsif ($op eq 'ge') { return $v1 >= $v2 }
22 elsif ($op eq 'eq') { return $v1 == $v2 }
23
24 return 0;
25 }
26
27 sub findbin($$$) {
28 my ($basename, $compare, $maxvstr) = @_;
29
30 my $lastversion = 0;
31 my $cmpversion = vernum($maxvstr);
32 my $prog = undef;
33
34 foreach my $dir (split /:/, $ENV{'PATH'}) {
35 foreach my $bin (glob("$dir/$basename?*"), "$dir/$basename") {
36 if (-x $bin && open BIN, '-|', $bin, '--version') {
37 my $vers = 0;
38 my $line = readline(BIN) || '';
39
40 foreach my $token (split /\s+/, $line) {
41 $vers = vernum($token);
42 last if $vers > 0;
43 }
44
45 if ($vers > 0 && (!$cmpversion || vercmp($compare, $vers, $cmpversion))) {
46 if ($vers > $lastversion) {
47 $lastversion = $vers;
48 $prog = $bin;
49 }
50 }
51
52 close BIN;
53 }
54 }
55 }
56
57 return $prog;
58 }
59
60 my $bin = findbin($ARGV[0], $ARGV[1], $ARGV[2]);
61
62 if (defined $bin) {
63 printf "%s\n", $bin;
64 exit 0;
65 }
66 else {
67 warn "Cannot find a $ARGV[0] command with version $ARGV[1] $ARGV[2]\n";
68 exit 1;
69 }