#!/usr/bin/perl =pod Build System Overview - Makefile.PL calls GHC to compile Setup.hs to ./Setup.exe. - Makefile.PL writes a Makefile that will call util/build_pugs.pl upon "make". - build_pugs.pl writes a Pugs.cabal file based on the flags given in the Makefile. - build_pugs.pl calls ./Setup.exe. - Setup.exe builds dist/build/libHSPugs-6.XXX.YYY.a and returns to build_pugs.pl. - build_pugs.pl calls GHC to build ./pugs.exe (by simply linking the freshly built libHSPugs package with src/Main.hs). =cut use 5.006; use strict; use warnings; use Config; use Cwd qw(abs_path cwd); use File::Spec; use File::Copy; use File::Basename; use FindBin; use ExtUtils::Embed; BEGIN { chdir $FindBin::RealBin }; use inc::Module::Install; use lib 'inc'; use PugsBuild::Config; use Carp; # Win32/CygWin GHC appears to be more memory hungry than its # *nix counterpart, causing it to bail part-way through builds. # This value will be used only if 'ghc_heap_size' in config.yml # is not defined. use constant WIN32_GHC_HEAPSIZE => "348m"; # Special case for migration - remove old version of Syck unlink 'src/Data/Yaml/Syck.hs' if -e 'src/Data/Yaml/Syck.hs'; my @warn; my $pugs = "pugs$Config{_exe}"; my ($fs) = ($Config{sitelib} =~ /([\/\\])/) or die "Can't determine file_sep"; my $thispugs = ".${fs}pugs$Config{_exe}"; my $version_h = "src/Pugs/pugs_version.h"; my $config_h = "src/Pugs/pugs_config.h"; my @srcdirs = grep {-d} glob("src"), glob("src/*"), glob("src/*/*"), glob("src/*/*/*"); my @hsfiles = map {glob "$_/*.hs"} @srcdirs; push @hsfiles, qw; my @hppfiles = map {my $x=$_; $x=~s/\.hs$/.hpp/; $x} @hsfiles; warn_cygwin (); print "*** Probing configuration (please ignore any warnings)...\n\n"; name ('Perl6-Pugs'); version_from ('lib/Perl6/Pugs.pm'); abstract_from ('lib/Perl6/Pugs.pm'); author ('Audrey Tang '); license ('perl'); install_script ($pugs); install_script (glob('script/*')); install_script ('util/prove6'); recommends ('Perl6::Bible'); recommends ('Inline'); recommends ('Filter::Simple'); recommends ('LWP::Simple'); recommends ('LWP'); build_requires ('ExtUtils::MakeMaker' => 6.15); build_requires ('FindBin'); build_requires ('File::Path'); include ('Module::Install::Makefile::Name'); include ('Module::Install::Makefile::Version'); build_subdirs (map fixpaths($_), grep { -f "$_/Makefile.PL" && not -l "$_/Makefile.PL" } glob("ext/*"), glob("docs/*") ); my $version = version(); $version .= 0 until length($version) >= length('0.123456'); $version =~ s{6\.(\d{3})(\d{3})?}{join '.', 6, int($1), int($2||0)}e; version($version); makemaker_args ( test => { TESTS => join ' ', "t/*/*.t", "t/*/*/*.t" }, # , "perl5/*/t/*.t" }, MAN1PODS => {}, ); if (my $prefix = PugsBuild::Config->lookup('install_dir')) { makemaker_args(PREFIX => $prefix); } clean_files (map fixpaths($_), $version_h, $config_h, (map {"$_/*.hpp"} @srcdirs), "pugs$Config{_exe}", "pil$Config{_exe}", "src/gen_prelude$Config{_exe}", "Setup$Config{_exe}", "util/ghc-pkg-wrapper$Config{_exe}", "util/runcompiler$Config{_exe}", qw( src/Pugs/pugs_config.h src/Pugs/Config.hs blib6 dist src/Pugs/Prelude.hs src/Pugs/CodeGen/PIR/Prelude.hs test.log src/Pugs/Embed/Parrot.hs src/Pugs/Embed/Parrot_hsc.* src/Pugs/*/*_stub.* util/ghc-pkg-wrapper.hs util/ghc-pkg-wrapper.hi util/ghc-pkg-wrapper.o util/runcompiler.hs util/runcompiler.hi util/runcompiler.o temp-ex* unlink-test* Prelude Pugs.cabal Setup.hi Setup.o .setup-config .installed-pkg-config temp-test.*.*-out tempfile.*.* create_this_file create_this_file2 third-party/*/*.hi third-party/*/*.o third-party/*/dist ), object_files("src/Pugs", "src/Pugs/*", "src/Pugs/*/*"), ); set_postamble (); no_index ( directory => qw< inc debian modules perl5 ext script util docs examples src > ); sign (1); WritePugs (5); print(('=' x 78), "\n\n"); print @warn; print << "."; *** Enter '$Config{make}' to build Pugs. If compilation is too slow, consider using '$Config{make} fast' instead. . ################################################################################ sub object_files { map { ("$_/*.o", "$_/*.hi") } @_; } sub set_postamble { my @srcfiles = map { glob("$_/*.*hs") } @srcdirs; push @srcfiles, map { glob("$_/*.*hs-boot") } @srcdirs; push @srcfiles, map { map { substr($_, 0, -1) } glob("$_/*.*hsc") } @srcdirs; my ($ghc, $ghc_version, $ghc_flags, $ghc_pkg) = assert_ghc(); my $hsc2hs = $ENV{HSC2HS}; my $setup = File::Spec->catfile(".", "Setup$Config{_exe}"); my $ghc_wrapper = File::Spec->catfile(".", "util", "runcompiler$Config{_exe}"); my $ghc_pkg_wrapper = File::Spec->catfile(".", "util", "ghc-pkg-wrapper$Config{_exe}"); my $config_path = File::Spec->catfile(cwd(), 'third-party', 'installed', 'packages.conf'); if (!$hsc2hs) { $hsc2hs = $ghc; $hsc2hs =~ s{(.*)ghc}{$1hsc2hs}; } preprocess( File::Spec->catfile('util', 'runcompiler.hs.in'), File::Spec->catfile('util', 'runcompiler.hs'), CONFIG_PATH => $config_path, GHC => $ghc, GHC_PKG => $ghc_pkg, ); preprocess( File::Spec->catfile('util', 'ghc-pkg-wrapper.hs.in'), File::Spec->catfile('util', 'ghc-pkg-wrapper.hs'), CONFIG_PATH => $config_path, GHC => $ghc, GHC_PKG => $ghc_pkg, ); # set up install path for third-party modules mkdir File::Spec->catdir('third-party', 'installed'); compile_hs($ghc, 'Setup', $setup); compile_hs($ghc, File::Spec->catfile('util', 'ghc-pkg-wrapper'), $ghc_pkg_wrapper); compile_hs($ghc, File::Spec->catfile('util', 'runcompiler'), $ghc_wrapper); # Add GHC to PATH local $ENV{PATH} = dirname($ghc) . $Config{path_sep} . $ENV{PATH}; if (not try_compile ( "import Control.Monad.RWS\n" . "main = let (x, (), ()) = runRWS (return ()) () () in return x\n" , $ghc, qw(-hide-all-packages -package mtl -package base) ), ) { # We are missing mtl somehow, likely because GHC 6.6's extra pkg is not there die <<'EOD'; *** Could not load the "mtl" package in your GHC installation. This is likely because the "extralibs" of GHC 6.6 was not built along with the base GHC distribution. To install extra libraries, extract both "-src" and "-src-extralibs" distributions from http://haskell.org/ghc/download_ghc_66.html in the same directory, then cd into ghc-6.6/ and build GHC from there. EOD } my $native_fps; if (try_compile("import Data.ByteString (useAsCStringLen)\n" ."main :: IO ()\n" ."main = main\n", $ghc, qw(-hide-all-packages -package base))) { # We have native ByteString; dummy the fps out $native_fps = 1; copy "third-party/fps/fps.cabal.dummy" => "third-party/fps/pugs-fps.cabal"; unlink "third-party/fps/fps.cabal"; # legacy } else { # Use bundled ByteString - unregister user-fps installed by earlier Pugs system($ghc_pkg, qw( --user unregister fps )); copy "third-party/fps/fps.cabal.in" => "third-party/fps/pugs-fps.cabal"; unlink "third-party/fps/fps.cabal"; # legacy } $ghc = $ghc_wrapper; $ghc_pkg = $ghc_pkg_wrapper; my $heap; # Win32 GHC is a memory hog. We need to provide it with a memory sty. # We still use the option from config.yml if available. # XXX - This is no longer needed for GHC 6.6! if ($Config{osname} eq 'cygwin' or $Config{osname} eq 'MSWin32') { $heap = WIN32_GHC_HEAPSIZE; } $heap = PugsBuild::Config->lookup('ghc_heap_size') || $heap; $ghc_flags .= " +RTS -M$heap -RTS" if $heap; # $ghc_flags .= ' -dcore-lint'; # $ghc_flags .= " -keep-tmp-files"; if ($ENV{PUGS_EMBED} and $ENV{PUGS_EMBED} =~ /\bhaskell\b/i) { if (has_ghc_package('plugins') and try_compile("import System.Eval\n" ."main :: IO ()\n" .'main = (eval_ "return ()" [] [] [] [] :: IO (Either [String] (Maybe ()))) >> return ()', $ghc, '-package', 'plugins')) { $ghc_flags .= ' -package plugins -DPUGS_HAVE_HSPLUGINS '; } else { push @warn, << '.'; *** Inline Haskell support disabled. If you want dynamic loading of haskell modules, please install the hs-plugins library: http://www.cse.unsw.edu.au/~dons/hs-plugins/ Remember to "make register" after "make install" for hs-plugins! . } } if (has_ghc_package('readline') and try_compile("import System.Console.Readline\n" ."main :: IO ()\n" ."main = do\n" ." setCatchSignals False\n" ." setCatchSigwinch False\n" .' _ <- readline "" '."\n" .' return ()', $ghc)) { $ghc_flags .= ' -DPUGS_HAVE_READLINE '; # -package readline'; } else { push @warn, << '.'; *** Readline support disabled. If you want readline support, please install the GNU readline library. . } my $ghc_output = ''; # "-o pugs$Config{_exe} src/Main.hs"; my $hasktags = $ENV{HASKTAGS} || 'hasktags'; # map a bunch of .c files to a bunch of expected .o files my $o = sub { map { substr($_, 0, -1) . 'o' } @_ }; my $pcre_c = "src/pcre/pcre.c"; my ($pcre) = $o->($pcre_c); my @prereqs = ($pcre); my @derived_srcfiles = qw< src/Pugs/Embed/Parrot.hs src/Pugs/pugs_config.h src/Pugs/pugs_version.h src/Pugs/Config.hs src/Pugs/Prelude.hs src/Pugs/CodeGen/PIR/Prelude.hs >; my $embed_flags = ""; my $hsc2hs_flags = ""; my $ccdlflags = ""; # [-!]perl5 does not work with the \bFLAG\b convention used in this file. # It should be removed, or the convention, and code, fixed. # Went in 2006-08-30. Depreciated 2006-09-11. if ($ENV{PUGS_EMBED} and $ENV{PUGS_EMBED} =~ /[-!]perl5\b/i) { push @warn, << '.'; *** PUGS_EMBED flags "-perl5" and "!perl5" are depreciated and buggy. Please use "noperl5" instead. . } if (!$ENV{PUGS_EMBED} or $ENV{PUGS_EMBED} !~ /(?:[-!]|\bno)perl5\b/i) { $ENV{PUGS_EMBED} .= " perl5 "; #push @prereqs, "src/perl5/p5embed.o"; # XXX # $ghc_output .= " src/perl5/p5embed.o "; $embed_flags .= " -DPUGS_HAVE_PERL5 -isrc/perl5 "; my $flags = "$Config{ccflags} $Config{ccdlflags} "; if ($flags =~ /\S/) { $flags =~ s{([\\"'])}{\\$1}g; my @flags = grep { length $_ } split /\s+/, $flags; if ($^O eq 'MSWin32') { if ($Config{libperl} =~ /lib(\w+)\.a/) { $embed_flags .= " -optl-l$1 "; } elsif (defined &Win32::BuildNumber) { # We are on ActivePerl -- Kluge massively! no warnings 'once'; our %MY_CONFIG = %Config; *Config = *MY_CONFIG; *Config::Config = *MY_CONFIG; *ExtUtils::MM_Win32::Config = *MY_CONFIG; *ExtUtils::MM_Unix::Config = *MY_CONFIG; $Config{ccflags} =~ s/-libpath:"?(.*?)"? //g; $Config{ccdlflags} =~ s/-libpath:"?(.*?)"? //g; $Config{lddlflags} =~ s/-libpath:"?(.*?)"? //g; $Config{ldflags} =~ s/-libpath:"?(.*?)"? //g or die "ldflags: $Config{ldflags} does not contain -libpath:"; my $lib = "$1/$Config{libperl}"; $embed_flags .= " -optl\"$lib\" "; $flags = "$Config{ccflags} $Config{ccdlflags}"; $flags =~ s{([\\"'])}{\\$1}g; @flags = grep { length $_ } split /\s+/, $flags; } else { warn "Unrecognized libperl shared library: $Config{libperl}, proceeding anyway...\n"; } $ccdlflags .= (/^-[DIL]/ ? ' -optc' : ' -optl') . qq["$_" ] for @flags; $embed_flags .= " -optc-Ddirent=DIRENT"; } else { $embed_flags .= " -optc$_" for grep length, split(/\s+/, ccopts()); $embed_flags .= " -optl$_" for grep length, split(/\s+/, ldopts()); } $embed_flags .= " $_" for grep { /-[DIL]/ } split(/\s+/, ccopts()); $embed_flags .= " $_" for grep { /-[DIL]/ } split(/\s+/, ldopts()); if ($Config{osname} eq 'cygwin') { my $cygpath = sub { my $path = `cygpath @_`; chomp $path; $path =~ s{\\}{/}g; return $path; }; $embed_flags =~ s{(/usr/\S+)}{$cygpath->($1)}eg; $embed_flags =~ s{/cygdrive/(\w)/}{$1:/}g; #warn "** Cygwin embedding flags: embed_flags\n"; } } } else { push @warn, << '.'; *** Perl 5 embedding disabled. If you want Perl 5 support, please set the PUGS_EMBED environment variable to not contain "noperl5". . } if ($ENV{PUGS_EMBED} and $ENV{PUGS_EMBED} =~ /\bparrot\b/i and $Config{cc} eq 'cl') { push @warn, << '.'; *** Parrot linking not supported with MSVC. Parrot linking will be disabled. . $ENV{PUGS_EMBED} =~ s/\bparrot\b//g; } # Respect CC setting my $cc = $ENV{CC} || 'gcc'; $ghc_flags .= " -pgmc $cc " unless $cc eq 'gcc'; if ($Config{cf_by} eq 'Debian Project' and $ENV{PUGS_EMBED} and $ENV{PUGS_EMBED} =~ /\bperl5\b/i) { # Is it safe to remove 'Debian Project' above, to test on all platforms? my $need_path = 1; my $libperlpath = ''; my $libperl = $Config{libperl}; foreach my $path (split(/\s/, $Config{libpth} . ' ' . $Config{libsdirs})) { if (-e "$path/libperl.so") { $need_path = 0; last; } elsif (-e "$path/$libperl") { $libperlpath ||= $path; } } if ($need_path) { my $message = ''; $message .= qq[ * Symlink $libperlpath/$libperl to libperl.so\n] if ($libperlpath and $libperl); $message .= qq[ * Install libperl-dev package\n] if ($Config{cf_by} eq 'Debian Project'); die <splitpath($parrot_config))[1]; } if (!$base) { $parrot_config = which('parrot-config') || ''; $base = (File::Spec->splitpath($parrot_config))[1] if -e $parrot_config; } if (!$base and -d File::Spec->catdir(File::Spec->updir, 'parrot')) { $base = abs_path(File::Spec->catdir(File::Spec->updir, 'parrot')); } if (!$base and -d File::Spec->catdir(File::Spec->updir, 'parrot-trunk')) { $base = abs_path(File::Spec->catdir(File::Spec->updir, 'parrot-trunk')); } my $temp = File::Spec->catfile($base, 'parrot-config.imc'); if (!$parrot_config && -e $temp) { $parrot_config = $temp; } $temp = File::Spec->catfile($base, 'parrot-config.pir'); if (!$parrot_config && -e $temp) { $parrot_config = $temp; } $temp = File::Spec->catfile($base, 'parrot-config'); if (!$parrot_config && -e $temp) { $parrot_config = $temp; } $base =~ s/bin\/*$//; (-d $base and -e $parrot_config) or die "*** Please set \$ENV{PARROT_PATH} to the base path with a built parrot tree.\n"; my $ldflags = parrot_config($base, $parrot_config, 'ldflags'); my $libs = parrot_config($base, $parrot_config, 'libs'); my $icuflags = parrot_config($base, $parrot_config, 'icu_shared'); my $include_path = parrot_config($base, $parrot_config, 'prefix') . parrot_config($base, $parrot_config, 'inc'); my $rpath_blib = parrot_config($base, $parrot_config, 'rpath_blib'); my $build_dir = parrot_config($base, $parrot_config, 'top_builddir', 'build_dir'); my $is_shared = parrot_config($base, $parrot_config, 'parrot_is_shared'); my $parrot_libdir = parrot_config($base, $parrot_config, 'lib_dir'); # Convert flags to -optc-*,etc, to pass through ghc. c/ompiler l/inker $ldflags =~ s/(^|\s)-/$1-optl-/g; $libs =~ s/(^|\s)-/$1-optl-/g; $icuflags =~ s/(^|\s)-/$1-optl-/g; $include_path =~ s/(^|\s)-/$1-optc-/g; $embed_flags .= " -I$include_path" if $include_path =~ /\S/; $rpath_blib =~ s/(^|\s)-/$1-optl-/g; $embed_flags .= " -I$base/include -L$base/lib -L$base/blib/lib -DPUGS_HAVE_PARROT -L/usr/local/lib $ldflags "; $embed_flags .= " -lparrot $libs $icuflags "; my $config = $parrot_libdir."/parrot/config/install_config$Config{_o}"; $config = $parrot_libdir."/parrot/config/parrot_config$Config{_o}" unless -e $config; $config = $parrot_libdir."/parrot/config/null_config$Config{_o}" unless -e $config; $config = "$build_dir/src/install_config$Config{_o}" unless -e $config; $config = "$build_dir/src/parrot_config$Config{_o}" unless -e $config; $config = "$build_dir/src/null_config$Config{_o}" unless -e $config; die <<"EOD" unless -e $config or $is_shared; *** Could not find src/null_config.o in $build_dir. Solutions include: * Remove parrot from PUGS_EMBED * Place a built Parrot source tree under $build_dir. EOD $embed_flags .= " $config "; $embed_flags .= " $rpath_blib " if -d $build_dir; # parrot include paths for hsc2hs $hsc2hs_flags .= " -DPUGS_HAVE_PARROT -I$base/include "; push @warn, << "."; *** Embedded 'parrot' enabled. You can use it for Perl 6 regex support by setting the PUGS_REGEX_ENGINE environment variable to "PGE" at runtime. . } else { my $whichparrot = can_run('parrot'); if ($whichparrot) { push @warn, << "."; *** External 'parrot' executable found in your PATH at: $whichparrot You can use it for Perl 6 regex support by setting the PUGS_REGEX_ENGINE environment variable to "PGE" at runtime. If you want to link against Parrot, set the PUGS_EMBED environment variable to contain 'parrot', the PARROT_PATH environment variable to the path of a built parrot tree, then run Makefile.PL again. . } } my $config = get_pugs_config(); my $is_win32 = ($^O =~ /MSWin|mingw|cygwin/i); my $threaded = (try_compile_and_run("main :: IO ()\nmain = return ()", $ghc, "-threaded")) ? '-threaded' : ''; if ($threaded and $ENV{PUGS_EMBED} and $ENV{PUGS_EMBED} =~ /\bperl5\b/ and !$Config{usethreads}) { push @warn, << '.'; *** Thread support disabled because you are building with embedded perl5 and your perl5 is not threaded. . $threaded = ''; } if ($threaded && $ENV{PUGS_NO_THREADS}) { push @warn, << '.'; *** Thread support disabled due to explicit request in PUGS_NO_THREADS. . $threaded = ''; } # As of now, Test::TAP::HTMLMatrix is the key dependency for smokes, # so we need only check for that. eval { require Test::TAP::HTMLMatrix } or push @warn, << '.'; *** You do not appear to have a Smoke Kit installed. You can still build Pugs and even run `make test', but you won't be able to run the more modern `make smoke' target to produce nice graphs and send them to the public smoke server. Installing Task::Smoke from CPAN will bring in the necessary dependencies. . # XXX - hsplugins doesn't build with profiles my $profiled_flags = $ghc_flags; $profiled_flags =~ s{-DPUGS_HAVE_HSPLUGINS}{}; $profiled_flags =~ s{-package plugins}{}; my $emit = sub { my $o = shift; my $c = substr($o, 0, -1) . 'c'; return "$o : $c\n\t$ghc $threaded $embed_flags $ghc_flags -no-link -no-hs-main -O -o $o $c\n"; }; mkdir 'dist'; mkdir 'dist/build'; mkdir 'dist/build/src'; # Using the Win32 Haskell compiler results in a setup program that # doesn't grok cygwin paths. This kludge takes any /cygdrive/ # style paths and rewrites them. This really should be factored # out to a common module. Better still, we should make a Cygwin-native # GHC. if ($Config{osname} eq 'cygwin') { # NB. We're exploiting for's aliasing of variables. foreach my $path ($ghc_pkg, $hsc2hs, $ghc) { $path =~ s{^/cygdrive/(\w)/}{$1:/}; } } my $setup_flags = "--prefix=\$(DESTDIR) --with-hc-pkg=$ghc_pkg --with-hsc2hs=$hsc2hs --ghc --with-compiler=$ghc"; my $svn_entries = ''; if (-d '.svn') { $svn_entries = File::Spec->catfile('.svn', 'entries'); } #$svn_entries = 'force_run'; # logic for Judy: =begin NOJUDY if ($Config{osname} ne 'MSWin32') { warn "Configuring Judy...\n"; chdir "third-party/judy/Judy-1.0.3"; copy('src/Judy.h', '../../HsJudy'); system("./configure") unless -e "config.status" and -e "Makefile"; chdir "../../.."; } my $judyclean; if ($Config{osname} eq 'MSWin32') { $judyclean = 'cd third-party\judy\Judy-1.0.3\src && '. 'nmake /nologo /F Makefile.win32 clean'; } else { my $make = $Config{make}; # Judy at this moment wants GNU make. $make = 'gmake' unless `$make --version` =~ /GNU/; $judyclean = "cd third-party/judy/Judy-1.0.3 \&\& $make clean \&\& perl cleanmore.pl"; } =end NOJUDY =cut postamble(fixpaths(<< ".")); $config_h : lib/Perl6/Pugs.pm util/config_h.pl \$(PERL) util/config_h.pl "$ghc $ghc_flags" $version_h : \$(PERL) util/version_h.pl $version_h @{[join("\n", map {$emit->($_)} grep { /\.o$/ } @prereqs)]} src/Pugs/Config.hs : util/PugsConfig.pm \$(PERL) -Iutil -MPugsConfig -e "PugsConfig->write_config_module" > src/Pugs/Config.hs src/gen_prelude$Config{_exe} : src/gen_prelude.hs $ghc -O0 --make -o src/gen_prelude$Config{_exe} src/gen_prelude.hs src/Pugs/CodeGen/PIR/Prelude.hs : src/gen_prelude$Config{_exe} src/perl6/Prelude/PIR.pm \@\$(PERL) -e "mkdir q-src/Pugs/CodeGen/PIR-" src/gen_prelude$Config{_exe} Pugs.CodeGen.PIR.Prelude < src/perl6/Prelude/PIR.pm > src/Pugs/CodeGen/PIR/Prelude.hs src/Pugs/Prelude.hs : src/perl6/Prelude.pm util/gen_prelude.pl \$(PERL) util/gen_prelude.pl -v --touch --inline -i src/perl6/Prelude.pm --output src/Pugs/Prelude.hs ${() = '%.hpp : %.hs @prereqs $version_h $ghc $threaded $ghc_flags -DHADDOCK -E \$< -o \$@ \$(PERL) util/munge_haddock.pl \$@'; \''} .SUFFIXES: .hs .hpp .hs.hpp : $ghc $threaded $ghc_flags -DHADDOCK -E \$< -o \$@ \$(PERL) util/munge_haddock.pl \$@ .SUFFIXES: .hsc .hs .hsc.hs : \$(PERL) -MFile::Spec -e "sub p () { File::Spec->splitpath(ARGV->[0]) }; chdir((p)[1]); system(q($hsc2hs), qw($hsc2hs_flags), (p)[2]);" \$< .SUFFIXES: .grammar .hs .grammar.hs : \$(PERL) util/file_to_hs.pl \$< \$@ .SUFFIXES: .pil .hs .pil.hs : \$(PERL) util/file_to_hs.pl \$< \$@ src/Emit/PIR.hs: src/Pugs/AST/Internals.hs: src/Pugs/PIL1.hs: src/Pugs/PIL2.hs: util/drift.pl: src/Emit/PIR/Instances.hs: src/Emit/PIR.hs util/drift.pl \$(PERL) util/drift.pl src/Emit/PIR.hs src/Pugs/AST/Internals/Instances.hs: src/Pugs/AST/Internals.hs util/drift.pl \$(PERL) util/drift.pl src/Pugs/AST/Internals.hs src/Pugs/PIL1/Instances.hs: src/Pugs/PIL1.hs util/drift.pl \$(PERL) util/drift.pl src/Pugs/PIL1.hs src/Pugs/PIL2/Instances.hs: src/Pugs/PIL2.hs util/drift.pl \$(PERL) util/drift.pl src/Pugs/PIL2.hs haddock : $version_h $config_h @hppfiles dist/doc/html haddock -t Pugs-$version -h -o dist/doc/html/ @hppfiles \@\$(RM_F) @{[map "$_.pre", @hppfiles]} @hppfiles \@\$(PERL) -le "print and print q-*** API Documentation generated in @{[File::Spec->catfile('dist', 'doc', 'html', 'index.html')]}-" # make haddock one file at a time to get partial, unlinked output haddock-broken : $version_h $config_h @hppfiles dist/doc/html @{[join("\n", map {"\thaddock -t Pugs-$version -h -o dist/doc/html/ $_"} @hppfiles)]} \@\$(RM_F) @{[map "$_.pre", @hppfiles]} @hppfiles \@\$(PERL) -le "print and print q-*** Unlinked API Documentation generated in @{[File::Spec->catfile('dist', 'doc', 'html', 'index.html')]}-" dist/doc/html : \@\$(PERL) -MFile::Path -e "mkpath q-dist/doc/html-" pugs_requirements : src/Emit/PIR/Instances.hs src/Pugs/AST/Internals/Instances.hs src/Pugs/PIL1/Instances.hs src/Pugs/PIL2/Instances.hs src/Pugs/Config.hs src/Pugs/CodeGen/PIR/Prelude.hs @srcfiles $version_h $config_h config.yml src/perl6/Prelude.pm src/Pugs/Prelude.hs prof :: profiled fastprof :: unoptimised-profiled unoptimized-profiled :: unoptimised-profiled unoptimised-profiled :: pugs_requirements \$(PERL) util/build_pugs.pl _+SETUP $setup_flags _-SETUP _+GHC $version $ghc $ghc_pkg $ghc_version $setup --make -O0 -auto-all -prof $threaded $profiled_flags $ccdlflags $embed_flags $ghc_output _-GHC _+GEN_PRELUDE --pugs $thispugs profiled :: pugs_requirements \$(PERL) util/build_pugs.pl _+SETUP $setup_flags _-SETUP _+GHC $version $ghc $ghc_pkg $ghc_version $setup --make -O -auto-all -prof $threaded $profiled_flags $ccdlflags $embed_flags $ghc_output _-GHC _+GEN_PRELUDE --pugs $thispugs pugs.prof :: profiled find t -type f | grep -v D | grep -v R | grep -v pugsrun | ./pugs +RTS -p -RTS -e 'my sub exit {}; for =\$\$*IN -> \$\$t is copy { \$\$t .= chomp; require \$\$t }' optimised :: optimized optimized :: pugs_requirements \$(PERL) util/build_pugs.pl _+SETUP $setup_flags _-SETUP _+GHC $version $ghc $ghc_pkg $ghc_version $setup --make -O $threaded $ghc_flags $ccdlflags $embed_flags $ghc_output _-GHC _+GEN_PRELUDE --pugs $thispugs fast :: unoptimized unoptimised :: unoptimized unoptimized :: pugs_requirements \$(PERL) util/build_pugs.pl _+SETUP $setup_flags _-SETUP _+GHC $version $ghc $ghc_pkg $ghc_version $setup --make -O0 $threaded $ghc_flags $ccdlflags $embed_flags $ghc_output _-GHC _+GEN_PRELUDE --pugs $thispugs $pugs : pugs_requirements \$(PERL) util/build_pugs.pl _+SETUP $setup_flags _-SETUP _+GHC $version $ghc $ghc_pkg $ghc_version $setup --make __optimization__ $threaded $ghc_flags $ccdlflags $embed_flags $ghc_output _-GHC _+GEN_PRELUDE --pugs $thispugs pirtest : test-pir pirsmoke : smoke-pir jssmoke : smoke-js test :: blib6/lib/Test.pm.yml pure_all :: blib6/lib/Test.pm.yml test-all : test test-js test-pir test-perl5 test-pir : \$(PERL) -e "ENV->{HARNESS_PERL_SWITCHES}=q+-B PIR+; system qq+$Config{make}+, q+test+" test-js : \$(PERL) -e "ENV->{HARNESS_PERL_SWITCHES}=q+-B JS+; system qq+$Config{make}+, q+test+" test-perl5 : \$(PERL) -e "ENV->{HARNESS_PERL_SWITCHES}=q+-B PERL5+; system qq+$Config{make}+, q+test+" blib6/lib/Test.pm.yml :: ext/Test/lib/Test.pm \$(NOECHO) \$(ECHO) "Precompiling Test.pm..." $thispugs -CParse-YAML ext/Test/lib/Test.pm > blib6/lib/Test.pm.yml upload-smoke : smoke.yml \$(PERL) util/smokeserv/smokeserv-client.pl smoke.html smoke.yml smoke-upload : upload-smoke smoke.yml : \$(PERL) util/run-smoke.pl . smoke.html smoke : smoke-pugs smoke-all : smoke-pugs smoke-js smoke-pir smoke-perl5 smoke-pugs : $pugs util/run-smoke.pl all blib6/lib/Test.pm.yml \$(PERL) util/run-smoke.pl . smoke.html smoke-pir : $pugs util/run-smoke.pl all \$(PERL) util/run-smoke.pl . smoke-pir.html -BPIR smoke-jsperl5 : $pugs util/run-smoke.pl all \$(PERL) -e "ENV->{PUGS_RUNTIME}=q+JSPERL5+; exec qw+$^X util/run-smoke.pl . smoke-jsperl5.html+" smoke-js : $pugs util/run-smoke.pl all \$(PERL) -e "ENV->{PUGS_RUNTIME}=q+JS+; exec qw+$^X util/run-smoke.pl . smoke-js.html+" smoke-perl5 : $pugs util/run-smoke.pl all \$(PERL) -e "ENV->{PUGS_RUNTIME}=q+PERL5+; exec qw+$^X util/run-smoke.pl . smoke-perl5.html -BPERL5+" ghci : @prereqs @derived_srcfiles $ghc @{[ dethread_flags($ghc_flags) ]} $ghc_output -DPUGS_UNDER_GHCI -no-link --make -O0 -fglasgow-exts -L. -idist/build -Ldist/build -idist/build/src -Ldist/build/src -isrc src/Prereqs.hs @prereqs \@\$(RM_RF) src/Pugs/*/*_stub.* $ghc @{[ dethread_flags($ghc_flags) ]} $ghc_output -DPUGS_UNDER_GHCI --interactive -fglasgow-exts -L. -idist/build -Ldist/build -idist/build/src -Ldist/build/src -isrc src/Main.hs @prereqs ctags : @prereqs @derived_srcfiles echo ":ctags" | $ghc $ghc_flags $ghc_output --interactive -osuf moose -hisuf miise -fglasgow-exts -L. -idist/build -Ldist/build -idist/build/src -Ldist/build/src -isrc src/Main.hs @prereqs etags : @prereqs @derived_srcfiles echo ":etags" | $ghc $ghc_flags $ghc_output --interactive -osuf moose -hisuf miise -fglasgow-exts -L. -idist/build -Ldist/build -idist/build/src -Ldist/build/src -isrc src/Main.hs @prereqs pil$Config{_exe} : $config_h $pcre @srcfiles src/PIL/Native/Bootstrap.hs src/PIL/Native/Syntax.hs $ghc $ghc_flags --make -fglasgow-exts -H0 -isrc -Isrc -L. -fno-warn-name-shadowing -o pil$Config{_exe} -main-is PIL.main src/PIL.hs $pcre pili : pil$Config{_exe} $ghc --interactive -fglasgow-exts -isrc -Isrc -L. -static -fno-warn-name-shadowing src/PIL.hs $pcre tags : @srcfiles $hasktags -c @{[ grep { !/PIL/ } @srcfiles ]} sort tags > tags.tmp mv tags.tmp tags config.yml: src/perl6/Prelude.pm: INST6_ARCHLIB = blib6/arch INST6_SCRIPT = blib6/script INST6_BIN = blib6/bin INST6_LIB = blib6/lib INST6_MAN1DIR = blib6/man1 INST6_MAN3DIR = blib6/man3 INSTPUGS_LIB = blib6/pugs build_perl5 :: @{[for_perl5(" cd __DIR__ && perl Makefile.PL && \$(MAKE) ")]} clean :: \@\$(RM_RF) third-party/installed @{[for_perl5(" -cd __DIR__ && \$(TEST_F) \$(FIRST_MAKEFILE) && \$(MAKE) clean ")]} realclean :: \@\$(RM_RF) third-party/installed @{[for_perl5(" -cd __DIR__ && \$(TEST_F) \$(FIRST_MAKEFILE) && \$(MAKE) realclean ")]} pure_all :: build_perl5 \$(PERLRUN) util/src_to_blib.pl register :: \$(PERLRUN) util/ghc_setup.pl copy --copy-prefix=\$(DESTDIR) \$(PERLRUN) util/ghc_setup.pl register --prefix=\$(DESTDIR) pure_site_install :: \$(NOECHO) \$(MOD_INSTALL) \\ \$(INST6_LIB) \$(DESTDIR)$config->{sitelib} \\ \$(INST6_ARCHLIB) \$(DESTDIR)$config->{sitearch} \\ \$(INST6_BIN) \$(DESTDIR)$config->{sitebin} \\ \$(INST6_SCRIPT) \$(DESTDIR)$config->{sitescript} \\ \$(INST6_MAN1DIR) \$(DESTDIR)$config->{installsiteman1dir} \\ \$(INST6_MAN3DIR) \$(DESTDIR)$config->{installsiteman3dir} \\ \$(INSTPUGS_LIB) \$(DESTDIR)$config->{sitelib}/auto/pugs # \$(PERLRUN) util/ghc_setup.pl copy --copy-prefix=\$(DESTDIR) pure_vendor_install :: \$(NOECHO) \$(MOD_INSTALL) \\ \$(INST6_LIB) \$(DESTDIR)$config->{privlib} \\ \$(INST6_ARCHLIB) \$(DESTDIR)$config->{archlib} \\ \$(INST6_BIN) \$(DESTDIR)$config->{installbin} \\ \$(INST6_SCRIPT) \$(DESTDIR)$config->{installscript} \\ \$(INST6_MAN1DIR) \$(DESTDIR)$config->{installman1dir} \\ \$(INST6_MAN3DIR) \$(DESTDIR)$config->{installman3dir} \\ \$(INSTPUGS_LIB) \$(DESTDIR)$config->{privlib}/auto/pugs # \$(PERLRUN) util/ghc_setup.pl copy --copy-prefix=\$(DESTDIR) . } sub for_perl5 { my $cmd = shift; $cmd =~ s{\n}{}g; my @cmds; foreach my $dir (grep { -d } glob('perl5/*')) { -e "$dir/Makefile.PL" or next; # Skip XS modules for now next if glob("$dir/*.xs") or glob("$dir/*.i") or $dir =~ /-\d+/; my $this = $cmd; $this =~ s{__DIR__}{$dir}g; push @cmds, $this; } return join("\n", @cmds); } our $do_run; sub try_compile_and_run { local $do_run = 1; try_compile(@_); } sub try_compile { my $code = shift; my $temp = "pugs-tmp-$$"; my $ghc = shift or croak "try_compile called without path to ghc"; eval { open TMP, "> $temp.hs"; print TMP $code; close TMP; system( $ghc, @_, "--make", "-v0", -o => "$temp.exe", "$temp.hs" ); }; my $ok = -s "$temp.exe"; if ($do_run) { $ok = 0 unless system(abs_path("$temp.exe")) == 0; } unlink("$temp.exe"); unlink("$temp.hs"); unlink("$temp.hi"); unlink("$temp.o"); return $ok; } sub parrot_config { my $base = shift; my $parrot_config = shift; my $ac_path = abs_path(); my $sp_base = $base; $sp_base =~ s{\\}{\/}g; chdir( $sp_base ) or die "Can't change dir to '$sp_base'"; my $parrot = "parrot$Config{_exe}"; $parrot = "bin/$parrot" if not -e $parrot; my $value; while (@_) { my $config = shift; $value = `./$parrot $parrot_config $config`; $value =~ /no such key:/ or last; } die $value if $value =~ /no such key:/; chomp($value); chdir( $ac_path ) or die "Can't change dir to '$ac_path'"; return $value; } sub which { my $file = shift; for ( File::Spec->path() ) { my $full_name = File::Spec->catfile($_, $file); return $full_name if -e $full_name; } return undef; } sub preprocess { my ($infile, $outfile, %substitutions) = @_; open IN, '<', $infile or die "failed to open $infile ($!)"; open OUT, '>', $outfile or die "failed to open $outfile ($!)"; if ($Config{osname} eq 'cygwin') { s{^/cygdrive/(\w)/}{$1:/} for values %substitutions; } while () { while (my ($pat, $subst) = each(%substitutions)) { $subst =~ s{\\}{\\\\}g; s/__${pat}__/$subst/g } print OUT $_; } close OUT; close IN; } sub compile_hs { my ($ghc, $prefix, $out) = @_; unlink($prefix . $_) for ( $Config{_exe}, '.o', '.hi', ); my $rv = system($ghc, '--make', '-o' => $out, (-e $prefix. '.hs') ? $prefix.'.hs' : $prefix.'.lhs' ); unless (-s $out) { die << "."; *** Building Setup$Config{_exe} failed (exit code $rv) Please check your GHC and Cabal installation. . } }