Esempio n. 1
0
void process(struct processor *p_uncast, const char *filename,
             struct stack *s, struct makefile *m)
{
    struct processor_pdfcrop *p;
    void *c;
    int cachedir_index;
    char *cachedir;
    char *infile;

    /* We need access to the real structure, get it safely */
    p = talloc_get_type(p_uncast, struct processor_pdfcrop);

    /* Makes a new context */
    c = talloc_new(p);

    /* Finds the original filename */
    cachedir_index = string_index(filename, ".tek_cache/");
    if (cachedir_index == -1) {
        fprintf(stderr, "Bad cachedir for image\n");
        return;
    }

    cachedir = talloc_strdup(c, filename);
    cachedir[cachedir_index + strlen(".tex_cache/")] = '\0';

    infile = talloc_strdup(c, filename);
    infile[cachedir_index] = '\0';
    strcat(infile, filename + strlen(cachedir));
    infile[strlen(infile) - 4] = '\0';

    TALLOC_FREE(cachedir);
    cachedir = talloc_strndup(c, filename, basename_len(filename));

    /* Creates the target to build the image */
    makefile_create_target(m, filename);
    makefile_start_deps(m);
    makefile_add_dep(m, infile);
    makefile_end_deps(m);

    makefile_start_cmds(m);
    makefile_nam_cmd(m, "echo -e \"PDFCROP\\t%s\"", infile);
    makefile_add_cmd(m, "mkdir -p \"%s\" >& /dev/null || true", cachedir);
    makefile_add_cmd(m, "pdfcrop \"%s\" \"%s\" >& /dev/null",
                     infile, filename);
    makefile_end_cmds(m);

