boot 5.47 KB
Newer Older
1
#!/usr/bin/env perl
2

3
use warnings;
4 5 6
use strict;

use Cwd;
Ian Lynagh's avatar
Ian Lynagh committed
7 8
use File::Path 'rmtree';
use File::Basename;
9

10
my %required_tag;
11
my $validate;
Ian Lynagh's avatar
Ian Lynagh committed
12
my $curdir;
13 14

$required_tag{"-"} = 1;
15
$validate = 0;
16

Ian Lynagh's avatar
Ian Lynagh committed
17 18 19
$curdir = &cwd()
    or die "Can't find current directory: $!";

20 21 22 23 24 25
while ($#ARGV ne -1) {
    my $arg = shift @ARGV;

    if ($arg =~ /^--required-tag=(.*)/) {
        $required_tag{$1} = 1;
    }
26 27 28
    elsif ($arg =~ /^--validate$/) {
        $validate = 1;
    }
29 30 31
    else {
        die "Bad arg: $arg";
    }
32 33
}

Ian Lynagh's avatar
Ian Lynagh committed
34
sub sanity_check_line_endings {
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
    local $/ = undef;
    open FILE, "packages" or die "Couldn't open file: $!";
    binmode FILE;
    my $string = <FILE>;
    close FILE;

    if ($string =~ /\r/) {
        print STDERR <<EOF;
Found ^M in packages.
Perhaps you need to run
    git config --global core.autocrlf false
and re-check out the tree?
EOF
        exit 1;
    }
50 51
}

Ian Lynagh's avatar
Ian Lynagh committed
52 53 54
sub sanity_check_tree {
    my $tag;
    my $dir;
55

Ian Lynagh's avatar
Ian Lynagh committed
56 57 58 59 60 61
    # Check that we have all boot packages.
    open PACKAGES, "< packages";
    while (<PACKAGES>) {
        if (/^#/) {
            # Comment; do nothing
        }
62
        elsif (/^([a-zA-Z0-9\/.-]+) +([^ ]+) +[^ ]+ +[^ ]+$/) {
Ian Lynagh's avatar
Ian Lynagh committed
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
            $dir = $1;
            $tag = $2;

            # If $tag is not "-" then it is an optional repository, so its
            # absence isn't an error.
            if (defined($required_tag{$tag})) {
                # We would like to just check for a .git directory here,
                # but in an lndir tree we avoid making .git directories,
                # so it doesn't exist. We therefore require that every repo
                # has a LICENSE file instead.
                if (! -f "$dir/LICENSE") {
                    print STDERR "Error: $dir/LICENSE doesn't exist.\n";
                    die "Maybe you haven't done './sync-all get'?";
                }
            }
        }
        else {
            die "Bad line in packages file: $_";
        }
    }
    close PACKAGES;
}
85

Ian Lynagh's avatar
Ian Lynagh committed
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
# Create libraries/*/{ghc.mk,GNUmakefile}
sub boot_pkgs {
    my @library_dirs = ();

    my $package;

    for $package (glob "libraries/*/") {
        $package =~ s/\/$//;
        my $pkgs = "$package/ghc-packages";
        if (-f $pkgs) {
            open PKGS, "< $pkgs"
                or die "Failed to open $pkgs: $!";
            while (<PKGS>) {
                chomp;
                s/\r//g;
                if (/.+/) {
                    push @library_dirs, "$package/$_";
                }
104 105
            }
        }
Ian Lynagh's avatar
Ian Lynagh committed
106 107 108
        else {
            push @library_dirs, $package;
        }
109
    }
Ian Lynagh's avatar
Ian Lynagh committed
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134

    for $package (@library_dirs) {
        my $dir = &basename($package);
        my @cabals = glob("$package/*.cabal");
        if ($#cabals > 0) {
            die "Too many .cabal file in $package\n";
        }
        if ($#cabals eq 0) {
            my $cabal = $cabals[0];
            my $pkg;
            my $top;
            if (-f $cabal) {
                $pkg = $cabal;
                $pkg =~ s#.*/##;
                $pkg =~ s/\.cabal$//;
                $top = $package;
                $top =~ s#[^/]+#..#g;
                $dir = $package;
                $dir =~ s#^libraries/##g;

                print "Creating $package/ghc.mk\n";
                open GHCMK, "> $package/ghc.mk"
                    or die "Opening $package/ghc.mk failed: $!";
                print GHCMK "${package}_PACKAGE = ${pkg}\n";
                print GHCMK "${package}_dist-install_GROUP = libraries\n";
135 136 137
                print GHCMK "\$(if \$(filter ${dir},\$(PACKAGES_STAGE0)),\$(eval \$(call build-package,${package},dist-boot,0)))\n";
                print GHCMK "\$(if \$(filter ${dir},\$(PACKAGES_STAGE1)),\$(eval \$(call build-package,${package},dist-install,1)))\n";
                print GHCMK "\$(if \$(filter ${dir},\$(PACKAGES_STAGE2)),\$(eval \$(call build-package,${package},dist-install,2)))\n";
Ian Lynagh's avatar
Ian Lynagh committed
138 139 140 141 142 143 144 145 146 147 148 149 150 151
                close GHCMK
                    or die "Closing $package/ghc.mk failed: $!";

                print "Creating $package/GNUmakefile\n";
                open GNUMAKEFILE, "> $package/GNUmakefile"
                    or die "Opening $package/GNUmakefile failed: $!";
                print GNUMAKEFILE "dir = ${package}\n";
                print GNUMAKEFILE "TOP = ${top}\n";
                print GNUMAKEFILE "include \$(TOP)/mk/sub-makefile.mk\n";
                print GNUMAKEFILE "FAST_MAKE_OPTS += stage=0\n";
                close GNUMAKEFILE
                    or die "Closing $package/GNUmakefile failed: $!";
            }
        }
152 153
    }
}
154

Ian Lynagh's avatar
Ian Lynagh committed
155
# autoreconf everything that needs it.
Ian Lynagh's avatar
Ian Lynagh committed
156 157 158 159 160 161 162 163 164 165 166
sub autoreconf {
    my $dir;

    foreach $dir (".", glob("libraries/*/")) {
        if (-f "$dir/configure.ac") {
            print "Booting $dir\n";
            chdir $dir or die "can't change to $dir: $!";
            system("autoreconf") == 0
                or die "Running autoreconf failed with exitcode $?";
            chdir $curdir or die "can't change to $curdir: $!";
        }
167 168
    }
}
169

Ian Lynagh's avatar
Ian Lynagh committed
170 171 172
sub checkBuildMk {
    if ($validate eq 0 && ! -f "mk/build.mk") {
        print <<EOF;
173 174 175 176 177 178 179 180 181

WARNING: You don't have a mk/build.mk file.

By default a standard GHC build will be done, which uses optimisation
and builds the profiling libraries. This will take a long time, so may
not be what you want if you are developing GHC or the libraries, rather
than simply building it to use it.

For information on creating a mk/build.mk file, please see:
182
    http://ghc.haskell.org/trac/ghc/wiki/Building/Using#Buildconfiguration
183 184

EOF
Ian Lynagh's avatar
Ian Lynagh committed
185
    }
186 187
}

Ian Lynagh's avatar
Ian Lynagh committed
188 189 190 191 192 193
&sanity_check_line_endings();
&sanity_check_tree();
&boot_pkgs();
&autoreconf();
&checkBuildMk();