##
##  wml::mod::MakeMaker - Create a Makefile to distribute your WML Modules
##  Copyright (c) 1999-2001 Denis Barbier, All Rights Reserved.
##

#  The <preserve>/<restore> tags with multiple arguments require WML 2.0.3
#use wml::mod::version
<require 2.0.3 />

#use wml::std::tags

##  Note for WML hackers:
##  This file MUST work with any version of WML, so take care that
##    * the <perl> tag has deeply changed after WML-1.7.4
##    * the ``:#FOO#}'' syntax did not work before WML-1.7.3

{#MK_DEFINITIONS#:
\# ------------------------------------------------
\#   DEFINITIONS
\# ------------------------------------------------

SHTOOL          = ./shtool
MKDIR           = $<suck/>(SHTOOL) mkdir -f -p -m 755
INSTALL_DATA    = $<suck/>(SHTOOL) install -c -m 644

includedir      = {#INCLUDEDIR#}
mandir          = {#MANDIR#}
manext          = {#MANEXT#}
srcext          = {#SRCEXT#}
modext          = {#MODEXT#}
DISTDIR         = $<suck/>(PACKAGE)-$<suck/>(VERSION)

FILES_SRC       = {#FILES_SRC#}
FILES_WML       = {#FILES_WML#}
FILES_MAN       = {#FILES_MAN#}
DISTFILES       = {#DISTFILES#}
CLEANFILES      = {#CLEANFILES#} $<suck/>(FILES_WML) $<suck/>(FILES_MAN)
INSTALLDIR      = {#INSTALLDIR#}
:##}

{#MK_ALL#:
all: modules doc

modules: $<suck/>(FILES_WML)

doc: $<suck/>(FILES_MAN)

$<suck/>(FILES_WML):
	@src=`echo $@ | sed -e 's/\.[^.]*$$/.$<suck/>(srcext)/'`; \\
	sed -e '/^=head1/,/^=cut/d' -e '/^__END__/,$$d' <$$src >$@

$<suck/>(FILES_MAN):
	@src=`echo $@ | sed -e 's/\.[^.]*$$/.$<suck/>(srcext)/'`; \\
	 podfile=`echo $@ | sed -e 's|\(.*\)/\(.*\)\.$<suck/>(manext)|$<suck/>(modext)::\1::\2.pod|'`; \\
	 cp $$src $$podfile; \\
	 pod2man --section=$<suck/>(manext) \\
	         --center="WML Modules" \\
	         --release="WML Modules" \\
	    $$podfile >$@; rm -f $$podfile
:##}

{#MK_INSTALL#:
install: shtool install-dir install-wml install-man

install-dir:
	@[ -z "$<suck/>(INSTALLDIR)" ] || $<suck/>(MKDIR) $<suck/>(includedir)/$<suck/>(INSTALLDIR)

install-wml:
	@[ -z "$<suck/>(FILES_WML)" ] || for file in $<suck/>(FILES_WML); do \\
            echo "$<suck/>(INSTALL_DATA) $$file $<suck/>(includedir)/$$file"; \\
	    $<suck/>(INSTALL_DATA) $$file $<suck/>(includedir)/$$file; \\
	 done

install-man:
	@[ -z "$<suck/>(FILES_MAN)" ] || for file in $<suck/>(FILES_MAN); do \\
	    manfile=`echo $$file | sed -e 's|\(.*\)/\(.*\)|$<suck/>(modext)::\1::\2|'`; \\
            echo "$<suck/>(INSTALL_DATA) $$file $<suck/>(mandir)/man$<suck/>(manext)/$$manfile"; \\
            $<suck/>(INSTALL_DATA) $$file $<suck/>(mandir)/man$<suck/>(manext)/$$manfile; \\
	 done
:##}

{#MK_CLEAN#:
clean:
	-[ -z "$<suck/>(CLEANFILES)" ] || rm -f $<suck/>(CLEANFILES)
:##}

{#MK_DISTCLEAN#:
distclean: clean
	-rm -f Makefile
:##}

#   This one is for you
{#MK_USER#::##}

{#MK_CONFIG#:
\# ------------------------------------------------
\#   THE CONFIG STUFF
\# ------------------------------------------------

shtool:
	@shtoolize mkdir install fixperm tarball

Makefile: Makefile.wml
	@wml -n -o Makefile Makefile.wml

:##}

{#MK_RELEASE#:
\# ------------------------------------------------
\#   THE RELEASE STUFF
\# ------------------------------------------------

fixperm:
	$<suck/>(SHTOOL) fixperm -v $<suck/>(DISTFILES)

dist: fixperm
	$<suck/>(SHTOOL) tarball -o $<suck/>(DISTDIR).tar.gz -d $<suck/>(DISTDIR) \\
	                  -u $(WML_SRC_USERNAME) -g $<suck/>(PACKAGE) \\
	                  -c 'gzip --best' $<suck/>(DISTFILES)

:##}

<define-tag default-value>
<preserve var value />
<set-var %attributes />
<when <not <get-var <get-var var /> /> />>
  <warning "
    The variable ``<get-var var />'' is not defined and its value \
    is assigned to ``<get-var value />''
  " />
  <set-var <get-var var />="<get-var value />" />
</when>
<restore  var value />
</define-tag>

<define-tag write-makefile>
<preserve package version modules src-ext man-ext extradistfiles />
<set-var src-ext="src" />
<set-var man-ext="3" />
<set-var %attributes />
<default-value var=package value=unknown />
<default-value var=version value="0.0" />
<default-value var=modules value="test.wml" />
<:
  {
    my $package = qq(<get-var package />);
    my $version = qq(<get-var version />);
    my $manext  = qq(<get-var man-ext />);
    my $srcext  = qq(<get-var src-ext />);
    my $extras  = qq(<get-var extradistfiles />);
    my @modules = qw(<get-var modules />);

    my ($wml, $infos, $includedir, $mandir, $installdir);
    my (@files_src, @files_wml, @files_man, $dir, $base, $suffix);
    my (@distfiles);

    print <<"EOT";
<nostrip>
\\##
\\##  This Makefile has been automatically generated by Makefile,wml
\\##  Do not edit
\\##

PACKAGE = $package
VERSION = $version
</nostrip>
EOT

    #    find installation paths
    $wml = $ENV{'WML'} || 'wml';
    {
        local ($/) = undef;
        open(INC, "$wml -q -V2 2>&1 |");
        $infos = <*INC>;
        close(INC, "$wml -V2|");
    }
    ($includedir) = ($infos =~ m|LibDir: ([^\n]+)\n|s);
    $includedir .= "/include";
    ($mandir) = ($infos =~ m|ManDir: ([^\n]+)\n|s);
    print "{#INCLUDEDIR#:$includedir:##}\n";
    print "{#MANDIR#:$mandir:##}\n";
    print "{#MANEXT#:$manext:##}\n";
    print "{#SRCEXT#:$srcext:##}\n";

    #   loop on module filenames
    @files_src = @files_wml = @files_man = @distfiles = ();
    foreach (@modules) {
        push(@files_wml, $_);
        if (m|/|) {
            ($dir, $base, $suffix) = m|(.*)/([^/]*)\.([^./]*)$|;
        }
        else {
            $dir = '.';
            ($base, $suffix) = m|(.*)\.([^.]*)$|;
        }
        $installdir = ${dir};
        push(@files_man, "$dir/$base.$manext");
        s/$suffix/$srcext/;
        push(@files_src, $_);
    }
    print "{#MODEXT#:$suffix:##}\n";
    print "{#FILES_SRC#:" . join(' ', @files_src) . ":##}\n";
    print "{#FILES_WML#:" . join(' ', @files_wml) . ":##}\n";
    print "{#FILES_MAN#:" . join(' ', @files_man) . ":##}\n";
    print "{#INSTALLDIR#:$installdir:##}\n";

    if (open(IN, "< MANIFEST")) {
        while(<*IN>) {
            chomp;
            s/^\s*(\S*).*$/\1/;
            push(@distfiles, $_);
        }
        close(IN);
    }
    else {
        @distfiles = split(' ', $extras);
        push(@distfiles, @files_src);
        foreach (qw(README shtool Makefile.wml MakeMaker.wml)) {
            push(@distfiles, $_) if -f $_;
        }
    }
    print "{#DISTFILES#:" . join(' ', @distfiles) . ":##}\n";
  }
:>
<nostrip>
{#MK_DEFINITIONS#}

\# ------------------------------------------------
\#   TARGETS
\# ------------------------------------------------
{#MK_ALL#}
{#MK_INSTALL#}
{#MK_CLEAN#}
{#MK_DISTCLEAN#}
{#MK_USER#}
{#MK_CONFIG#}
{#MK_RELEASE#}

\##EOF##
</nostrip>
<restore  package version modules src-ext man-ext extradistfiles />
</define-tag>

##EOF##
__END__

=head1 NAME

wml::mod::MakeMaker - A Makefile generator

=head1 SYNOPSIS

 #!wml -o Makefile
 #use wml::mod::MakeMaker

 <write-makefile [attributes]>

=head1 DESCRIPTION

This include file provides an easy way to write a Makefile to distribute
your own WML modules. It is inspired by the C<ExtUtils::MakeMaker> Perl
module.

=head2 Default targets

=over 4

=item B<make all>

This is the default target. It will build all include files and their
documentation.

=item B<make install>

Install include files and documentation in the locations given by ``wml -V2''.

=item B<make clean>

Remove files generated by B<make>.

=item B<make distclean>

Like B<make clean>, plus remove the F<Makefile> too.

=item B<make dist>

Build a distribution. Should only be used by the module maintainer.
If there is a F<MANIFEST> file, then the list of files to include is
taken from this file. Otherwise the tarball contains all source files,
plus F<MakeMaker.wml>, F<Makefile.wml>, F<shtool> and F<README> if these
files exist.

=back

=head2 Overriding default targets

To build the F<Makefile>, all targets are put in separate buffers during
pass 3, and those buffers are diverted by pass 5. You can override this
defaukt target by redefining buffer contents.
Buffer names are explicit:

    MK_ALL MK_INSTALL MK_CLEAN MK_DISTCLEAN MK_CONFIG MK_RELEASE

=head2 Defining new targets

The B<MK_USER> is empty and devoted to this task.

=head1 ATTRIBUTES

The first three attributes are mandatory.

=over 4

=item B<package>

The name of the package

=item B<version>

Its version number

=item B<modules>

List of modules to build and install. This is a space separated list of
filenames. Modules should reside in a sub-directory to be compliant with
actual file hierarchy. For instance, the declaration

     modules="math/log.tmpl math/exp.tmpl"

tells that after compilation, there are two modules which are
C<math/log.tmpl> and C<math/exp.tmpl>. This modules will be installed to
C<LibDir/include/math/log.tmpl> and C<LibDir/include/math/exp.tmpl>.

These modules will then be called in a WML file by

    #use tmpl::math::log
    #use tmpl::math::exp

Source files for these modules are obtained by replacing the suffix by
I<.src>.

=item B<src-ext>

Defines an alternate suffix for the source files.

=item B<man-ext>

Section number of the manual in which man files are put. Default is 3.

=item B<extradistfiles>

Space separated list of files to include in a distribution. By default,
all source files plus F<MakeMaker.wml>, F<Makefile.wml>,  F<README> and
F<shtool> are included in a distribution.

=back

=head1 EXAMPLE

 <write-makefile
    package="log"
    version="3.14"
    modules="math/log.tmpl"
    source-ext="exp"
 >

This will build the B<tmpl::math::log> include module from the
F<math/log.exp> source file. This source file will also produce the
B<tmpl::math::log(3)> manpage.

=head1 NOTES

Please do _not_ use a C<.wml> suffix for your modules, they should be reserved
for official WML modules shipped with WML. You may instead put your initials or
anything else.

=head1 AUTHOR

 Denis Barbier
 barbier@engelschall.com

=head1 REQUIRES

 Internal: P1, P2, P3, P5
 External: --

=cut

