I would add to Sašo Živanović's answer that it is possible to configure latexmk to use memoize with an output directory.
Here's what goes in a latexmkrc file.
(NOTE that an improved version of this configuration will be in the next version of latexmk (v. 4.84). The solution here works only with TeXLive on Unix-type OSs (linux and macOS), and only when latexmk uses lualatex for pdflatex for the compilation of the .tex file.)
$pdf_mode = 4; # Use lualatex. Set to 1 for pdflatex, 5 for xelatex.
You can have separate build and output directories, or they can be
the same, e.g., by $out_dir = $aux_dir = 'output';
$out_dir = 'output';
$aux_dir = 'build';
$emulate_aux = 1;
Get latexmk -C to delete memoize-generated files, at least
when the default setting in memoize for the prefix of .memo
and .pdf files is used.
push @generated_exts, 'mmz', 'mmz.log', '%R..memo', '%R..pdf';
&set_tex_cmds( 'internal latex_memoize %C %B %S -synctex=1 %O' );
sub latex_memoize {
print "============= I am latex_memoize \n";
Ensure TEX_OUTPUT_DIRECTORY is set. (In v. >=4.84 of latexmk, this
will not be necessary, since latexmk will make the setting itself.)
local %ENV = %ENV;
foreach ( 'TEXMF_OUTPUT_DIRECTORY' ) {
$ENV{$} = $aux_dir;
print "latex_memoize: ENV{$} = '$ENV{$_}'\n";
}
my ($cmd, $base, $source, @args) = @_;
my $tex_log = "$aux_dir1$base.log";
my $mmz_file = "$aux_dir1$base.mmz";
my @tex_cmd = ($cmd, @args, $source );
my @memo_cmd = ("memoize-extract.pl", '-F', 'latex', $mmz_file );
print "latex_memoize: Running\n '@tex_cmd'\n";
my $ret = system @tex_cmd;
if (! -e $mmz_file) {
print "latex_memoize: No mmz file '$mmz_file', so memoize is not being used.\n";
return $ret;
}
Use (not-currently-documented) latexmk subroutine to determine
whether mmz file was generated in current run:
if ( ! test_gen_file_time( $mmz_file) ) {
warn "latex_memoize: Mmz file '$mmz_file' exists, but wasn't generated\n",
" in this run so memoize is not currently being used.\n";
return $ret;
}
Fix up dependency information in log file:
my $mmz_fh = undef;
my $tex_log_fh = undef;
if (! open( $mmz_fh, '<', $mmz_file ) ) {
print "latex_memoize: Cannot open mmz file '$mmz_file':\n $!\n";
return $ret;
}
if (! open( $tex_log_fh, '>>', $tex_log ) ) {
warn "latex_memoize: Cannot open log file '$tex_log': $!\n";
close $mmz_fh;
return $ret;
}
while ( <$mmz_fh> ) {
s/\s$//;
my $source = undef;
if ( /^\mmzNewExtern\s+{([^}]+)}/ ) {
# We have a new memo item without a corresponding pdf file
# Put a suitable message in the log file, so that latexmk will
# know to run latex again, when it analyzes the results of
# the current run.
$file = "$aux_dir1$1";
print "latex_memoize: new extern for memoize: '$file'\n";
print $tex_log_fh "No file $file\n";
}
}
close $tex_log_fh;
close $mmz_fh;
Run memoize-extract.pl now. Then missing pdf files are
created, which will provoke latexmk into rerunning *latex.
It also handles the case that the memoize package is used
with the external=no option. (But gives no problem when
the option is not used.)
It also allows the use of separate aux and output directories
which would otherwise give a problem, since in that situation
latexmk will move the pdf file from the aux directory to the
output directory, where it is no longer accessible to
memoize-extract.pl.
print "Running\n @memo_cmd\n";
my $ret2 = system @memo_cmd;
if ($ret2) { return $ret2; }
return $ret;
}
This has been tested on TeXLive 2023 and 2024, and with all of pdflatex, lualatex, and xelatex. (On Windows, there may be some issues when files have non-ASCII characters in their names, but I haven't yet checked.)
As mentioned in comments to the question, there are some complications in working with an output directory. Ways to get things working are already programmed into latexmk; that was done many years ago and was quite simple, but not something you'd want to do regularly from the command line. I've found that the use of latexmk insulates me against the difficulties that were mentioned.
--output-directorymakes everything far more complicated, you have to configure every related program to find where the files have been hidden and has no real advantages at all. – David Carlisle Mar 02 '24 at 16:56memoizedo you have? For 1.1.2 did you read footnote 68 on page 86? – cfr Mar 02 '24 at 19:29.mmz.logfiles: one in the top level directory and one in the output directory. Moreover, Memoize complains extraction fails even when there is nothing to extract on the first run. I suggest reporting this as a bug. I also third the suggestions not to use--output-directory. – cfr Mar 02 '24 at 19:51