--- toast 2005/09/05 00:36:12 1.395 +++ toast 2005/09/05 22:29:42 1.396 @@ -2621,45 +2621,68 @@ sub helphspkg($$$) { my($rootdir, $helperdir, $cmd) = @_; + return true unless hspkg; helpstub($helperdir, $cmd); writescript(path($helperdir, "$cmd.helper"), "#!/bin/sh\n# $genby\n", q[ rootdir=], quote($rootdir), q[ name=], time() . "-$$", q[ -cat > "$rootdir/bin/ghc" << "EOF" +wrapper="$rootdir/bin/ghc.wrapped" +cat > "$wrapper" << "EOF" #!/bin/sh -exec perl -wx "$0" +exec perl -wx "$0" "$@" #!perl $0 =~ m!([^/]+)$! or die; my($me) = $1; -my(@mystats) = stat($0) or die("stat $0: $!"); my(@extra); -push(@extra, "-package-conf", $_) for split(/:/, $ENV{"HS_PKG_PATH"} || ""); +my($wrap) = $ENV{"TOAST_HS_WRAPPER"} || ""; +if($wrap) +{ + $wrap .= ":"; +} +else +{ + push(@extra, "--package-conf=$_") for split(/:/, $ENV{"HS_PKG_PATH"} || ""); +} +$ENV{"TOAST_HS_WRAPPER"} = $wrap .= $0; -for(split(/:/, $ENV{"PATH"})) +DIR: for(split(/:/, $ENV{"PATH"})) { - my($prog) = "$_/$me"; - if(-x($prog)) + for("$_/$me.unwrapped", "$_/$me") { - my(@progstats) = stat($prog) or die("stat $prog: $!"); - next if $progstats[0] == $mystats[0] && $progstats[1] == $mystats[1]; - exec($prog, @extra, @ARGV); - die("exec $prog failed: $!"); + if(-x) + { + my(@stats) = stat or die("stat $_: $!"); + my($skip); + for $skip (split(/:/, $wrap)) + { + my(@skipstats) = stat($skip) or die("stat $skip: $!"); + next DIR if "$skipstats[0] $skipstats[1]" eq "$stats[0] $stats[1]"; + } + exec $_ ($0, @extra, @ARGV); + die("exec $_ failed: $!"); + } } } die("can't find next $me in PATH"); EOF -chmod +x "$rootdir/bin/ghc" -for i in ghc-pkg runghc runhaskell; do - ln -sf ghc "$rootdir/bin/$i" +chmod +x "$wrapper" +for i in ghc; do + path="$rootdir/bin/$i" + if [ -r "$path" -a ! -r "$path.unwrapped" ] && ! diff -q "$path" "$wrapper" + then + mv "$path" "$path.unwrapped" + fi + ln -sf ghc.wrapped "$rootdir/bin/$i" done for arg; do case "$arg" in + --toast-install-wrapper-only) exit 0 ;; -*) ;; *) [ -r "$arg" ] && exec < "$arg" ;; esac @@ -3780,12 +3803,28 @@ } } +sub wraphaskell($$$) +{ + my($srcdir, $rootdir, $helperdir) = @_; + return true unless -x(path($rootdir, qw(bin ghc))); + my($script) = path($helperdir, "ghc-pkg"); + if(!-x($script)) + { + optmd($helperdir); + helphspkg($rootdir, $helperdir, "wrap-ghc"); + $script = path($helperdir, "wrap-ghc"); + armhelpers($helperdir); + } + run($script, "--toast-install-wrapper-only"); +} + sub compile($$$) { my($srcdir, $rootdir, $helperdir) = @_; compiledata($srcdir, $rootdir) || compilebin($srcdir, $rootdir) || compilehelp($srcdir, $rootdir, $helperdir); + wraphaskell($srcdir, $rootdir, $helperdir) if hspkg; polishrootdir($rootdir, armdir); } @@ -4135,7 +4174,7 @@ safechmod(0777, $etcdir); safechmod(0666, $file) if -e($file); writefile($file, "[]\n"); - optrun("ghc-pkg", "--force", "-f", $file, "register", $_) for(@pkgs); + optrun("ghc-pkg", "--force", "-f", $file, "update", $_) for(@pkgs); optrmall("$file.old"); safechmod($mode, $etcdir); @@ -6802,20 +6841,23 @@ =item S<B<--hspkg> | B<--nohspkg>> -When B<hspkg> is enabled, B<toast arm> and B<toast disarm> -will maintain a Haskell package database B<armdir> called +When B<hspkg> is enabled, B<toast build> will generate various terrible +wrapper scripts for ghc and related commands, and B<toast arm> and +B<toast disarm> will maintain a Haskell package database B<armdir> called C<etc/xml/toast-hs-package.conf>, whose presence and contents depend on the contents of B<armdir>'s C<hspkg> subdirectory, which in turn will be automatically populated by a wrapper script whenever a Haskell library -tries to register itself in the package database. If the package database -already exists, it may be overwritten or deleted. The B<toast env> -command will set C<HS_PKG_PATH> to point to this file when this option -is set, which will cause further wrapper scripts automatically installed -with Haskell libraries to insert a -package-conf argument into the command -lines of all the appropriate programs. If B<hspkg> is disabled, B<toast -arm> and B<toast disarm> will delete the C<toast-hs-package.conf> file, -if present, instead of rebuilding it. Tested with GHC 6.4. Default: -enabled. +built via B<toast build> tries to register itself in the package database. +If the package database already exists, it may be overwritten or deleted. +The B<toast env> command will set C<HS_PKG_PATH> to point to this file +when this option is set, which will cause wrapper scripts installed with +ghc and/or Haskell libraries to insert a --package-conf argument into +the command lines of some of the appropriate programs. If B<hspkg> is +disabled, B<toast build> will not attempt to generate any Haskell-specific +wrapper scripts (which may prevent Haskell libraries from building, at +least with GHC 6.4); B<toast arm> and B<toast disarm> will delete the +C<toast-hs-package.conf> file, if present, instead of rebuilding it. +Tested with GHC 6.4. Default: enabled. =item S<B<--protect> | B<--noprotect>>