    /* Cleans up all the memory allocated by this code. */
    TALLOC_FREE(c);
}
Esempio n. 2
0
int context_test_destructor(struct context *c)
{
    struct language *l;
    void *context;
    const char *hash_langlinkopts, *hash_linkopts, *hash_objs;

    assert(c->type == CONTEXT_TYPE_TEST);
#ifdef DEBUG
    fprintf(stderr, "context_test_destructor('%s')\n", c->full_path);
#endif

    l = c->language;
    assert(l != NULL);

    context = talloc_new(NULL);

#ifdef DEBUG
    stringlist_fprintf(c->objects, stderr, "obj: %s\n");
#endif

    hash_langlinkopts = stringlist_hashcode(c->language->link_opts, context);
    hash_linkopts = stringlist_hashcode(c->link_opts, context);
    hash_objs = stringlist_hashcode(c->objects, context);
    talloc_unlink(c, (char *)c->link_path);
    c->link_path = talloc_asprintf(c, "%s/%s/%s-%s-%s.bin",
                                   c->obj_dir, c->full_path,
                                   hash_langlinkopts, hash_linkopts,
                                   hash_objs);
    c->link_path_install = talloc_asprintf(c, "%s/%s/%s-%s-%s.ins/%s",
                                           c->obj_dir, c->full_path,
                                           hash_langlinkopts, hash_linkopts,
                                           hash_objs, c->full_path);

    makefile_add_targets(c->mf, c->full_path);
    makefile_add_check(c->mf, c->full_path);

    /* Run the test, producing a tarball with the results. */
    makefile_create_target(c->mf, c->full_path);
    makefile_start_deps(c->mf);
    makefile_add_dep(c->mf, "%s", c->test_parent->full_path);
    makefile_add_dep(c->mf, "%s", c->link_path);
    makefile_addl_dep(c->mf, c->testdeps, "%%s");
    makefile_end_deps(c->mf);
    makefile_start_cmds(c->mf);
    makefile_nam_cmd(c->mf, "echo \"TEST\t%s\"",
                     c->full_path + strlen(c->chk_dir) + 1);
    makefile_add_cmd(c->mf, "mkdir -p `dirname %s`", c->full_path);
    makefile_add_cmd(c->mf, "ptest --test %s --out %s --bin %s",
                     c->link_path, c->full_path, c->test_parent->full_path);
    makefile_end_cmds(c->mf);

    /* Does the actual linking with hashes of the arguments */
    makefile_create_target(c->mf, c->link_path);

    makefile_start_deps(c->mf);
    makefile_addl_dep(c->mf, c->objects, "%%s");
    makefile_addl_dep(c->mf, c->libraries, "%s/lib%%s.%s",
                      c->lib_dir, l->so_ext);
    makefile_end_deps(c->mf);

    makefile_start_cmds(c->mf);
    language_link_pass_vcmd(l, c, false);
    makefile_end_cmds(c->mf);

    makefile_add_distclean(c->mf, c->chk_dir);

    TALLOC_FREE(context);
    return 0;
}
Esempio n. 3
0
int context_source_destructor(struct context *c)
{
    struct language *l;
    void *context;
    const char *obj_name;

    assert(c->type == CONTEXT_TYPE_SOURCE);
#ifdef DEBUG
    fprintf(stderr, "context_source_destructor('%s', '%s')\n",
            c->full_path, c->parent->full_path);
#endif

    /* Try to find a language that's compatible with the language already used
     * in this binary, and is compatible with this current source file. */
    l = languagelist_search(c->ll, c->parent->language, c->full_path, c);
    if (l == NULL) {
        fprintf(stderr, "No language found for '%s'\n", c->full_path);

        if ((c->parent == NULL) || (c->parent->language == NULL))
            abort();

        fprintf(stderr, "Parent language is '%s', from '%s'\n",
                c->parent->language->name, c->parent->full_path);
        abort();
    }
    c->parent->language = l;
#ifdef DEBUG
    fprintf(stderr, "\tc->parent->language->name: '%s'\n",
            c->parent->language->name);
#endif

    /* Try and figure out if the grandparent of this code should be a
     * shared or static library. */
    if (l->cares_about_static == true) {
        struct context *lc;

        lc = c;
        while (lc != NULL) {
            if (lc->type == CONTEXT_TYPE_LIBRARY)
                break;

            if (lc->parent == lc) {
                lc = NULL;
                break;
            }

            lc = lc->parent;
        }

        /* It's very possible we ended up with something that
         * _doesn't_ target a library, which is perfectly fine. */
        if (lc != NULL) {
            char *ext;

            ext = strstr(lc->full_path, ".");
            if (ext == NULL)
                abort();
            ext++;

            if (strcmp(ext, lc->language->so_ext_canon) == 0)
                c->shared_target = true;
            else if (strcmp(ext, lc->language->a_ext_canon) == 0)
                c->shared_target = false;
            else
                abort();
        }
    }

    /* We need to allocate some temporary memory */
    context = talloc_new(NULL);

    /* Some languages don't need to be compiled (just linked) so we skip the
     * entire compiling phase. */
    if (language_needs_compile(l, c) == true) {
        /* This is the name that our code will be compiled into.  This must
         * succeed, as we just checked that it's necessary. */
        obj_name = language_objname(l, context, c);
        assert(obj_name != NULL);

        /* This handles half of the whole "--binname --objname" stuff,
         * which is why it's so messy! */
        if (found_binary && c->called_path != NULL) {
            if (strcmp(c->called_path, o->srcname) == 0) {
                printf("%s\n", obj_name);
                talloc_disable_null_tracking();
                exit(0);
            }
        }

        /* If we've already built this dependency, then it's not necessary to
         * add it to the build list again, so skip it. */
        if (!stringlist_include(c->mf->targets, obj_name)) {
            makefile_add_targets(c->mf, obj_name);
            makefile_create_target(c->mf, obj_name);

            makefile_start_deps(c->mf);
            language_deps_vadd_dep(l, c, c->mf);
            makefile_end_deps(c->mf);

            makefile_start_cmds(c->mf);
            language_build_pass_vcmd(l, c);
            makefile_end_cmds(c->mf);

            makefile_add_targets(c->mf, obj_name);
            makefile_add_clean(c->mf, obj_name);
            makefile_add_cleancache(c->mf, c->obj_dir);
        }
    } else {
        /* The "objects" for languages that aren't compiled are really just the
         * included sources. */
        obj_name = talloc_reference(context, c->full_path);
    }

    /* Adds every "extra" (which is defined as any other sources that should be 
     * linked in as a result of this SOURCES += line) to the stack. */
    if (stringlist_include(c->parent->objects, obj_name) == false) {
        language_extras_pass_cs_push_fs(l, c, context, c->s);
        stringlist_add(c->parent->objects, obj_name);
    }

    /* Run some language-specific quirks here */
    language_quirks(l, c, c->mf);

    /* Everything succeeded! */
    TALLOC_FREE(context);
    return 0;
}
Esempio n. 4
0
int context_library_destructor(struct context *c)
{
    struct language *l;
    char *tmp;
    void *context;
    const char *hash_langlinkopts, *hash_linkopts, *hash_objs;
    char *sname;

    assert(c->type == CONTEXT_TYPE_LIBRARY);

#ifdef DEBUG
    fprintf(stderr, "context_library_destructor('%s')\n", c->full_path);
#endif

    l = c->language;
    assert(l != NULL);

    context = talloc_new(NULL);

    /* Checks if the library name doesn't match and attempts to
     * correct it. */
    if (l->cares_about_static == true) {
        char *new_name;
        char *old_name;
        char *ext;
        char *without_slash;

        old_name = talloc_strdup(context, c->full_path);

        if (strstr(old_name, ".") == NULL)
            abort();

        if (strcmp(strstr(old_name, ".") + 1, c->language->so_ext_canon) == 0)
            c->shared_target = true;
        else if (strcmp(strstr(old_name, ".") + 1, c->language->a_ext_canon)
                 == 0)
            c->shared_target = false;
        else
            abort();

        strstr(old_name, ".")[0] = '\0';

        without_slash = old_name;
        while (strstr(without_slash, "/") != NULL)
            without_slash = strstr(without_slash, "/") + 1;

        ext = c->shared_target ? c->language->so_ext : c->language->a_ext;
        new_name = talloc_asprintf(c, "%s.%s", old_name, ext);

        fprintf(c->mf->file, "LIBDEP__%s := %s.%s\n",
                without_slash,
                old_name, ext);

        c->full_path = new_name;
    }

#ifdef DEBUG
    stringlist_fprintf(c->objects, stderr, "%s\n");
#endif

    hash_langlinkopts = stringlist_hashcode(c->language->link_opts, context);
    hash_linkopts = stringlist_hashcode(c->link_opts, context);
    hash_objs = stringlist_hashcode(c->objects, context);
    talloc_unlink(c, (char *)c->link_path);
    c->link_path = talloc_asprintf(c, "%s/%s/%s-%s-%s-shared.%s",
                                   c->obj_dir, c->full_path,
                                   hash_langlinkopts, hash_linkopts,
                                   hash_objs, c->language->so_ext);

    makefile_add_targets(c->mf, c->full_path);
    makefile_add_all(c->mf, c->full_path);

    /* Creates a "dummy" target that just copies over the actual binary */
    makefile_create_target(c->mf, c->full_path);
    makefile_start_deps(c->mf);
    makefile_add_dep(c->mf, "%s", c->link_path);
    makefile_add_dep(c->mf, "Makefile");
    makefile_end_deps(c->mf);
    makefile_start_cmds(c->mf);
    makefile_nam_cmd(c->mf, "echo \"CP\t%s\"",
                     c->full_path + strlen(c->lib_dir) + 1);
    makefile_add_cmd(c->mf, "mkdir -p `dirname %s`", c->full_path);
    makefile_add_cmd(c->mf, "cp %s %s", c->link_path, c->full_path);
    makefile_end_cmds(c->mf);

    /* Does the actual linking with hashes of the arguments */
    makefile_create_target(c->mf, c->link_path);

    makefile_start_deps(c->mf);

    makefile_addl_dep(c->mf, c->objects, "%%s");

    /* If the language isn't compiled then we won't detect any changes
     * when we try and build it -- it'll just get copied.  In this
     * case we're just going to force a dependency on the Makefile, as
     * that'll ensure it gets built. */
    if (!language_needs_compile(l, c)) {
        makefile_add_dep(c->mf, "Makefile");
        language_deps_vadd_dep(l, c, c->mf);
    }

    makefile_end_deps(c->mf);

    makefile_start_cmds(c->mf);
    language_slib_pass_vcmd(l, c);
    makefile_end_cmds(c->mf);

    /* There is an install/uninstall target */
    tmp = talloc_asprintf(context, "echo -e \"INS\\t%s\"", c->full_path);
    makefile_add_install(c->mf, tmp);
    tmp = talloc_asprintf(context,
                          "mkdir -p `dirname $D\"%s/%s\"` >& /dev/null || true",
                          c->prefix, c->full_path);
    makefile_add_install(c->mf, tmp);
    tmp =
        talloc_asprintf(context,
                        "install -m a=r %s $D/`dirname \"%s/%s\"`",
                        c->full_path, c->prefix, c->full_path);
    makefile_add_install(c->mf, tmp);

    tmp = talloc_asprintf(context, "%s/%s", c->prefix, c->full_path);
    makefile_add_uninstall(c->mf, tmp);

    makefile_add_distclean(c->mf, c->lib_dir);

    /* Add this library to the big global list of libraries.  The idea
     * here is that we can handle recursive library dependencies this
     * way. */
    sname = talloc_strndup(context, c->called_path + 3,
                           strstr(c->called_path + 3, ".")
                           - (c->called_path + 3));

    if (lib_deps == NULL) {
        lib_deps_ctx = talloc_init("context_library_destructor(): lib_deps");
        atexit(&context_destructor);
        lib_deps = liblist_new(lib_deps_ctx);
    }

    liblist_add(lib_deps, sname);

    stringlist_add_to_liblist(c->libraries, lib_deps, sname);

    TALLOC_FREE(context);
    return 0;
}
Esempio n. 5
0
int context_binary_destructor(struct context *c)
{
    struct language *l;
    char *tmp;
    void *context;
    const char *hash_langlinkopts, *hash_linkopts, *hash_objs;

    assert(c->type == CONTEXT_TYPE_BINARY);
#ifdef DEBUG
    fprintf(stderr, "context_binary_destructor('%s')\n", c->full_path);
#endif

    l = c->language;
    assert(l != NULL);

    context = talloc_new(NULL);

#ifdef DEBUG
    stringlist_fprintf(c->objects, stderr, "obj: %s\n");
#endif

    hash_langlinkopts = stringlist_hashcode(c->language->link_opts, context);
    hash_linkopts = stringlist_hashcode(c->link_opts, context);
    hash_objs = stringlist_hashcode(c->objects, context);
    talloc_unlink(c, (char *)c->link_path);
    c->link_path = talloc_asprintf(c, "%s/%s/%s-%s-%s.bin",
                                   c->obj_dir, c->full_path,
                                   hash_langlinkopts, hash_linkopts,
                                   hash_objs);
    c->link_path_install = talloc_asprintf(c, "%s/%s/%s-%s-%s.ins/%s",
                                           c->obj_dir, c->full_path,
                                           hash_langlinkopts, hash_linkopts,
                                           hash_objs, c->full_path);

    makefile_add_targets(c->mf, c->full_path);
    makefile_add_all(c->mf, c->full_path);
    makefile_add_all_install(c->mf, c->link_path_install);

    /* Creates a "dummy" target that just copies over the actual binary */
    makefile_create_target(c->mf, c->full_path);
    makefile_start_deps(c->mf);
    makefile_add_dep(c->mf, "%s", c->link_path);
    makefile_add_dep(c->mf, "Makefile");
    makefile_end_deps(c->mf);
    makefile_start_cmds(c->mf);
    makefile_nam_cmd(c->mf, "echo \"CP\t%s\"",
                     c->full_path + strlen(c->bin_dir) + 1);
    makefile_add_cmd(c->mf, "mkdir -p `dirname %s`", c->full_path);
    makefile_add_cmd(c->mf, "cp %s %s", c->link_path, c->full_path);
    makefile_end_cmds(c->mf);

    /* Does the actual linking with hashes of the arguments */
    makefile_create_target(c->mf, c->link_path);

    makefile_start_deps(c->mf);

    makefile_addl_dep(c->mf, c->objects, "%%s");
    makefile_addl_dep(c->mf, c->libraries, "$(LIBDEP__%s%%s)",
                      c->lib_dir);

    makefile_end_deps(c->mf);

    makefile_start_cmds(c->mf);
    language_link_pass_vcmd(l, c, false);
    makefile_end_cmds(c->mf);

    /* Link a second time, but with the install path now */
    makefile_create_target(c->mf, c->link_path_install);

    makefile_start_deps(c->mf);

    makefile_addl_dep(c->mf, c->objects, "%%s");
    makefile_addl_dep(c->mf, c->libraries, "$(wildcard %s/lib%%s.%s)",
                      c->lib_dir, l->so_ext);
    makefile_addl_dep(c->mf, c->libraries, "$(wildcard %s/lib%%s.%s)",
                      c->lib_dir, l->a_ext);

    makefile_end_deps(c->mf);

    makefile_start_cmds(c->mf);
    language_link_pass_vcmd(l, c, true);
    makefile_end_cmds(c->mf);

    /* There is an install/uninstall target */
    tmp = talloc_asprintf(context, "echo -e \"INS\\t%s\"", c->full_path);
    makefile_add_install(c->mf, tmp);
    tmp = talloc_asprintf(context,
                          "mkdir -p `dirname $D/\"%s/%s\"` >& /dev/null || true",
                          c->prefix, c->full_path);
    makefile_add_install(c->mf, tmp);
    tmp =
        talloc_asprintf(context,
                        "install -m a=rx %s $D/`dirname \"%s/%s\"`",
                        c->link_path_install, c->prefix, c->full_path);
    makefile_add_install(c->mf, tmp);

    tmp = talloc_asprintf(context, "%s/%s", c->prefix, c->full_path);
    makefile_add_uninstall(c->mf, tmp);

    makefile_add_distclean(c->mf, c->bin_dir);

    TALLOC_FREE(context);
    return 0;
}
Esempio n. 6
0
void process(struct processor *p_uncast, const char *filename,
             struct stack *s, struct makefile *m)
{
    struct processor_svgtex *p;
    void *c;
    int cachedir_index;
    char *cachedir;
    char *infile;
    char *cachename;
    char *origfile;

