root/Makefile.PL

Revision 22987, 9.5 kB (checked in by audreyt, 10 days ago)

* Support Cabal 1.6.0 (comes with GHC 6.10.1) in Makefile.PL.

  • Property svn:mime-type set to text/plain; charset=UTF-8
  • Property svn:eol-style set to native
  • Property svn:executable set to *
Line 
1#!/usr/bin/env perl
2
3use 5.006;
4use strict;
5use warnings;
6use FindBin;
7BEGIN { chdir $FindBin::RealBin };
8use inc::Module::Install;
9use lib 'inc';
10use Config;
11use File::Spec;
12use POSIX qw/uname/;
13
14# Hack to prevent recursive calls
15exit if @ARGV and $ARGV[0] =~ /^--with/;
16
17my ($ghc, $ghc_version, $ghc_flags, $ghc_pkg) = assert_ghc();
18
19my $setup_exe  = File::Spec->catfile('.', "Setup$Config{_exe}");
20
21rebuild_setup();
22my $app_dir = `$setup_exe -d`;
23chomp $app_dir;
24
25die "Cannot find application directory '$app_dir'; check to see if Setup.lhs compiles?\n"
26    unless $app_dir;
27
28my $bin_dir = File::Spec->catdir($app_dir, 'bin');
29my $cabal   = File::Spec->catfile($bin_dir, "cabal$Config{_exe}");
30my $cabal_config = File::Spec->catfile($app_dir, 'config');
31
32$ENV{PATH} = $bin_dir . $Config{path_sep} . $ENV{PATH};
33
34# First let's see if Cabal is there.
35print "*** Checking for Haskell dependencies...\n";
36print "[Automatic Installation]\n";
37
38my $rebuilt = 0;
39$rebuilt += bootstrap_with(Cabal            => qr/1\.[46-9]\./, '1.4.0');
40$rebuilt += bootstrap_with(parsec           => qr/2\./, '2.0');
41$rebuilt += bootstrap_with(network          => qr/[12]\./, '1.0');
42$rebuilt += bootstrap_with(HTTP             => qr/300[01]\./, '3000.0');
43$rebuilt += bootstrap_with(zlib             => qr/0\.(?:[4-9]|[1-9]\d)\./, '0.4');
44$rebuilt += bootstrap_with('cabal-install'  => qr/0\.(?:[5-9]|[1-9]\d)\..*9999/, '0.5.2.0.9999');
45
46if ($rebuilt) {
47    rebuild_setup();
48}
49
50print "[Pugs Dependencies]\n";
51
52my @deps = qw(
53    stm mtl time utf8-string binary haskeline FindBin MetaObject HsParrot
54    pugs-compat pugs-DrIFT stringtable-atom HsSyck control-timeout
55);
56
57# This line is here simply to trick Cabal into creating a default config file.
58delete $ENV{CABAL_CONFIG_FILE};
59my $rv = `$cabal list -v0 --installed --simple-output`;
60
61my $cabal_local_config = "$FindBin::RealBin/third-party/packages/config";
62
63# Ok, now we copy the config file to our tree.
64open IN, '<', $cabal_config or die "Impossible: $cabal_config not found?";
65open OUT, '>', $cabal_local_config;
66print OUT << ".";
67local-repos: "$FindBin::RealBin/third-party/packages/hackage.haskell.org"
68.
69while (<IN>) {
70    next if /^(?:local-)?repos:/;
71    print OUT $_;
72}
73close IN;
74close OUT;
75
76$ENV{CABAL_CONFIG_FILE} = $cabal_local_config;
77system($cabal => 'install', '--user', @deps);
78
79do "Configure.PL";
80print "==> Pugs configuration finished.\n";
81
82name            ('Perl6-Pugs');
83version_from    ('lib/Perl6/Pugs.pm');
84abstract_from   ('lib/Perl6/Pugs.pm');
85author          ('Audrey Tang <cpan@audreyt.org>');
86license         ('perl');
87install_script  ("pugs$Config{_exe}");
88install_script  ('script/pugscc');
89install_script  ('util/prove6');
90build_subdirs   (map fixpaths($_), grep {
91                   -f "$_/Makefile.PL" && not -l "$_/Makefile.PL"
92                 } glob("ext/*"), glob("docs/*")
93                );
94my $version = version();
95$version .= 0 until length($version) >= length('0.123456');
96$version =~ s{6\.(\d{3})(\d{3})?}{join '.', 6, int($1), int($2||0)}e;
97version($version);
98makemaker_args  (
99    test => { TESTS => "`perl t/spec/fudgeall pugs t/*/*.t t/*/*/*.t`" }, # , "perl5/*/t/*.t" },
100    MAN1PODS => {},
101);
102set_postamble   ();
103no_index        (
104    directory =>
105        qw< inc debian modules perl5 ext script util docs examples src >
106);
107sign            (1);
108WritePugs       (5);
109
110sub set_postamble {
111    unlink (my $build_config = 'current.build.yml');
112
113    my $find_ver = sub {
114        `$_[0] $_ 2>&1` =~ /(.* (?:version|build) .*)/i && return $1
115            for qw{--version -v -V -? /?};
116        return "unknown";
117    };
118    my $config = get_pugs_config(
119        uname               =>  join (" ", (uname)[0,2,4] ),
120        regex_engine        =>  ( $ENV{PUGS_REGEX_ENGINE} ?  $ENV{PUGS_REGEX_ENGINE} : 'default' ),
121        embed_flags         => 'noparrot nohaskell',
122#        embedded            =>  join (" ", ( $embed_flags =~ /HAVE_PERL5/ ?  $Config{perlpath} : 'noperl' ),
123#                                    ( $embed_flags =~ /HAVE_PARROT/
124#                                        ?  abs_path( File::Spec->catfile( "$ENV{PARROT_PATH}", "parrot" ) )
125#                                        : 'noparrot' ),
126#                                    ( $ENV{PUGS_EMBED} =~ /\bhaskell\b/ ?  $ghc : 'nohaskell' )
127#                                ),
128#        ghc                 =>  join (" ", [ assert_ghc() ]->[0], $ghc_version,
129#                                    ( $ghc_flags =~ /HAVE_READLINE/ ?  'readline' : 'noreadline' ),
130#                                    ( $ghc_flags =~ /HAVE_HSPLUGINS/ ?  'hsplugins' : 'nohsplugins' ),
131#                                    ( $threaded ? "threads" : "nothreads" ),
132#                                ),
133        ghc => 'noreadline nohsplugins nothreads',
134        cc                  =>  $find_ver->( $Config{cc} ),
135    );
136
137    {
138        # maybe move this to inc/PugsBuild/MiniYAML.pm ?
139        open my $fh, '>', $build_config or die "Cannot open $build_config for writing";
140        print $fh "# *** NOTE ***\n";
141        print $fh "# This file is generated during Makefile.PL.\n";
142        print $fh "# Changes will not persist after running Makefile.PL\n";
143        for ( sort keys %$config ) {
144            print $fh "$_: $config->{$_}\n";
145        }
146        close $fh;
147    }
148
149    my @srcdirs  = grep {-d} glob("src"), glob("src/*"), glob("src/*/*"), glob("src/*/*/*");
150    my @srcfiles = map { glob("$_/*.*hs") } @srcdirs;
151    push @srcfiles, map { glob("$_/*.*hs-boot") } @srcdirs;
152    push @srcfiles, map { map { substr($_, 0, -1) } glob("$_/*.*hsc") } @srcdirs;
153
154    my $version_h = "src/Pugs/pugs_version.h";
155    my $config_h = "src/Pugs/pugs_config.h";
156
157    my $EMBED_SMOP = ($ENV{PUGS_EMBED} // '') ? '--flags=SMOP' : '';
158    # Ok, now we have Cabal-Install and all the deps.  Let's be lazy and write a simple makefile.
159    postamble(<<".");
160pugs_requirements : @srcfiles $version_h $config_h src/Pugs/Config.hs src/Pugs/Prelude.hs
161
162$config_h : lib/Perl6/Pugs.pm util/config_h.pl
163        \$(PERL) util/config_h.pl "$ghc $ghc_flags"
164
165$version_h :
166        \$(PERL) util/version_h.pl $version_h
167
168pugs$Config{_exe} :: pugs_requirements build_perl5
169        ./Configure.PL
170        \$(RM_F) dist/build/pugs/pugs$Config{_exe}
171        \$(RM_F) Pugs.cabal
172        \$(CP) Pugs.cabal.in Pugs.cabal
173        ./Setup$Config{_exe} configure --user $EMBED_SMOP
174        ./Setup$Config{_exe} build
175        \$(CP) dist/build/pugs/pugs$Config{_exe} .
176
177prof :: pugs-prof$Config{_exe}
178
179pugs-prof$Config{_exe} :: pugs_requirements build_perl5
180        $cabal install --user -p @deps
181        PUGS_NO_THREADS=true ./Configure.PL
182        \$(RM_F) dist/build/pugs/pugs$Config{_exe}
183        \$(RM_F) Pugs.cabal
184        \$(CP) Pugs.cabal.in Pugs.cabal
185        ./Setup$Config{_exe} configure --user -p --enable-executable-profiling
186        ./Setup$Config{_exe} build
187        \$(CP) dist/build/pugs/pugs$Config{_exe} ./pugs-prof$Config{_exe}
188
189install ::
190\t./Setup$Config{_exe} install --user
191
192INST6_ARCHLIB = blib6/arch
193INST6_SCRIPT = blib6/script
194INST6_BIN = blib6/bin
195INST6_LIB = blib6/lib
196INST6_MAN1DIR = blib6/man1
197INST6_MAN3DIR = blib6/man3
198INSTPUGS_LIB = blib6/pugs
199
200clean ::
201\t./Setup$Config{_exe} clean
202
203src/Pugs/Config.hs : util/PugsConfig.pm current.build.yml
204\t\$(PERL) -Iutil -MPugsConfig -e "PugsConfig->write_config_module" > src/Pugs/Config.hs
205
206smoke : pugs$Config{_exe} util/run-smoke.pl
207\t\$(PERL) util/run-smoke.pl . smoke.html
208
209upload-smoke : smoke.yml
210\t\$(PERL) util/smokeserv/smokeserv-client.pl smoke.html smoke.yml
211
212smoke-upload : upload-smoke
213
214src/Pugs/Prelude.hs : src/perl6/Prelude.pm util/gen_prelude.pl
215\t\$(PERL) util/gen_prelude.pl -v --touch --inline -i src/perl6/Prelude.pm --output src/Pugs/Prelude.hs
216
217build_perl5 ::
218@{[for_perl5("
219        cd __DIR__ && $^X Makefile.PL && \$(MAKE)
220")]}
221
222clean ::
223@{[for_perl5("
224        -cd __DIR__ && \$(TEST_F) \$(FIRST_MAKEFILE) && \$(MAKE) clean
225")]}
226
227realclean ::
228@{[for_perl5("
229        -cd __DIR__ && \$(TEST_F) \$(FIRST_MAKEFILE) && \$(MAKE) realclean
230")]}
231
232.
233
234}
235
236sub bootstrap_with {
237    my ($package, $pattern, $version) = @_;
238    my @has_version;
239    if ($package eq 'cabal-install') {
240        @has_version = sort map { /^cabal-install version ($pattern.*)/ ? $1 : () } `$cabal --version`;
241    }
242    else {
243        @has_version = sort map { /^version: ($pattern.*)/ ? $1 : () } `$ghc_pkg describe $package`;
244    }
245
246    printf "- %-20s ", $package;
247    if (@has_version) {
248        print "...loaded. ($has_version[0] >= $version)\n";
249        return 0;
250    }
251
252    print "...missing. (would need $version)\n";
253    print "==> Installing $package. This may take a minute or two...\n";
254    sleep 1;
255
256    chdir "third-party/$package";
257
258    my ($setup_hs) = glob('Setup.*hs');
259    die "Impossible: No Setup?" unless $setup_hs;
260
261    use File::Path;
262    File::Path::rmtree(['dist']);
263
264    system($ghc, qw(--make -O0), -o => $setup_exe, $setup_hs)
265        || system($setup_exe, qw(configure --user))
266        || system($setup_exe, qw(build))
267        || system($setup_exe, qw(install --user))
268        || system($setup_exe, qw(clean))
269            and die << ".";
270Cannot install $package: $?
271Please enter the third-party/Cabal directory and install it manually
272following the instructions of README there.
273.
274
275    chdir $FindBin::RealBin;
276    return 1;
277}
278
279sub for_perl5 {
280    my $cmd = shift;
281    $cmd =~ s{\n}{}g;
282    my @cmds;
283    foreach my $dir (grep { -d } glob('perl5/*')) {
284        -e "$dir/Makefile.PL" or next;
285
286        # Skip XS modules for now
287        next if glob("$dir/*.xs") or glob("$dir/*.i") or $dir =~ /-\d+/;
288
289        next unless $dir =~ /Pugs-Compiler-Rule/;
290
291        my $this = $cmd;
292        $this =~ s{__DIR__}{$dir}g;
293        push @cmds, $this;
294    }
295    return join("\n", @cmds);
296}
297
298sub rebuild_setup {
299    unlink $_ for qw(Setup.hi Setup.o);
300    unlink $setup_exe;
301    system($ghc, qw(--make -O0), -o => $setup_exe, 'Setup.lhs');
302}
Note: See TracBrowser for help on using the browser.