=item B { I }[ I, ...];
Output those lines from all files, for which I returns true.
=item B;
Simply fail.
=item B>[, -r|--reverse][, -u|--uniq|--unique][, I, ...];
=item B { I }[ -r|--reverse,][ -u|--uniq|--unique,][ I, ...];
Sort the lines of all files together. In the first case, the default sort
order is used. In the second a programmed order as in the Perl sort
function is used.
=item B I[, I, ...];
=item B B>/I/[, I, ...];
=item B I[, I, ...];
=item B B>/I/[, I, ...];
Output the lines respectively from one to I, or from I to end
of each file. If number is negative, it is counted from the end of each file.
The I variants will instead go up to or from the first matching line.
=item B I, ...;
Creates each I and any required parent directories. (cf. Unix
mkdir -p) I if you really need the original.>
=item B[ -d|--delimiter=I,] I, ...;
Paste all lines from each file side by side. They get separated by
I, which defaults to tabulator.
=item B[ I

, ...];
=for later item B[ I

, ...];
=for later item B[ I

, ...];
=for later item B[ I

, ...];
=item B[ I

, ...];
Identical to the respective external Perl programs.
=item B[ -l|--lines,][ I, ...];
Reverse the characters on each line, or with the options the lines among all
files.
=item B I|I, ...;
Removes each I or I with contents. Doesn't complain about
missing files. (cf. Unix rm -fr)
=item B { I }[ I, ...];
Performs I for each line of each I, and outputs the result.
It should modify C, like C or C

. (cf. Unix sed or perl -pe)
=item B %{{ I => I, ... }}[, I

, ...,][ I, ...];
=item B I[, I

, ...,][ I, ...];
Find all the occurences of the keys from the hash in either form, delimited by
an immediately leading and trailing @. Replace all these occurences, from all
the files, with the associated value. Options are:
=for html

=over
=item B, B=I use I as key prefix, instead of @
=item B, B=I use I as key suffix, instead of @
=back
=for html