    /* We need access to the real structure, get it safely */
    p = talloc_get_type(p_uncast, struct processor_svgtex);

    /* Makes a new context */
    c = talloc_new(p);

    /* Finds the original filename */
    cachedir_index = string_index(filename, ".tek_cache/");
    if (cachedir_index == -1) {
        fprintf(stderr, "Bad cachedir for image\n");
        return;
    }

    cachedir = talloc_strdup(c, filename);
    cachedir[cachedir_index + strlen(".tex_cache/")] = '\0';

    infile = talloc_strdup(c, filename);
    infile[cachedir_index] = '\0';
    strcat(infile, filename + strlen(cachedir));
    infile[strlen(infile) - 8] = '\0';

    TALLOC_FREE(cachedir);
    cachedir = talloc_strndup(c, filename, basename_len(filename));

    cachename = talloc_strndup(c, filename, strlen(filename) - 8);

    origfile = infile;
    while (strstr(infile, "/") != NULL)
        infile = infile + 1;

    /* Creates the target to build the LaTeX file for importing. */
    makefile_create_target(m, filename);
    makefile_start_deps(m);
    makefile_add_dep(m, cachename);
    makefile_end_deps(m);

    makefile_start_cmds(m);
    makefile_nam_cmd(m, "echo -e \"SVGTEX\\t%s\"", infile);
    makefile_add_cmd(m, "mkdir -p \"%s\" >& /dev/null || true", cachedir);
    makefile_add_cmd(m, "cd .tek_cache; svgtexpp \"%s/%s\" > /dev/null",
                     strstr(cachedir, "/")+1, infile);
    makefile_end_cmds(m);

