I am working on a project where in the .cls and .sty files installed by the TeX distributions are too old, but they have been patched by other users on github. I wish to use these updated versions of these .cls and .sty files for my project. For various personal reasons (easy portability across computers), I do not wish to use texmf-local tree and wish to put them in a folder titled custom_cls_sty_files in the root of my project directory.

I am using latexmk as my build tool. Following the solution proposed here, I tried configuring my latexmkrc as

$ENV{'TEXINPUTS'}='./custom_cls_sty_files//:' . $ENV{'TEXINPUTS'};

However, this broke everything. latexmk is not only unable to find the .sty and .cls files, it could not find even main.tex!

Here is an mwe of main.tex



where a local copy of setspace.sty is located in the folder custom_cls_sty_files.

Presently, I am encountering this issue on a Windows 10 machine on TL 2018. But I have a mac laptop at home and a linux machine at work where I work on this project through git/github combo. Therefore, I would like a single cross-platform latexmkrc file that can solve this issue (i.e. assuming that this issue arose in the first place due to OS differences)

Error message when trying the suggested solution

Use of uninitialized value in concatenation (.) or string at (eval 17) line 59, <GEN0> chunk 1.
Latexmk: This is Latexmk, John Collins, 25 October 2018, version: 4.61.
Latexmk: applying rule 'lualatex'...
Rule 'lualatex': Rules & subrules not known to be previously run:
Rule 'lualatex': The following rules & subrules became out-of-date:
Run number 1 of rule 'lualatex'
Running 'lualatex  -recorder  "main.tex"'
This is LuaTeX, Version 1.07.0 (TeX Live 2018/W32TeX)
 restricted system commands enabled.
! I can't find file `main.tex'.
<*> main.tex

(Press Enter to retry, or Control-Z to exit)
Please type another input file name:
  • first off relative directories should be relative to main thus AFAIK ./custom_cls_sty_files// would need to be a subfolder of where the .tex is which may constantly change and not work always as expected & certainly above will not work like that on windows even if working on mac or nix since windows uses different separators. When you say across computers do you mean cross-platform which would require at least two different approaches or do you mean across flavours of Windows since if that is the case the approach will be different to the one you are pursuing. Please EDIT/clarify question
    – user170109
    Commented Feb 13, 2019 at 20:13
  • @KJO I did not fully understand your comment about the relative directory? This custom_cls_sty_files is just a folder in my project's root where all the sty and cls files exist. For the 2nd part of the comment, I have updated the question to clarify what I meant by cross-platform. Commented Feb 13, 2019 at 20:16
  • Also if later on you don't want to use those custom stuff you'll need to update your latexmkrc. I'd recommend something else. Learn to use custom texmf trees. Both texlive and miktex has tools to add and remove these.
    – daleif
    Commented Feb 13, 2019 at 20:18
  • @daleif I really prefer this particular approach. I know about local texmf trees. But I need this custom subfolder approach for archival purposes. Some package that I use are constantly changing breaking backwards compatibility with updates. I wish to use a specific version of these dependency files that can be fully controlled by me, and which will be automatically used by latexmk preferred over the system-wide sty files. This way, everything I need for reproducibility is self-contained in the project (at the expense of an increased size, of course) Commented Feb 13, 2019 at 20:24
  • 1
    A few basics windows uses ; where nix and mac use : so your syntax needs to change for windows versus others. You can place the sty in the same project folder as .tex no need to mess about with varieties of // ./ \\ etc
    – user170109
    Commented Feb 13, 2019 at 20:43

2 Answers 2


Latexmk actually has a subroutine for adding items to search paths. You can write

ensure_path( 'TEXINPUTS', './custom_cls_sty_files//' );

This takes care of using the correct operating-system-dependent separator between items in the variable. It also gracefully handles the case where the search-path variable doesn't already exist.

This subroutine is not yet documented, but it will be in the next release.

Documentation of ensure_path

ensure_path( var, values ...)

The first parameter is the name of one of the system's environment variables for search paths. The remaining parameters are values that should be in the variable. For each of the value parameters, if it isn't already in the variable, then it is prepended to the variable; in that case the environment variable is created if it doesn't already exist. For separating values, the character appropriate the the operating system is used -- see the configuration variable $search_path_separator.


