make: Loaded Object Example

 
 12.2.4 Example Loaded Object
 ----------------------------
 
 Let's suppose we wanted to write a new GNU 'make' function that would
 create a temporary file and return its name.  We would like our function
 to take a prefix as an argument.  First we can write the function in a
 file 'mk_temp.c':
 
      #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, 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;
      }
 
    Next, we will write a makefile that can build this shared object,
 load it, and use it:
 
      all:
              @echo Temporary file: $(mk-temp tmpfile.)
 
      load mk_temp.so
 
      mk_temp.so: mk_temp.c
              $(CC) -shared -fPIC -o $ $<
 
    On MS-Windows, due to peculiarities of how shared objects are
 produced, the compiler needs to scan the "import library" produced when
 building 'make', typically called 'libgnumake-VERSION.dll.a', where
 VERSION is the version of the load object API. So the recipe to produce
 a shared object will look on Windows like this (assuming the API version
 is 1):
 
      mk_temp.dll: mk_temp.c
              $(CC) -shared -o $ $< -lgnumake-1
 
    Now when you run 'make' you'll see something like:
 
      $ make
      cc -shared -fPIC -o mk_temp.so mk_temp.c
      Temporary filename: tmpfile.A7JEwd