[29481] | 1 | #!/usr/bin/env perl
|
---|
| 2 |
|
---|
| 3 | # Generates Makefiles for different systems and packages
|
---|
| 4 | # Uses a hashmap to do config variables (see readvar for how variables are
|
---|
| 5 | # read in and an example of how they are resolved / used)
|
---|
| 6 |
|
---|
| 7 | use strict;
|
---|
| 8 | use warnings;
|
---|
| 9 | use utf8;
|
---|
| 10 | use File::Basename;
|
---|
| 11 | use File::Path 'make_path';
|
---|
[29508] | 12 | use File::Copy 'cp';
|
---|
[29481] | 13 | use Storable 'dclone';
|
---|
[29508] | 14 | use Digest::MD5;
|
---|
[29481] | 15 |
|
---|
[29508] | 16 |
|
---|
[29481] | 17 | my $USAGE = "Usage: " . basename($0) . " <platforms> <packages>
|
---|
[29508] | 18 | platforms: A comma separated list of the platforms defined in platforms/
|
---|
[29481] | 19 | Or 'all' (for all platforms)
|
---|
[29508] | 20 | packages: A comma separated list of the packages defined in packages/
|
---|
| 21 | Or 'all' (for all packages)
|
---|
[29481] | 22 | ";
|
---|
| 23 |
|
---|
| 24 | $#ARGV == 1 or die $USAGE;
|
---|
| 25 |
|
---|
| 26 | sub globbify {
|
---|
| 27 | my ($dir, $files) = @_;
|
---|
| 28 | $files =~ /^all$/i and return glob "$dir/*";
|
---|
| 29 | my @list = glob "$dir/{$files}";
|
---|
| 30 | for (@list) {
|
---|
| 31 | -f or die "Could not find '", $_, "'";
|
---|
| 32 | }
|
---|
| 33 | return @list;
|
---|
| 34 | }
|
---|
| 35 |
|
---|
[29508] | 36 | sub empty {
|
---|
| 37 | /^\s*$/ and return 1;
|
---|
| 38 | }
|
---|
| 39 |
|
---|
| 40 | sub comment {
|
---|
| 41 | /^\s*#/ and return 1;
|
---|
| 42 | }
|
---|
| 43 |
|
---|
| 44 | sub trim {
|
---|
| 45 | for (@_) {
|
---|
| 46 | s/^\s+|\s+$//g;
|
---|
| 47 | }
|
---|
| 48 | return @_;
|
---|
| 49 | }
|
---|
| 50 |
|
---|
| 51 | sub copydir {
|
---|
| 52 | my ($src, $dst, $subst) = @_;
|
---|
| 53 | mkdir $dst;
|
---|
| 54 | opendir my $DIRFH, $src or die "Could not open '$src': $!";
|
---|
| 55 | while (readdir $DIRFH) {
|
---|
| 56 | next if ($_ eq '.' or $_ eq '..');
|
---|
| 57 | print " - $dst/$_\n";
|
---|
| 58 | if (-d "$src/$_") {
|
---|
| 59 | # copy folder
|
---|
| 60 | copydir ("$src/$_", "$dst/$_", $subst);
|
---|
| 61 | } elsif (-B "$src/$_") {
|
---|
| 62 | # copy binary file
|
---|
| 63 | cp "$src/$_", "$dst/$_" or die "Failed to copy '$_': $!";
|
---|
| 64 | } else {
|
---|
| 65 | # copy normal file
|
---|
| 66 | my $newFile = "$dst/$_";
|
---|
| 67 | open OUT, '>', $newFile
|
---|
| 68 | or die "Failed to open '$_' for writing: $!";
|
---|
| 69 | open IN, '<', "$src/$_"
|
---|
| 70 | or die "Failed to open '$_' for reading: $!";
|
---|
| 71 | while (<IN>) {
|
---|
| 72 | s/@([\w]+)@/$subst->{$1}/g;
|
---|
| 73 | print OUT;
|
---|
| 74 | }
|
---|
| 75 | my $perms = (stat IN)[2] & 07777;
|
---|
| 76 | close IN;
|
---|
| 77 | close OUT;
|
---|
| 78 | chmod ($perms | 0600, $newFile);
|
---|
| 79 | }
|
---|
| 80 | }
|
---|
| 81 | closedir $DIRFH;
|
---|
| 82 | }
|
---|
| 83 |
|
---|
| 84 | my %escape = (
|
---|
| 85 | "n" => "\n",
|
---|
| 86 | "\\" => "\\",
|
---|
| 87 | " " => " "
|
---|
| 88 | );
|
---|
| 89 |
|
---|
[29481] | 90 | sub readvar {
|
---|
| 91 | my ($vars, $line) = @_;
|
---|
[29508] | 92 | my ($var, $val) = trim (split ":", $line, 2);
|
---|
[29481] | 93 | defined $var and defined $val or die "Invalid variable assignment: '$line'";
|
---|
[29508] | 94 | local $/ = '';
|
---|
| 95 | $val =~ s/\\([ \\n]|$)/$escape{$1}/g;
|
---|
| 96 | $val =~ s/@([\w]+)@/$vars->{$1}/g;
|
---|
[29481] | 97 | $vars->{$var} = $val;
|
---|
| 98 | }
|
---|
| 99 |
|
---|
[29508] | 100 | sub addsource {
|
---|
| 101 | my ($vars, $source) = @_;
|
---|
| 102 | my $md5 = Digest::MD5->new;
|
---|
| 103 | open my $MD5FH, '<', $source;
|
---|
| 104 | binmode $MD5FH;
|
---|
| 105 | $md5->addfile ($MD5FH);
|
---|
| 106 | my $field_separator = $vars->{'FIELD_SEPARATOR'};
|
---|
| 107 | $vars->{'SOURCES'} .= $field_separator . basename($source);
|
---|
| 108 | $vars->{'SOURCE_SUMS'} .= $field_separator . $md5->hexdigest;
|
---|
| 109 | close $MD5FH;
|
---|
| 110 | }
|
---|
[29481] | 111 |
|
---|
[29508] | 112 | my @platforms = globbify "platforms", shift;
|
---|
| 113 | my @packages = globbify "packages", shift;
|
---|
| 114 |
|
---|
[29481] | 115 | for (@platforms) {
|
---|
[29508] | 116 | my $platform = basename $_;
|
---|
| 117 | print "$platform\n";
|
---|
| 118 |
|
---|
| 119 | open PLATFORM, '<', $_;
|
---|
| 120 | my %platform_vars;
|
---|
| 121 | while (<PLATFORM>) {
|
---|
[29481] | 122 | chomp;
|
---|
[29508] | 123 | (comment or empty) and next;
|
---|
[29481] | 124 | readvar \%platform_vars, $_;
|
---|
| 125 | }
|
---|
[29508] | 126 | close PLATFORM;
|
---|
[29481] | 127 |
|
---|
| 128 | for (@packages) {
|
---|
[29508] | 129 | my $package = basename $_;
|
---|
| 130 | print " - $package\n";
|
---|
[29481] | 131 | my $package_path = "build/$platform/$package";
|
---|
| 132 | make_path $package_path;
|
---|
| 133 |
|
---|
[29508] | 134 | open PACKAGE, '<', $_;
|
---|
| 135 | my %package_vars = %{dclone \%platform_vars};
|
---|
| 136 | while (<PACKAGE>) {
|
---|
[29481] | 137 | chomp;
|
---|
[29508] | 138 | empty and last;
|
---|
| 139 | comment and next;
|
---|
| 140 | readvar \%package_vars, $_;
|
---|
[29481] | 141 | }
|
---|
[29508] | 142 | for (keys %package_vars) {
|
---|
| 143 | defined $package_vars{$_} or $package_vars{$_} = ' ';
|
---|
| 144 | # print "$_ = $package_vars{$_}\n";
|
---|
| 145 | }
|
---|
[29481] | 146 |
|
---|
[29508] | 147 | while (<PACKAGE>) {
|
---|
[29481] | 148 | chomp;
|
---|
[29508] | 149 | empty and last;
|
---|
| 150 | comment and next;
|
---|
| 151 | cp "files/$_", "$package_path/$_" or die "Failed to copy '$_': $!";
|
---|
| 152 | addsource \%package_vars, "$package_path/$_";
|
---|
[29481] | 153 | }
|
---|
[29508] | 154 |
|
---|
| 155 | # write the makefile
|
---|
[29481] | 156 | my $outfile = "$package_path/Makefile";
|
---|
[29508] | 157 | print " - $outfile\n";
|
---|
| 158 | open MAKEFILE, '>', $outfile
|
---|
| 159 | or die "Failed to open '$outfile' for writing: $!";
|
---|
| 160 | while (<PACKAGE>) {
|
---|
[29481] | 161 | chomp;
|
---|
[29508] | 162 | empty and last;
|
---|
| 163 | comment and next;
|
---|
| 164 | open IN, '<', "segments/$_"
|
---|
| 165 | or die "Failed to open '$_' for reading: $!";
|
---|
| 166 | while (<IN>) {
|
---|
| 167 | s/@([\w]+)@/$package_vars{$1}/g;
|
---|
| 168 | print MAKEFILE;
|
---|
[29481] | 169 | }
|
---|
[29508] | 170 | close IN;
|
---|
[29481] | 171 | }
|
---|
[29508] | 172 | close MAKEFILE;
|
---|
| 173 | close PACKAGE;
|
---|
| 174 | addsource \%package_vars, $outfile;
|
---|
| 175 |
|
---|
| 176 | # write the package manager files
|
---|
| 177 | copydir ("managers/$platform_vars{'MANAGER'}", $package_path, \%package_vars);
|
---|
[29481] | 178 | }
|
---|
| 179 | }
|
---|