[Tex/LaTex] Can the custom dependency for latexmk be improved

glossarieslatexmk

In my answer to this question on how to make latexmk use makeglossaries for generating glossaries, I propose the following custom dependency:

add_cus_dep('glo', 'gls', 0, 'run_makeglossaries');
add_cus_dep('acn', 'acr', 0, 'run_makeglossaries');

sub run_makeglossaries {
  if ( $silent ) {
    system "makeglossaries -q '$_[0]'";
  }
  else {
    system "makeglossaries '$_[0]'";
  };
}

When latexmk is run on the LaTeX input file

\documentclass{article}

\usepackage[acronym]{glossaries}

\newglossaryentry{test}{name={Test}, description={A Test}}

\newacronym{AT}{AT}{A Test}

\makeglossaries

\glsaddall

\begin{document}

\printglossaries

\end{document}

the first time it invokes latex, makeglossaries and latex (in that order). This is as expected, since makeglossaries processes all defined glossaries (here the main glossary and the list of acronyms) in a single call.

Now, assume I apply some trivial changes to both the term test and the acronym AT (e.g., I convert Test to lowercase). Then, the command sequence issued by latexmk is latex, makeglossaries, makeglossaries and latex. Thus, makeglossaries is called twice while it would suffice to call it once.

Hence, I wonder: Is it possible to improve my custom dependency such that latexmk also handles the preceding case correctly?

Best Answer

The two runs of makeglossaries are because of an inadequacy in latexmk. The problem is that a custom dependency is considered to have a single input file and a single output file. But makeglossaries has an input file and an output file for each glossary; in the example given, the input files have extensions acn and glo, and the output files have extensions acr and gls.

It would require significant rewriting of latexmk to improve this situation. I suspect the extra running time from the extra runs of makeglossaries is normally fairly low compared with the running of latex itself, so this isn't a high priority for me to fix this.

Alternatively, you could rewrite the definitions of the custom dependencies to directly run makeindex instead of delegating that to makeglossaries.

What happens is that latexmk creates two custom dependencies, as expected: for acn to acr, and for glo to gls. When a change is made to both glossaries, latexmk sees that both rules have become out-of-date and runs makeglossaries. So the two runs are expected.

But this leaves a puzzle of why is there only one run of makeglossaries the first time the source file is processed by latexmk. This is because from a virgin set up, latexmk first runs makeglossaries to create the gls file. As a side effect this also creates the acr file. Now on an initial run, latexmk sees that the acr file is newer than the acn file, so it doesn't bother to make it. But on subsequent runs, latexmk uses a criterion of change of file contents rather than relative file times between input and output files to determine whether to remake output files. Hence the first time through, only one run of makeglossaries is done.

Added note: I mentioned that the custom dependencies can written differently to call makeindex directly rather than delegating that to makeglossaries. This optimizes the number of runs. Here's one way of doing it:

add_cus_dep('glo', 'gls', 0, 'run_makeindex');
add_cus_dep('acn', 'acr', 0, 'run_makeindex');
sub run_makeindex {
   my $source = $$Psource;
   my $dest = $$Pdest;
   my $log = $dest."LOG";
   my $cmd = "makeindex %O -s \"$_[0].ist\"  -t \"$log\" -o \"$dest\" \"$source\"";
   if ($silent) { $cmd =~ s/%O/-q/; }
   else { $cmd =~ s/%O//; }
   return system $cmd;
}

To make the code simpler and the same for the two cases, I've uses a couple of internal variables of latexmk that specify the source and destination files for the dependency. I've set the names of the log files for makeindex to something easier to create than those of makeglossaries.

Related Question