    /* This one is necessary for pandoc. */
    makefile_create_target(m, cachename);
    makefile_start_deps(m);
    makefile_add_dep(m, origfile);
    makefile_end_deps(m);

    makefile_start_cmds(m);
    makefile_nam_cmd(m, "echo -e \"IMGCP\\t%s\"", origfile);
    makefile_add_cmd(m, "mkdir -p \"%s\" >& /dev/null || true", cachedir);
    makefile_add_cmd(m, "cp \"%s\" \"%s\"", origfile, cachename);
    makefile_end_cmds(m);

    /* Also generate the relevant PDF */
    {
        char *outname;

        outname = talloc_asprintf(c, "%.*s.svg.pdf",
                                  (int)(strlen(cachename)-8),
                                  cachename);
        

        makefile_create_target(m, outname);
        makefile_start_deps(m);
        makefile_add_dep(m, cachename);
        makefile_end_deps(m);

        makefile_start_cmds(m);
        makefile_nam_cmd(m, "echo -e \"RSVGC\\t%s\"", infile);
        makefile_add_cmd(m, "mkdir -p \"%s\" >& /dev/null || true", cachedir);
        makefile_add_cmd(m, "rsvg-convert \"%s\" -f pdf -o \"%s\"",
                         infile, outname);
        makefile_end_cmds(m);
    }
    