ensure_path( 'TEXINPUTS', './custom_cls_sty_files//' );

(In this example, the trailing // is documented by TeX systems to mean that latex, pdflatex, etc search for files in the specified directory and in all subdirectories.)

Technically ensure_path works by setting Perl's variable $ENV{var}, where var is the name of the target variable. The changed value is then passed as an environment variable to any invoked programs.

  • awesome. This is exactly what I was looking for. Upvoted & accepted. Commented Feb 14, 2019 at 18:06
  • ensure_path() does not exist in my version (4.41, January 2015) of latexmk, so I used $ENV{TEXINPUTS} = join(":", ($ENV{TEXINPUTS} || ()), "su-thesis//"); instead.
    – zrajm
    Commented Mar 4, 2020 at 12:31
  • 1
    @JohnCollins, where ensure_path() subroutine call should be placed? In latexmkrc file?
    – and1er
    Commented Apr 12, 2020 at 11:07

Newer versions of Tex Live address the need for user or project specific sets of files to override the defaults. This should only apply to give priority to the files that are there others that are on texmf paths will be used as normal. Although untested I would NOT split a TDS package between the two locations, so you may need to duplicate in some cases package related support files so as to be found relative to each other.

This was introduced in Tex Live 2017 and is invoked by calling (irrespective of platform)

 tlmgr conf auxtrees [add | remove | show] <path to desired files>

For windows use it may be something like (avoiding spaces and accents etc.)

tlmgr conf auxtrees add C:\Users\myname\PersonalTexmf
tlmgr conf auxtrees show C:\Users\myname\PersonalTexmf

Linux or OS/X users may need to use sudo:

sudo tlmgr conf auxtrees add "./personal_texmf"

You may need to experiment with using TDS compliant folders but the related structure should be similar to within texmf-local.
see also https://www.tug.org/texlive/doc/texlive-en/texlive-en.html#x1-110002.3

IT is important that the aux tree is NOT within an existing texmf structure (to avoid potential conflicts of priority) however the auxiliary may be a folder alongside texmf-local

IF texmf-local files interfere in precedence then it may become necessary to temporarily block a default texmf-local folder first via a shell script or manually commenting out via alternative copies of your current texmf.cnf

Here is a hypothetical example session from the 2017 blog

$ tlmgr conf auxtrees show
tlmgr: no auxiliary texmf trees defined.
$ tlmgr conf auxtrees add /projects/book-abc
$ tlmgr conf auxtrees
List of auxiliary texmf trees:
$ tlmgr conf auxtrees remove /projects/book-abc
$ tlmgr conf auxtrees show
tlmgr: no auxiliary texmf trees defined.

That was very untypical, and we may need to address the filename database /font maps for the user prior to calling Tex Live in anger.

Note at the same time there were changes to

"The TEXMFLOCAL tree is now searched before TEXMFSYSCONFIG and TEXMFSYSVAR (by default);"

The defaults should be

"TEXMFLOCAL (by default, /usr/local/texlive/texmf-local or %SystemDrive%\texlive\texmf-local on Windows) is intended for system-wide local fonts and macros; and TEXMFHOME (by default, $HOME/texmf or %USERPROFILE%\texmf), is for personal fonts and macros. These directories are intended to stick around from release to release, and have their content seen automatically by a new TEX Live release. Therefore, it is best to refrain from changing the definition of TEXMFLOCAL to be too far away from the main TEX Live directory, or you will need to manually change future releases."

It may be useful to see the results with Kpathsea & Kpsewhich

Thus after adding or removing a path to the priority order we should also call


or possibly better

  • 2
    Your solution worked nicely for me yesterday. Thank you for the awesome detailed answer. I hadn't heard of the conf auxtrees option before. I am glad I could learning something new from your answer. John Collin's latexmk-based solution answers exactly my question, whilst yours provides a valuable workaround. Hope it is okay if I accept his answer. I have upvoted for your answer for its usefulness. Commented Feb 14, 2019 at 18:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .