GNU Make 4.0 released, including support for plugins

Posted by Steve on Sun 11 May 2014 at 11:31

Tags:

The new upload of GNU Make 4.0 recently reached Debian's unstable distribution, and has also migrated to the testing distribution, currently codenamed "jessie". GNU Make 4.0 brings in several new features, perhaps the most interesting of which is support for the use of plugins.

A full changelog for the package is perhaps out of our scope, but significant highlights include:

  • Support for Guile inside Makefiles.
  • Support for plugins, written in C.

In addition to this there are several bug-fixes, and similar minor updates. There is a nice writeup of the features in this whats new in GNU Make 4.0 blog entry.

The ultimate goal of enabling plugins in Make is to allow more complex operations to be carried out, but this is just a preview with the ability to support adding dynamic functions to your Makefile - supported by shared libraries.

In the future it might be possible to make more extensive plugins, which would use SHA1 hashes instead of timestamps, etc. For the moment though adding simple fuctions to Makefiles is both powerful and interesting.

To get started we're going to look at writing a simple extension which will generate a temporary file, and allow the name of that file to be returned to your Makefile.

Here is the plugin code:

#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <gnumake.h>

int plugin_is_GPL_compatible;

char *
gen_tmpfile(const char *nm, unsigned int argc, char **argv)
{
    int fd;

    /* Compute the size of the filename and allocate space for it.  */
    int len = strlen (argv[0]) + 6 + 1;
    char *buf = gmk_alloc (len);

    strcpy (buf, argv[0]);
    strcat (buf, "XXXXXX");

    fd = mkstemp(buf);
    if (fd >= 0)
    {
        /* Don't leak the file descriptor.  */
        close (fd);
        return buf;
    }

    /* Failure.  */
    fprintf (stderr, "mkstemp(%s) failed: %s\n", buf, strerror (errno));
    gmk_free (buf);
    return NULL;
}

int
mk_temp_gmk_setup ()
{
    /* Register the function with make name "mk-temp".  */
    gmk_add_function ("mk-temp", gen_tmpfile, 1, 1, 1);
    return 1;
}

To build and use this plugin we're going to need a Makefile, and this is the one we'll use:

#
#  Build the shared library
#
mk_temp.so: mk_temp.c
	$(CC) -I. -shared -fPIC -o mk_temp.so mk_temp.c


#
#  Use the shared library in a trivial test fasion
#
test: mk_temp.so
	@echo Temporary file: $(mk-temp tmpfile.)

#
#  If we're running `make test` load the plugin.
#
ifeq ($(MAKECMDGOALS),test)
load mk_temp.so
endif

With these two files we can run the following to build the plugin, and then invoke it:

$ make
cc -I. -shared -fPIC -o mk_temp.so mk_temp.c

$ make test
Temporary file: tmpfile.vMUZVv

This is just the bare minimum, but you could easily imagine a plugin which would get the git-tag from a source tree, or allow you to invoke some code written in Perl, Lua, or some similar embedded code.

(As an example of invoking Perl you can consult gmk-perl, on github.)

In short many new options are available, and the official GNU Make documentation contains a chapter on the plugin API, along with a brief introduction to the general plugin overview.

 

 


Posted by Anonymous (77.95.xx.xx) on Mon 12 May 2014 at 09:58

[ Parent | Reply to this comment ]

Posted by Steve (176.27.xx.xx) on Mon 12 May 2014 at 10:01
[ View Steve's Scratchpad | View Weblogs ]

Very nice, thanks for sharing (I have an interest in Lua these days, thanks to my console mail-client.)

PS. Looks like make-guile is in the NEW-queue at the moment, and will be available in the Debian archive soon.

Steve

[ Parent | Reply to this comment ]

Posted by Anonymous (68.58.xx.xx) on Fri 16 May 2014 at 02:34
I'm waiting for the flash plugin so I can watch YouTube while my code compiles.

[ Parent | Reply to this comment ]

Sign In

Username:

Password:

[Register|Advanced]

 

Flattr

 

Current Poll

What do you use for configuration management?








( 472 votes ~ 5 comments )