buildall.pl 4.62 KB
Newer Older
Franksen, Benjamin's avatar
Franksen, Benjamin committed
1
#!/usr/bin/perl
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# Copyright 2015 Helmholtz-Zentrum Berlin für Materialien und Energie GmbH
# <https://www.helmholtz-berlin.de>
#
# Author: Benjamin Franksen <Benjamin.Franksen@helmholtz-berlin.de>
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
# 
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
# 
# You should have received a copy of the GNU General Public License along with
# this program.  If not, see <http://www.gnu.org/licenses/>.

Franksen, Benjamin's avatar
Franksen, Benjamin committed
21
22
23
24
25
use strict;
use lib "/opt/Epics/R3.14.12/base/3-14-12-1-1/lib/perl";
use Getopt::Long;
use EPICS::Release;

26
my $startdir = $ENV{PWD};
Franksen, Benjamin's avatar
Franksen, Benjamin committed
27
28
my $mindepth = 2;
my $maxdepth = 3;
29
my $include = '.*/\([0-9]+-\)+\(bessy\|snapshot\)?[0-9]+';
Franksen, Benjamin's avatar
Franksen, Benjamin committed
30
31
my $exclude = '*/mba-templates/*';
my $opt_clean = 0;
32
my $opt_clean_only = 0;
33
my $jobs;
34
my $opt_list = 0;
Franksen, Benjamin's avatar
Franksen, Benjamin committed
35
36
my $opt_dryrun = 0;
my $opt_quiet = 0;
37
my $opt_debug = 0;
Franksen, Benjamin's avatar
Franksen, Benjamin committed
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
my $opt_help = 0;

sub HELP_MESSAGE {
    print STDERR <<EOF;
Usage: build.pl options
Find EPICS support modules and build them in the correct dependency order.
Options are:
 -s --startdir=DIR  Start directory (default: $startdir)
 -m --mindepth=NUM  Minimum depth to search directory tree (default: $mindepth)
 -M --maxdepth=NUM  Maximum depth to search directory tree (default: $maxdepth)
 -i --include=REGEX Include (only) paths matching this regex pattern
                    (default: $include)
 -e --exclude=GLOB  Exclude paths matching this glob pattern
                    (default: $exclude)
 -c --clean         Make clean before building
53
54
55
 -C --clean-only    Only make clean, don't build
 -j --jobs[=NUM]    Number of jobs to run simultaneously
 -l --list          List directories in dependency order
Franksen, Benjamin's avatar
Franksen, Benjamin committed
56
57
 -n --dryrun        Do nothing, just say what would be done
 -q --quiet         Don't say what is being done
58
 -d --debug         Output debug messages
59
 -h --help          Display this help message
Franksen, Benjamin's avatar
Franksen, Benjamin committed
60
61
62
EOF
}

63
Getopt::Long::Configure ("bundling");
64
Getopt::Long::Configure ("no_ignore_case");
Franksen, Benjamin's avatar
Franksen, Benjamin committed
65
66
67
68
69
70
71
GetOptions(
  "s|startdir=s"  => \$startdir,
  "m|mindepth=i"  => \$mindepth,
  "M|maxdepth=i"  => \$maxdepth,
  "i|include=s"   => \$include,
  "e|exclude=s"   => \$exclude,
  "c|clean"       => \$opt_clean,
72
73
74
  "C|clean-only"  => \$opt_clean_only,
  "j|jobs:s"      => \$jobs,
  "l|list"        => \$opt_list,
Franksen, Benjamin's avatar
Franksen, Benjamin committed
75
76
  "n|dryrun"      => \$opt_dryrun,
  "q|quiet"       => \$opt_quiet,
77
  "d|debug"       => \$opt_debug,
Franksen, Benjamin's avatar
Franksen, Benjamin committed
78
79
80
81
82
  "h|help"        => \$opt_help,
) or HELP_MESSAGE() && exit 2;

HELP_MESSAGE() && exit 0 if ($opt_help);

