| #!/usr/bin/perl |
| |
| use strict; |
| use Data::Dumper; |
| use Getopt::Std; |
| use IO::File; |
| our %opts = (d => 'size-tests'); |
| |
| # default arguments go here |
| my @sets = |
| ({ |
| "with-defaults" => '', |
| }); |
| |
| my %base_args = %{$sets[0]}; |
| my ($basename, $basenum); |
| |
| getopts('t:hlcD:nj:o:eb:T', \%opts) || usage(); |
| |
| $opts{'j'} = "-j$opts{j}" if (exists($opts{'j'})); |
| |
| usage() if ($opts{'h'}); |
| |
| my @argumentsets = |
| ( |
| { |
| title => 'security-types', |
| arguments => |
| { |
| usm => { |
| 'with-security-modules' => 'usm', |
| }, |
| dtlsandtls => { |
| 'with-security-modules' => 'tsm', |
| 'with-out-security-modules' => 'usm', |
| 'with-transports' => 'DTLSUDP TLSTCP', |
| 'with-mib-modules' => 'tlstm-mib tsm-mib' |
| }, |
| usmanddtlsandtls => { |
| 'with-security-modules' => 'tsm usm', |
| 'with-transports' => 'DTLSUDP TLSTCP', |
| 'with-mib-modules' => 'tlstm-mib tsm-mib' |
| } |
| } |
| }, |
| { |
| title => 'minimalist', |
| arguments => |
| { |
| minimal => { |
| 'enable-minimalist' => '', |
| }, |
| 'not-minimal' => { |
| } |
| } |
| }, |
| { |
| title => 'mib-loading', |
| arguments => |
| { |
| 'without-mib-loading' => { |
| 'disable-mib-loading' => '', |
| }, |
| 'with-mib-loading' => { |
| } |
| } |
| }, |
| { |
| title => 'debugging', |
| arguments => |
| { |
| 'without-debugging' => { |
| 'disable-debugging' => '', |
| }, |
| 'with-debugging' => { |
| } |
| } |
| }, |
| { |
| title => 'logging', |
| arguments => |
| { |
| 'without-logging' => { |
| 'with-out-features' => 'logging', |
| }, |
| 'with-logging' => { |
| } |
| } |
| }, |
| { |
| title => 'agent-mibs', |
| arguments => |
| { |
| 'full-agent' => { |
| }, |
| 'mini-agent' => { |
| 'enable-mini-agent' => '', |
| } |
| } |
| }, |
| { |
| title => 'protocol-support', |
| arguments => |
| { |
| 'everything' => { |
| }, |
| 'read-only' => { |
| 'enable-read-only' => '', |
| }, |
| 'notify-only' => { |
| 'enable-notify-only' => '', |
| } |
| } |
| }, |
| { |
| title => 'perl', |
| arguments => |
| { |
| 'without-perl-modules' => { |
| 'without-perl-modules' => '', |
| 'disable-embedded-perl' => '', |
| }, |
| 'with-perl-no-embedding' => { |
| 'with-perl-modules' => '', |
| 'disable-embedded-perl' => '', |
| }, |
| 'with-perl-and-embedding' => { |
| 'with-perl-modules' => '', |
| 'enable-embedded-perl' => '', |
| } |
| } |
| }, |
| ); |
| |
| # map these to a referencable lookup hash |
| my %argumentsets; |
| foreach my $set (@argumentsets) { |
| $argumentsets{$set->{'title'}} = $set; |
| } |
| |
| if ($opts{'l'}) { |
| print "Types available:\n"; |
| printf(" %-40.40s %s\n", "Test Title", "Number of subtests"); |
| printf(" %-40.40s %s\n", "-" x 39, "-" x length("Number of subtests")); |
| foreach my $type (@argumentsets) { |
| my @keys = keys(%{$type->{'arguments'}}); |
| printf(" %-40.40s %s\n", $type->{'title'}, $#keys+1); |
| } |
| exit; |
| } |
| |
| my %types; |
| if ($opts{'t'}) { |
| my @types = split(/,\s*/, $opts{'t'}); |
| foreach my $type (@types) { |
| $types{$type} = 1; |
| } |
| } |
| |
| if ($opts{'b'}) { |
| # use this set as the base default set of arguments |
| ($basename, $basenum) = ($opts{'b'} =~ /(.*):(\d+)/); |
| if (!exists($argumentsets{$basename})) { |
| printf STDERR "failed to find set for -b argument: %s\n", $basename; |
| exit(1); |
| } |
| @sets = add_in_flags($argumentsets{$basename}, \%base_args, ()); |
| @sets = @sets[$basenum]; |
| %base_args = %{$sets[0]}; |
| } |
| |
| foreach my $set (@argumentsets) { |
| if (!$opts{'t'} || exists($types{$set->{'title'}})) { |
| if ($basename && $set->{'title'} eq $basename) { |
| next; |
| } |
| @sets = add_in_flags($set, \%base_args, @sets); |
| } |
| } |
| |
| if ($opts{'c'}) { |
| # print the configure flags |
| foreach my $set (@sets) { |
| print "$set->{'title'}:\n"; |
| print " ", generate_configure_flags($set), "\n"; |
| } |
| exit; |
| } |
| |
| my $summaryfile; |
| if ($opts{'o'} && !$opts{'n'}) { |
| $summaryfile = new IO::File; |
| $summaryfile->open(">$opts{o}"); |
| } |
| |
| my $count = 0; |
| foreach my $set (@sets) { |
| $count++; |
| build_set($count, $set); |
| } |
| |
| sub add_in_flags { |
| my ($argumentset, $base_flags, @current_flags) = @_; |
| |
| my @new_flags; |
| |
| # do a linear search of the options |
| if (! $opts{'e'}) { |
| @new_flags = @current_flags; |
| foreach my $newargs (keys(%{$argumentset->{'arguments'}})) { |
| my %flags = %$base_flags; |
| |
| $flags{'title'} = "$flags{'title'}:$newargs"; |
| |
| foreach my $newflag (keys(%{$argumentset->{'arguments'}{$newargs}})) { |
| |
| $flags{$newflag} .= " $argumentset->{'arguments'}{$newargs}{$newflag}"; |
| } |
| push @new_flags, \%flags; |
| } |
| return @new_flags; |
| } |
| |
| # or an exponential search |
| foreach my $flags (@current_flags) { |
| foreach my $newargs (keys(%{$argumentset->{'arguments'}})) { |
| my %flags = %{$flags}; # copy the existing hash-set of flags |
| |
| if (exists($flags{'title'})) { |
| $flags{'title'} .= ", $newargs"; |
| } else { |
| $flags{'title'} .= "$newargs"; |
| } |
| foreach my $newflag (keys(%{$argumentset->{'arguments'}{$newargs}})) { |
| |
| $flags{$newflag} .= " $argumentset->{'arguments'}{$newargs}{$newflag}"; |
| } |
| |
| push @new_flags, \%flags; |
| } |
| } |
| |
| return @new_flags; |
| } |
| |
| sub generate_configure_flags { |
| my ($arguments) = @_; |
| my $line = ""; |
| foreach my $arg (keys(%$arguments)) { |
| next if ($arg eq 'title'); |
| if ($arguments->{$arg} =~ /^\s*$/) { |
| $line .= " --$arg"; |
| } else { |
| $line .= " --$arg=\"$arguments->{$arg}\""; |
| } |
| } |
| return $line; |
| } |
| |
| sub build_set { |
| my ($num, $arguments) = @_; |
| |
| $num = sprintf("%03d", $num); |
| |
| my $file; |
| |
| if (!$opts{'n'}) { |
| mkdir $opts{'d'} if (! -d $opts{'d'}); |
| die "failed to create the $opts{'d'} directory" if (! -d $opts{'d'}); |
| |
| $file = new IO::File; |
| $file->open(">$opts{'d'}/$num-0-cmd-summary"); |
| $file->print("Creating output for: $arguments->{'title'}\n"); |
| } |
| |
| print "==================== $arguments->{'title'}\n"; |
| |
| |
| System ($file, $num, "1-distclean", "make distclean"); |
| System ($file, $num, "2-configure", |
| "./configure " . generate_configure_flags($arguments)); |
| System ($file, $num, "3-features", "make features"); |
| System ($file, $num, "4-make", "make $opts{'j'}"); |
| System ($file, $num, "5-unused-code", "perl local/minimalist/find-unused-code -g"); |
| System ($file, $num, "6-testing", "make -C testing test") if ($opts{'T'}); |
| |
| if (!$opts{'n'}) { |
| analyze_size($arguments->{'title'}, "$opts{'d'}/$num-9-results"); |
| } |
| } |
| |
| sub analyze_size { |
| my ($title, $filename) = @_; |
| |
| my $outfile = new IO::File; |
| $outfile->open(">$filename"); |
| |
| print "Results for: $title\n"; |
| printf $outfile "Results for: $title\n"; |
| printf ("%-50.50s %10s\n", "-" x 49, "-" x 10); |
| printf $outfile ("%-50.50s %10s\n", "-" x 49, "-" x 10); |
| |
| my $totalsize = 0; |
| foreach my $buildfile (glob("snmplib/.libs/lib*.so.*.0.0"), |
| glob("agent/.libs/lib*.so.*.0.0"), |
| "agent/.libs/snmpd") { |
| |
| my @info = stat($buildfile); |
| printf $outfile ("%-50.50s %10s\n", $buildfile, $info[7]); |
| printf("%-50.50s %10s\n", $buildfile, $info[7]); |
| $totalsize += $info[7]; |
| } |
| printf $outfile ("%-50.50s %10s\n", "-" x 49, "-" x 10); |
| printf $outfile ("%-50.50s %10s bytes\n", "TOTAL", $totalsize); |
| |
| printf("%-50.50s %10s\n", "-" x 49, "-" x 10); |
| printf("%-50.50s %10s bytes\n", "TOTAL", $totalsize); |
| |
| if (defined($summaryfile)) { |
| my $restricted_title = $title; |
| $restricted_title =~ s/[^a-zA-Z]/_/g; |
| printf $summaryfile "%10s %s \n", $totalsize, $title; |
| } |
| |
| return $totalsize; |
| } |
| |
| sub usage { |
| print "Usage: $0 [FLAGS]\n\n"; |
| print "FLAGS:\n"; |
| print " -h\t\thelp\n"; |
| print " -t TYPES\tSelect types to analyze (default = all)\n"; |
| print " -l\t\tList available types\n"; |
| print " -c\t\tPrint the configuration flags that would be used\n"; |
| print " -D DIR\tSave data results to this directory\n"; |
| print " -o FILE\tSave a complete summary chart to FILE\n"; |
| print " -n\t\tDry run -- only show the commands to execute\n"; |
| print " -j NUM\tExecute make with parallel building (-jNUM)\n"; |
| print " -e\t\tUse exponential expansion (all combos) of the requested options\n"; |
| print " -b NAME:NUM\tUse NAME and the NUM'th set as the base arguments to start from\n"; |
| print " -T\t\tRun 'make test' at each step as well\n"; |
| exit; |
| } |
| |
| sub System { |
| my $file = shift; |
| my $num = shift; |
| my $title = shift; |
| my $pipe = " 2>&1 | tee $opts{'d'}/$num-$title.out\n"; |
| |
| print "### ", join(" ", @_), $pipe; |
| if (!$opts{'n'} && $file) { |
| print $file "### ", join(" ", @_), "\n"; |
| } |
| |
| if (!$opts{'n'}) { |
| system(join(" ", @_) . $pipe); |
| } |
| } |