Gentoo calls 'w64' a mingw flavour with mingw-w64 runtime.
[ghc.git] / boot
1 #!/usr/bin/perl -w
2
3 use strict;
4
5 use Cwd;
6 use File::Path 'rmtree';
7 use File::Basename;
8
9 my %required_tag;
10 my $validate;
11 my $curdir;
12
13 $required_tag{"-"} = 1;
14 $validate = 0;
15
16 $curdir = &cwd()
17     or die "Can't find current directory: $!";
18
19 while ($#ARGV ne -1) {
20     my $arg = shift @ARGV;
21
22     if ($arg =~ /^--required-tag=(.*)/) {
23         $required_tag{$1} = 1;
24     }
25     elsif ($arg =~ /^--validate$/) {
26         $validate = 1;
27     }
28     else {
29         die "Bad arg: $arg";
30     }
31 }
32
33 sub sanity_check_line_endings {
34     local $/ = undef;
35     open FILE, "packages" or die "Couldn't open file: $!";
36     binmode FILE;
37     my $string = <FILE>;
38     close FILE;
39
40     if ($string =~ /\r/) {
41         print STDERR <<EOF;
42 Found ^M in packages.
43 Perhaps you need to run
44     git config --global core.autocrlf false
45 and re-check out the tree?
46 EOF
47         exit 1;
48     }
49 }
50
51 sub sanity_check_tree {
52     my $tag;
53     my $dir;
54
55     # Check that we have all boot packages.
56     open PACKAGES, "< packages";
57     while (<PACKAGES>) {
58         if (/^#/) {
59             # Comment; do nothing
60         }
61         elsif (/^([a-zA-Z0-9\/.-]+) +([^ ]+) +[^ ]+ +[^ ]+$/) {
62             $dir = $1;
63             $tag = $2;
64
65             # If $tag is not "-" then it is an optional repository, so its
66             # absence isn't an error.
67             if (defined($required_tag{$tag})) {
68                 # We would like to just check for a .git directory here,
69                 # but in an lndir tree we avoid making .git directories,
70                 # so it doesn't exist. We therefore require that every repo
71                 # has a LICENSE file instead.
72                 if (! -f "$dir/LICENSE") {
73                     print STDERR "Error: $dir/LICENSE doesn't exist.\n";
74                     die "Maybe you haven't done './sync-all get'?";
75                 }
76             }
77         }
78         else {
79             die "Bad line in packages file: $_";
80         }
81     }
82     close PACKAGES;
83 }
84
85 # Create libraries/*/{ghc.mk,GNUmakefile}
86 sub boot_pkgs {
87     my @library_dirs = ();
88
89     my $package;
90
91     for $package (glob "libraries/*/") {
92         $package =~ s/\/$//;
93         my $pkgs = "$package/ghc-packages";
94         if (-f $pkgs) {
95             open PKGS, "< $pkgs"
96                 or die "Failed to open $pkgs: $!";
97             while (<PKGS>) {
98                 chomp;
99                 s/\r//g;
100                 if (/.+/) {
101                     push @library_dirs, "$package/$_";
102                 }
103             }
104         }
105         else {
106             push @library_dirs, $package;
107         }
108     }
109
110     for $package (@library_dirs) {
111         my $dir = &basename($package);
112         my @cabals = glob("$package/*.cabal");
113         if ($#cabals > 0) {
114             die "Too many .cabal file in $package\n";
115         }
116         if ($#cabals eq 0) {
117             my $cabal = $cabals[0];
118             my $pkg;
119             my $top;
120             if (-f $cabal) {
121                 $pkg = $cabal;
122                 $pkg =~ s#.*/##;
123                 $pkg =~ s/\.cabal$//;
124                 $top = $package;
125                 $top =~ s#[^/]+#..#g;
126                 $dir = $package;
127                 $dir =~ s#^libraries/##g;
128
129                 print "Creating $package/ghc.mk\n";
130                 open GHCMK, "> $package/ghc.mk"
131                     or die "Opening $package/ghc.mk failed: $!";
132                 print GHCMK "${package}_PACKAGE = ${pkg}\n";
133                 print GHCMK "${package}_dist-install_GROUP = libraries\n";
134                 print GHCMK "\$(if \$(filter ${dir},\$(PKGS_THAT_BUILD_WITH_STAGE0)),\$(eval \$(call build-package,${package},dist-boot,0)))\n";
135                 print GHCMK "\$(eval \$(call build-package,${package},dist-install,\$(if \$(filter ${dir},\$(PKGS_THAT_BUILD_WITH_STAGE2)),2,1)))\n";
136                 close GHCMK
137                     or die "Closing $package/ghc.mk failed: $!";
138
139                 print "Creating $package/GNUmakefile\n";
140                 open GNUMAKEFILE, "> $package/GNUmakefile"
141                     or die "Opening $package/GNUmakefile failed: $!";
142                 print GNUMAKEFILE "dir = ${package}\n";
143                 print GNUMAKEFILE "TOP = ${top}\n";
144                 print GNUMAKEFILE "include \$(TOP)/mk/sub-makefile.mk\n";
145                 print GNUMAKEFILE "FAST_MAKE_OPTS += stage=0\n";
146                 close GNUMAKEFILE
147                     or die "Closing $package/GNUmakefile failed: $!";
148             }
149         }
150     }
151 }
152
153 # autoreconf everything that needs it.
154 sub autoreconf {
155     my $dir;
156
157     foreach $dir (".", glob("libraries/*/")) {
158         if (-f "$dir/configure.ac") {
159             print "Booting $dir\n";
160             chdir $dir or die "can't change to $dir: $!";
161             system("autoreconf") == 0
162                 or die "Running autoreconf failed with exitcode $?";
163             chdir $curdir or die "can't change to $curdir: $!";
164         }
165     }
166 }
167
168 sub checkBuildMk {
169     if ($validate eq 0 && ! -f "mk/build.mk") {
170         print <<EOF;
171
172 WARNING: You don't have a mk/build.mk file.
173
174 By default a standard GHC build will be done, which uses optimisation
175 and builds the profiling libraries. This will take a long time, so may
176 not be what you want if you are developing GHC or the libraries, rather
177 than simply building it to use it.
178
179 For information on creating a mk/build.mk file, please see:
180     http://hackage.haskell.org/trac/ghc/wiki/Building/Using#Buildconfiguration
181
182 EOF
183     }
184 }
185
186 &sanity_check_line_endings();
187 &sanity_check_tree();
188 &boot_pkgs();
189 &autoreconf();
190 &checkBuildMk();
191