83
if (defined $jobs and ($jobs > 0 or $jobs eq "")) {
84
85
86
87
88
  $jobs = "j$jobs";
} else {
  $jobs = "";
}

89
our $pipe;
Franksen, Benjamin's avatar
Franksen, Benjamin committed
90

91
92
93
open($pipe,'-|',"find",$startdir,
  "-mindepth",$mindepth,"-maxdepth",$maxdepth,"-regex",$include,
  "-not","-path",$exclude,"-type","d");
94

95
96
97
98
my @tops = <$pipe>;

print for (@tops);
exit;
Franksen, Benjamin's avatar
Franksen, Benjamin committed
99

100
die unless $? == 0;
Franksen, Benjamin's avatar
Franksen, Benjamin committed
101
102
103
104

my %deps = ();

foreach my $top (@tops) {
105
  chomp $top;
Franksen, Benjamin's avatar
Franksen, Benjamin committed
106
107
108
109
110
111
  #print "top = $top\n";

  my %macros = ();
  my @apps   = ();

  my $relfile = "$top/configure/RELEASE";
112
113
114
115
116
  unless (-f $relfile) {
    @tops = grep !/$top/, @tops;
    warn "Can't find $relfile\n";
    next;
  }
Franksen, Benjamin's avatar
Franksen, Benjamin committed
117
118
119
120
121
122
123
  readReleaseFiles($relfile, \%macros, \@apps, undef);
  expandRelease(\%macros, \@apps);

  delete $macros{TOP};
  delete $macros{TEMPLATE_TOP};
  delete $macros{SUPPORT};
  delete $macros{EPICS_SUPPORT};
124
125
126
127
128
  delete $macros{EPICS_BASE};

  # initialize in case there are no dependencies
  $deps{$top} = {};
  print "$top:\n" if $opt_debug;
Franksen, Benjamin's avatar
Franksen, Benjamin committed
129

130
  # build dependency graph
Franksen, Benjamin's avatar
Franksen, Benjamin committed
131
132
133
  foreach my $app (@apps) {
    my $dep = $macros{$app};
    if (-d $dep) {
134
135
      print "  $dep\n" if $opt_debug;
      $deps{$top}->{$dep} = 1;
Franksen, Benjamin's avatar
Franksen, Benjamin committed
136
137
138
139
140
141
142
143
144
    }
  }
}

my %mark = ();
my %done = ();

sub make {
  my ($top) = @_;
145
146
147
148
149
150
151
152
153
  if (not $done{$top}) {
    if ($mark{$top}) {
      die "circular dependency: $top";
    }
    $mark{$top} = 1;
    my $topdeps = $deps{$top};
    foreach my $dep (sort(keys(%$topdeps))) {
        make($dep);
    }
154
    my $cmd = "make -s$jobs -C $top";
Franksen, Benjamin's avatar
Franksen, Benjamin committed
155
    if ($opt_clean) {
156
157
158
159
      $cmd = "make -s$jobs -C $top distclean && $cmd";
    }
    if ($opt_clean_only) {
      $cmd = "make -s$jobs -C $top distclean";
Franksen, Benjamin's avatar
Franksen, Benjamin committed
160
    }
161
162
163
    if ($opt_list) {
      print "$top\n";
    } elsif ($opt_dryrun) {
Franksen, Benjamin's avatar
Franksen, Benjamin committed
164
      print "$cmd\n";
165
    } else {
166
      print "building $top ...\n" if not $opt_quiet;
Franksen, Benjamin's avatar
Franksen, Benjamin committed
167
168
169
      system($cmd);
      die unless $? == 0;
    }
170
    $done{$top} = 1;
Franksen, Benjamin's avatar
Franksen, Benjamin committed
171
172
173
  }
}

174
175
foreach my $tgt (@tops) {
  make($tgt);
Franksen, Benjamin's avatar
Franksen, Benjamin committed
176
177
  %mark = ();
}