    /* Cleans up all the memory allocated by this code. */
    TALLOC_FREE(c);
}
Esempio n. 7
0
int mf_destructor(struct makefile *m)
{
    struct stringlist_node *cur;

    /* Creates the fake all target. */
    makefile_create_target(m, "tek__all");
    makefile_start_deps(m);
    cur = stringlist_start(m->targets_all);
    while (stringlist_notend(cur)) {
        makefile_add_dep(m, stringlist_data(cur));
        cur = stringlist_next(cur);
    }
    makefile_end_deps(m);
    makefile_start_cmds(m);
    makefile_end_cmds(m);

    /* Cleans the cache */
    makefile_create_target(m, "cleancache");
    makefile_start_deps(m);
    makefile_end_deps(m);

    makefile_start_cmds(m);
    cur = stringlist_start(m->targets_cleancache);
    while (stringlist_notend(cur)) {
        makefile_add_cmd(m, "rm -rf \"%s\" >& /dev/null || true",
                         stringlist_data(cur));
        cur = stringlist_next(cur);
    }
    makefile_end_cmds(m);

    /* Creates the fake clean target. */
    makefile_create_target(m, "clean");
    makefile_start_deps(m);
    makefile_add_dep(m, "cleancache");
    makefile_end_deps(m);

    makefile_start_cmds(m);
    cur = stringlist_start(m->targets_clean);
    while (stringlist_notend(cur)) {
        makefile_add_cmd(m, "rm \"%s\" >& /dev/null || true",
                         stringlist_data(cur));
        cur = stringlist_next(cur);
    }
    makefile_end_cmds(m);

    /* The disclean target has its own magic. */
    makefile_create_target(m, "distclean");
    makefile_start_deps(m);
    makefile_add_dep(m, "clean");
    makefile_end_deps(m);
    makefile_start_cmds(m);
    cur = stringlist_start(m->targets_distclean);
    while (stringlist_notend(cur)) {
        makefile_add_cmd(m, "rm \"%s\" >& /dev/null || true",
                         stringlist_data(cur));
        cur = stringlist_next(cur);
    }
    makefile_end_cmds(m);

    fclose(m->file);

    return 0;
}
Esempio n. 8
0
void process(struct processor *p_uncast, const char *filename,
             struct stack *s, struct makefile *m)
{
    struct processor_pdfcopy *p;
    void *c;
    int cachedir_index;
    char *cachedir;
    char *infile;
    char *procfile;

