The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.


Make - Pure-Perl implementation of a somewhat GNU-like make.


    require Make;
    my $make = Make->new;

    # to see what it would have done
    print $make->Script(@ARGV);

    # to see an expanded version of the makefile

    my $targ = $make->target($name);
    my $rule = Make::Rule->new(':', \@prereqs, \@recipe, \@recipe_raw);
    my @rules = @{ $targ->rules };

    my @prereqs  = @{ $rule->prereqs };
    my @commands = @{ $rule->recipe };


Implements in pure Perl a somewhat GNU-like make, intended to be highly customisable.

Via pure-perl-make Make has built perl/Tk from the MakeMaker generated Makefiles...


Broadly, there are macros, directives, and rules (including recipes).


    varname = value


    vpath %.c src/%.c
    [-]include # - means no warn on failure to include

Please note the vpath does not have the GNU-make behaviour of discarding the found path if an inferred target must be rebuilt, since this is too non-deterministic / confusing behaviour for this author.


    target : prerequisite1 prerequisite2[; immediate recipe]
    (tab character)follow-on recipe...

Recipe lines can start with @ (do not echo), - (continue on failure).

In addition to traditional

        .c.o :
                $(CC) -c ...

GNU make's 'pattern' rules e.g.

        %.o : %.c
                $(CC) -c ...

The former gets internally translated to the latter.


There are other methods (used by parse) which can be used to add and manipulate targets and their prerequites.


Class method, takes pairs of arguments in name/value form. Arguments:


A hash-ref of values that sets variables, overridable by the makefile.


Number of concurrent jobs to run while building. Not implemented.


If true, then GNUmakefile is looked for first.


Array-ref of package names to search for GNU-make style functions. Defaults to Make::Functions.


Hash-ref of file-system functions by which to access the file-system. Created to help testing, but might be more widely useful. Defaults to code accessing the actual local filesystem. The various functions are expected to return real Perl filehandles. Relevant keys: glob, fh_open, fh_write, mtime, file_readable, is_abs.


Optional. If supplied, will be treated as the current directory instead of the default which is the real current directory.


Array-ref of functions to be called in order, searching an expanded recipe line for a recursive make invocation (cf Recursive Make Considered Harmful) that would run a make in a subdirectory. Each returns either an empty list, or

    ($dir, $makefile, $vars, $targets)

The $makefile might be <undef>, in which case the default will be searched for. $vars and $targets are array-refs of pairs and strings, respectively. The $targets can be empty.

Defaults to a single, somewhat-suitable, function.


Parses the given makefile. If none or undef, these files will be tried, in order: GNUmakefile if "GNU", makefile, Makefile.

If a scalar-ref, will be makefile text.

Returns the make object for chaining.


Given a target-name, builds the target(s) specified, or the first 'real' target in the makefile.


Print to current select'ed stream a form of the makefile with all variables expanded.


Print to current select'ed stream the equivalent bourne shell script that a make would perform i.e. the output of make -n.


Given a name and value, sets the variable to that.

May gain a "type" parameter to distinguish immediately-expanded from recursively-expanded (the default).


Uses "subsvars" to return its only arg with any macros expanded.


Find or create Make::Target for given target-name.


Returns boolean on whether the given target-name is known to this object.


List all "real" (non-dot, non-inference) target-names known to this object at the time called, unsorted. Note this might change when Make is called, as targets will be added as part of the dependency-search process.


Search registered pattern-rules for one matching given target-name. Returns a Make::Rule for that of the given kind, or false.

Uses GNU make's "exists or can be made" algorithm on each rule's proposed requisite to see if that rule matches.


    my @found = $make->find_recursive_makes;

Iterate over all the rules, expanding them for their targets, and find any recursive make invocations using the "RecursiveMakeFinders".

Returns a list of array-refs with:

    [ $from_target, $rule_index, $line_index, $dir, $makefile, $vars, $targets ]


These are read-only.


Returns a hash-ref of the current set of variables.


Returns an array-ref of the packages to search for macro functions.


Returns a hash-ref of the "FSFunctionMap".


Returns a Graph::Directed object representing the makefile. Takes options as a hash:


If true (default false), uses "RecursiveMakeFinders" to find recursive make invocations in the current makefile, parses those, then includes them, with an edge created to the relevant target.


If true, the graph will only have target vertices, but will be "multiedged". The edges will have an ID of the zero-based index of the rule on the predecessor target, and will have attributes recipe and recipe_raw. Rules with no prerequisites will be indicated with an edge back to the same target.

If false (the default), the vertices are named either target:name (representing Make::Targets) or rule:name:rule_index (representing Make::Rules). The names encoded with "name_encode". Rules are named according to the first (alphabetically) target they are attached to.

The rule vertices have attributes with the same values as the Make::Rule attributes:





    my $encoded = Make::name_encode([ 'target', 'all' ]);
    my $tuple = Make::name_decode($encoded); # [ 'target', 'all' ]

Uses %-encoding and -decoding to allow % and : characters in components without problems.


Given a file-handle, returns array-ref of Abstract Syntax-Tree (AST) fragments, representing the contents of that file. Each is an array-ref whose first element is the node-type (comment, include, vpath, var, rule), followed by relevant data.


Given a line, returns array-ref of the space-separated "tokens". Also splits on any further args.


    my $expanded = Make::subsvars(
        'hi $(shell echo there)',
        [ \%vars ],
    # "hi there"

Given a piece of text, will substitute any macros in it, either a single-character macro, or surrounded by either {} or (). These can be nested. Uses the array-ref as a list of hashes to search for values.

If the macro is of form $(varname:a=b), then this will be a GNU (and others) make-style "substitution reference". First "varname" will be expanded. Then all occurrences of "a" at the end of words within the expanded text will be replaced with "b". This is intended for file suffixes.

For GNU-make style functions, see Make::Functions.


To see debugging messages on STDERR, set environment variable MAKE_DEBUG to a true value;


More attention needs to be given to using the package to write makefiles.

The rules for matching 'dot rules' e.g. .c.o and/or pattern rules e.g. %.o : %.c are suspect. For example give a choice of .xs.o vs .xs.c + .c.o behaviour seems a little odd.


pure-perl-make POSIX standard for make GNU make docs


Nick Ing-Simmons


Copyright (c) 1996-1999 Nick Ing-Simmons.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.