=item B I, ...;
Sets the access and modification time for each I to now, creating those
that don't exist.
=item B[ I, ...];
Output those lines from all files which differ from the preceding one.
=back
=head2 External Commands
=over
=item B[ -f|--first|-l|--last,] I, ...;
This can take one or more arguments, and Perl will execute the list. To
eliminate repeated arguments, use --first to keep only the first occurence of
each, or --last to keep only the last.
=item B -c|--command => I, ...;
In the second form the arguments are joined into one string, separated by
semicolons. This string is passed to a shell for execution. If it contains
no shell metacharacters, Perl emulates the shell. Do not call something like
sh 'ls -l';
when you want one of
sh qw'ls -l';
sh -c => 'ls -l';
=back
=head2 Adding Commands
=over
=item B command> I => I;
=item B command> I => B> { I };
These create a function of name I, which calls I or
I with make.pl command semantics. The I or
I can C, C or C. Dying is turned into a make.pl error.
=item B command> I;
=item B command> I => B>(I);
These create a function of name I, which is an alias to an external
command. In the first form the external command name is identical to the
function name. In the second case it may be different, and/or may have
additional arguments.
=back
=head2 Command Modifiers
=over
=item B { I } I, ...;
You can place builtin or external shell commands (e.g. within rules) into such
a block, to redirect their I/O. The old settings get restored afterwards.
Note that this is technically not a block, but a closure. This means that the
outer C is not available, but my-variables are.
The I arguments are performed back to front, allowing you to do
pipelines. If I is the empty string, this prevents the commands from
being echoed, as with the --silent command line option.
As in Shell, a I of '&-' and '2>&-' will close STDIN, STDOUT and
STDERR respectively.
The other modes are almost as for the open function. A I starting with
'>', '+>', '+. A I
starting with '2>', '2+>', '2+ as C, I ...]>, to use the
multiple argument form of open.
=item B { I }[ I];
You can place builtin or external shell commands (e.g. within rules) into such
a block. Optional level is either B<0> -- override englobing ignore_errors;
B<1>, the default -- prevents the commands' return value from being acted on;
B<2> -- error return code is not even shown. I in make.>
=back
=head1 EXAMPLES
This makes any intermediate .o file when needed, from the corresponding .c
source:
rule {
my $source = $_[0];
my $target = $_[-1]; # may have more than 2 args from static rules
sh -c => 'gcc -c -o', $target, $source;
} '.c' => qr/\.o$/;
This makes F from all present object files:
rule undef, => 'myprog'; # wrong, maybe none are built yet
rule undef, sub { } => 'myprog'; # closer but wrong
rule undef, sub { grep s/c$/o/, } => 'myprog'; # correct for C
This makes F from F, F, F, F, F, which are
themselves implicitly made from any available sources:
rule undef, \@more_C_objects, \$eno => 'myprog';
@more_C_objects = (qw(a.o b.o c.o), \$do);
$do = 'd.o';
$eno = sub { "e$n.o" };
$n = 3;
This defines analogous static rules with a varying component, here in a
maximum of places, the Perl code, several prerequisites and the target:
rule { print "$_.a\n" } "$_.b", "$_.c", 'config.h' => "$_.z"
for qw(src1 src2 srcn);
This gives you another builtin command:
use command nop => sub { print "I do nothing\n" }
This will first print to the file, and then edit the file inplace, without
echoing the sed command:
io { print 'hallo' } ">$file";
io { sed { tr/a/e/ } $file } '', ['+ outfile';
This will extract the header and signature of each file in email format:
egrep { 1../^$/ or /^-- /..eof } file, ...;
=head1 TODO
Precompile files and extract dependency list (cpp-style and open for handling
anything).
Try to look which files from the same directory can be compiled with one call
to the compiler (idea thanks to Nadim Khemir). I'm not sure how this fits in
with my rules, nor with using an intermediate directory...
Optionally stop after reading all makefiles (and autoloading every command)
waiting for targets from fifo and forking (idea from ant server).
Have more predicates for eliminating compilations and getting away from only
files:
=over
=item * file-signature-based, rather than modification-time based. In fact
I'm starting to believe, this should be the only criterion for files.
=item * compare arbitrary objects with some method
=back
Handle parallelization (hopefully easy with threads) and subdirectories
(package and threads vs. fork? chdir probably forces us to fork).
Extend sh() to transparently distribute to various machines.
Have a builtin B command, since that is not standard, and, when
available, named differently of different machines. Also:
cut undef|{ split /regexp/ } [-o outfile1,] [-o outfile2,] ..., infile, ...;
ncp url|file ... url|directory # with LWP::UserAgent
$COMMAND{yacc} = determine YACC => 'yacc', [$COMMAND{bison}, '-y'];
$COMMAND{bison} = determine BISON => 'bison';
# fsort:
my @data = map $_->[0],
sort { $a->[1] <=> $b->[1] || # second column-numeric
$a->[2] <=> $b->[2] || # third column-numeric
$a->[3] <=> $b->[3] # fourth column-numeric
}
map [ $_, (split)[1, 2, 3] ], ;
Command make for building self-contained subprojects.
Give it all the rules and external variables (CFLAGS, ... -- optionally?) of
GNU make.
Turn it into one or two modules, so that a makefile can itself be a standalone
Perl program.
Somebody should write a simple makedepend-style makefile parser.
Somebody might use Perl's XML-capabilities for writing an ant-makefile parser.
Teach ExtUtils::MakeMaker to generate this.
Maybe support an interpreter linked to gcc, performing almost everything in a
single process.
=head1 AUTHOR
Daniel Pfeiffer
=begin CPAN
=head1 README
Make with Perl as the rule language. Write a B in Perl syntax. Or, write a program that among others does a few B things.
http://dapfy.bei.t-online.de/make.pl/
=pod SCRIPT CATEGORIES
UNIX/System_administration
VersionControl/CVS
Win32/Utilities