    /* We need access to the real structure, get it safely */
    p = talloc_get_type(p_uncast, struct processor_pdfcopy);

    /* Makes a new context */
    c = talloc_new(p);

    /* Finds the original filename */
    cachedir_index = string_index(filename, ".tek_cache/");
    if (cachedir_index == -1) {
        fprintf(stderr, "Bad cachedir for image\n");
        return;
    }

    cachedir = talloc_strdup(c, filename);
    cachedir[cachedir_index + strlen(".tex_cache/")] = '\0';

    infile = talloc_strdup(c, filename);
    infile[cachedir_index] = '\0';
    strcat(infile, filename + strlen(cachedir));
    infile[strlen(infile) - 4] = '\0';

    TALLOC_FREE(cachedir);
    cachedir = talloc_strndup(c, filename, basename_len(filename));

    /* Figure out if we're supposed to copy the file or we're supposed
     * to generate it. */
    procfile = talloc_asprintf(c, "%s.proc", infile);
    if (access(procfile, X_OK) == 0) {
        /* Generate the file manually. */
        makefile_create_target(m, filename);
        makefile_start_deps(m);
        makefile_add_dep(m, procfile);
        makefile_end_deps(m);

        makefile_start_cmds(m);
        makefile_nam_cmd(m, "echo -e \"PDFGEN\\t%s\"", infile);
        makefile_add_cmd(m, "mkdir -p \"%s\" >& /dev/null || true", cachedir);
        makefile_add_cmd(m, "./\"%s\" > \"%s\"", procfile, filename);
        makefile_end_cmds(m);
    } else {
        /* Just copy the file over. */
        makefile_create_target(m, filename);
        makefile_start_deps(m);
        makefile_add_dep(m, infile);
        makefile_end_deps(m);

        makefile_start_cmds(m);
        makefile_nam_cmd(m, "echo -e \"PDFCOPY\\t%s\"", infile);
        makefile_add_cmd(m, "mkdir -p \"%s\" >& /dev/null || true", cachedir);
        makefile_add_cmd(m, "cp \"%s\" \"%s\" >& /dev/null", infile, filename);
        makefile_end_cmds(m);
    }

    /* Cleans up all the memory allocated by this code. */
    TALLOC_FREE(c);
}