texlive.withPackages: use buildenv (finalAttrs: ...)
This commit is contained in:
@@ -951,7 +951,7 @@ rec {
|
||||
scheme:
|
||||
builtins.foldl' (
|
||||
acc: pkg: concatLicenses acc (lib.toList (pkg.meta.license or [ ]))
|
||||
) [ ] scheme.passthru.requiredTeXPackages;
|
||||
) [ ] scheme.passthru.includedTeXPackages;
|
||||
correctLicensesAttrNames = scheme: lib.sort lt (map licenseToAttrName (correctLicenses scheme));
|
||||
|
||||
hasLicenseMismatch =
|
||||
|
||||
@@ -23,12 +23,9 @@
|
||||
}:
|
||||
|
||||
lib.fix (
|
||||
self:
|
||||
buildTeXEnv:
|
||||
{
|
||||
withDocs ? false,
|
||||
withSources ? false,
|
||||
requiredTeXPackages ? ps: [ ps.scheme-infraonly ],
|
||||
|
||||
### texlive.combine backward compatibility
|
||||
__extraName ? "combined",
|
||||
__extraVersion ? "",
|
||||
@@ -38,448 +35,484 @@ lib.fix (
|
||||
__fromCombineWrapper ? false,
|
||||
# build only the formats of a package (for internal use!)
|
||||
__formatsOf ? null,
|
||||
}@args:
|
||||
}:
|
||||
buildEnv (
|
||||
finalAttrs:
|
||||
|
||||
let
|
||||
### texlive.combine backward compatibility
|
||||
# if necessary, convert old style { pkgs = [ ... ]; } packages to attribute sets
|
||||
isOldPkgList = p: !p.outputSpecified or false && p ? pkgs && builtins.all (p: p ? tlType) p.pkgs;
|
||||
ensurePkgSets =
|
||||
ps:
|
||||
if !__fromCombineWrapper && builtins.any isOldPkgList ps then
|
||||
let
|
||||
oldPkgLists = builtins.partition isOldPkgList ps;
|
||||
in
|
||||
oldPkgLists.wrong ++ lib.concatMap toTLPkgSets oldPkgLists.right
|
||||
else
|
||||
ps;
|
||||
let
|
||||
withDocs = finalAttrs.passthru.withDocs or false;
|
||||
withSources = finalAttrs.passthru.withSources or false;
|
||||
|
||||
pkgList = rec {
|
||||
# resolve dependencies of the packages that affect the runtime
|
||||
all =
|
||||
let
|
||||
packages = ensurePkgSets (requiredTeXPackages tl);
|
||||
runtime = builtins.partition (
|
||||
p:
|
||||
p.outputSpecified or false
|
||||
-> builtins.elem (p.tlOutputName or p.outputName) [
|
||||
"out"
|
||||
"tex"
|
||||
"tlpkg"
|
||||
]
|
||||
) packages;
|
||||
keySet = p: {
|
||||
key =
|
||||
p.pname or p.name
|
||||
+ lib.optionalString (p.outputSpecified or false) ("-" + p.tlOutputName or p.outputName or "");
|
||||
inherit p;
|
||||
tlDeps = if p ? tlDeps then ensurePkgSets p.tlDeps else (p.requiredTeXPackages or (_: [ ]) tl);
|
||||
};
|
||||
in
|
||||
# texlive.combine: the wrapper already resolves all dependencies
|
||||
if __fromCombineWrapper then
|
||||
requiredTeXPackages null
|
||||
# if necessary, convert old style { pkgs = [ ... ]; } packages to attribute sets
|
||||
isOldPkgList = p: !p.outputSpecified or false && p ? pkgs && builtins.all (p: p ? tlType) p.pkgs;
|
||||
ensurePkgSets =
|
||||
ps:
|
||||
if !finalAttrs.passthru.__fromCombineWrapper && builtins.any isOldPkgList ps then
|
||||
let
|
||||
oldPkgLists = builtins.partition isOldPkgList ps;
|
||||
in
|
||||
oldPkgLists.wrong ++ lib.concatMap toTLPkgSets oldPkgLists.right
|
||||
else
|
||||
builtins.catAttrs "p" (
|
||||
builtins.genericClosure {
|
||||
startSet = map keySet runtime.right;
|
||||
operator = p: map keySet p.tlDeps;
|
||||
}
|
||||
)
|
||||
++ runtime.wrong;
|
||||
ps;
|
||||
|
||||
# group the specified outputs
|
||||
specified = builtins.partition (p: p.outputSpecified or false) all;
|
||||
specifiedOutputs = lib.groupBy (p: p.tlOutputName or p.outputName) specified.right;
|
||||
otherOutputNames = builtins.catAttrs "key" (
|
||||
builtins.genericClosure {
|
||||
startSet = map (key: { inherit key; }) (
|
||||
lib.concatLists (builtins.catAttrs "outputs" specified.wrong)
|
||||
);
|
||||
operator = _: [ ];
|
||||
}
|
||||
);
|
||||
otherOutputs = lib.genAttrs otherOutputNames (n: builtins.catAttrs n specified.wrong);
|
||||
outputsToInstall = builtins.catAttrs "key" (
|
||||
builtins.genericClosure {
|
||||
startSet = map (key: { inherit key; }) (
|
||||
[ "out" ]
|
||||
++ lib.optional (otherOutputs ? man) "man"
|
||||
++ lib.concatLists (builtins.catAttrs "outputsToInstall" (builtins.catAttrs "meta" specified.wrong))
|
||||
);
|
||||
operator = _: [ ];
|
||||
}
|
||||
);
|
||||
pkgList = rec {
|
||||
# resolve dependencies of the packages that affect the runtime
|
||||
all =
|
||||
let
|
||||
packages = ensurePkgSets (finalAttrs.passthru.requiredTeXPackages tl);
|
||||
runtime = builtins.partition (
|
||||
p:
|
||||
p.outputSpecified or false
|
||||
-> builtins.elem (p.tlOutputName or p.outputName) [
|
||||
"out"
|
||||
"tex"
|
||||
"tlpkg"
|
||||
]
|
||||
) packages;
|
||||
keySet = p: {
|
||||
key =
|
||||
p.pname or p.name
|
||||
+ lib.optionalString (p.outputSpecified or false) ("-" + p.tlOutputName or p.outputName or "");
|
||||
inherit p;
|
||||
tlDeps = if p ? tlDeps then ensurePkgSets p.tlDeps else (p.requiredTeXPackages or (_: [ ]) tl);
|
||||
};
|
||||
in
|
||||
# texlive.combine: the wrapper already resolves all dependencies
|
||||
if finalAttrs.passthru.__fromCombineWrapper then
|
||||
finalAttrs.passthru.requiredTeXPackages null
|
||||
else
|
||||
builtins.catAttrs "p" (
|
||||
builtins.genericClosure {
|
||||
startSet = map keySet runtime.right;
|
||||
operator = p: map keySet p.tlDeps;
|
||||
}
|
||||
)
|
||||
++ runtime.wrong;
|
||||
|
||||
# split binary and tlpkg from tex, texdoc, texsource
|
||||
bin =
|
||||
if __fromCombineWrapper then
|
||||
builtins.filter (p: p.tlType == "bin") all # texlive.combine: legacy filter
|
||||
else
|
||||
otherOutputs.out or [ ] ++ specifiedOutputs.out or [ ];
|
||||
tlpkg =
|
||||
if __fromCombineWrapper then
|
||||
builtins.filter (p: p.tlType == "tlpkg") all # texlive.combine: legacy filter
|
||||
else
|
||||
otherOutputs.tlpkg or [ ] ++ specifiedOutputs.tlpkg or [ ];
|
||||
|
||||
nonbin =
|
||||
if __fromCombineWrapper then
|
||||
builtins.filter (p: p.tlType != "bin" && p.tlType != "tlpkg") all # texlive.combine: legacy filter
|
||||
else
|
||||
(
|
||||
if __combine then # texlive.combine: emulate old input ordering to avoid rebuilds
|
||||
lib.concatMap (
|
||||
p:
|
||||
lib.optional (p ? tex) p.tex
|
||||
++ lib.optional ((withDocs || p ? man) && p ? texdoc) p.texdoc
|
||||
++ lib.optional (withSources && p ? texsource) p.texsource
|
||||
) specified.wrong
|
||||
else
|
||||
otherOutputs.tex or [ ]
|
||||
++ lib.optionals withDocs (otherOutputs.texdoc or [ ])
|
||||
++ lib.optionals withSources (otherOutputs.texsource or [ ])
|
||||
)
|
||||
++ specifiedOutputs.tex or [ ]
|
||||
++ specifiedOutputs.texdoc or [ ]
|
||||
++ specifiedOutputs.texsource or [ ];
|
||||
|
||||
# outputs that do not become part of the environment
|
||||
nonEnvOutputs = lib.subtractLists [ "out" "tex" "texdoc" "texsource" "tlpkg" ] otherOutputNames;
|
||||
|
||||
# packages that contribute to config files and formats
|
||||
fontMaps = lib.filter (p: p ? fontMaps && (p.tlOutputName or p.outputName == "tex")) nonbin;
|
||||
sortedFontMaps = builtins.sort (a: b: a.pname < b.pname) fontMaps;
|
||||
hyphenPatterns = lib.filter (
|
||||
p: p ? hyphenPatterns && (p.tlOutputName or p.outputName == "tex")
|
||||
) nonbin;
|
||||
sortedHyphenPatterns = builtins.sort (a: b: a.pname < b.pname) hyphenPatterns;
|
||||
formatPkgs = lib.filter (
|
||||
p:
|
||||
p ? formats
|
||||
&& (p.outputSpecified or false -> p.tlOutputName or p.outputName == "tex")
|
||||
&& builtins.any (f: f.enabled or true) p.formats
|
||||
) all;
|
||||
sortedFormatPkgs =
|
||||
if __formatsOf != null then [ __formatsOf ] else builtins.sort (a: b: a.pname < b.pname) formatPkgs;
|
||||
formats = map (
|
||||
p:
|
||||
self {
|
||||
requiredTeXPackages =
|
||||
ps:
|
||||
[
|
||||
ps.scheme-infraonly
|
||||
p
|
||||
]
|
||||
++ hyphenPatterns;
|
||||
__formatsOf = p;
|
||||
}
|
||||
) sortedFormatPkgs;
|
||||
};
|
||||
|
||||
# list generated by inspecting `grep -IR '\([^a-zA-Z]\|^\)gs\( \|$\|"\)' "$TEXMFDIST"/scripts`
|
||||
# and `grep -IR rungs "$TEXMFDIST"`
|
||||
# and ignoring luatex, perl, and shell scripts (those must be patched using postFixup)
|
||||
needsGhostscript = lib.any (
|
||||
p:
|
||||
lib.elem p.pname [
|
||||
"context"
|
||||
"dvipdfmx"
|
||||
"latex-papersize"
|
||||
"lyluatex"
|
||||
]
|
||||
) pkgList.bin;
|
||||
|
||||
pname =
|
||||
if __combine then
|
||||
"texlive-${__extraName}" # texlive.combine: old name
|
||||
else
|
||||
"texlive";
|
||||
version =
|
||||
if __combine then
|
||||
"${toString tlpdbVersion.year}${__extraVersion}" # texlive.combine: old version
|
||||
else
|
||||
"${toString tlpdbVersion.year}-r${toString tlpdbVersion.revision}-"
|
||||
+ (lib.optionalString tlpdbVersion.frozen "final-")
|
||||
+ (if __formatsOf != null then "${__formatsOf.pname}-fmt" else "env");
|
||||
|
||||
name = "${pname}-${version}";
|
||||
|
||||
texmfdist = buildEnv {
|
||||
name = "${name}-texmfdist";
|
||||
|
||||
# remove fake derivations (without 'outPath') to avoid undesired build dependencies
|
||||
paths = builtins.catAttrs "outPath" pkgList.nonbin;
|
||||
|
||||
# mktexlsr
|
||||
nativeBuildInputs = [
|
||||
tl.texlive-scripts # for mktexlsr.pl with --sort support
|
||||
perl
|
||||
];
|
||||
|
||||
postBuild = # generate ls-R database
|
||||
''
|
||||
perl ${tl.texlive-scripts.tex}/scripts/texlive/mktexlsr.pl --sort "$out"
|
||||
'';
|
||||
};
|
||||
|
||||
tlpkg = buildEnv {
|
||||
name = "${name}-tlpkg";
|
||||
|
||||
# remove fake derivations (without 'outPath') to avoid undesired build dependencies
|
||||
paths = builtins.catAttrs "outPath" pkgList.tlpkg;
|
||||
};
|
||||
|
||||
# the 'non-relocated' packages must live in $TEXMFROOT/texmf-dist
|
||||
# and sometimes look into $TEXMFROOT/tlpkg (notably fmtutil, updmap look for perl modules in both)
|
||||
texmfroot =
|
||||
runCommand "${name}-texmfroot"
|
||||
{
|
||||
inherit texmfdist tlpkg;
|
||||
}
|
||||
''
|
||||
mkdir -p "$out"
|
||||
ln -s "$texmfdist" "$out"/texmf-dist
|
||||
ln -s "$tlpkg" "$out"/tlpkg
|
||||
'';
|
||||
|
||||
# texlive.combine: expose info and man pages in usual /share/{info,man} location
|
||||
doc = buildEnv {
|
||||
name = "${name}-doc";
|
||||
|
||||
paths = [ (texmfdist.outPath + "/doc") ];
|
||||
extraPrefix = "/share";
|
||||
|
||||
pathsToLink = [
|
||||
"/info"
|
||||
"/man"
|
||||
];
|
||||
};
|
||||
|
||||
meta = {
|
||||
description =
|
||||
"TeX Live environment"
|
||||
+ lib.optionalString withDocs " with documentation"
|
||||
+ lib.optionalString (withDocs && withSources) " and"
|
||||
+ lib.optionalString withSources " with sources";
|
||||
platforms = lib.platforms.all;
|
||||
longDescription =
|
||||
"Contains the following packages and their transitive dependencies:\n - "
|
||||
+ lib.concatMapStringsSep "\n - " (
|
||||
p:
|
||||
p.pname + (lib.optionalString (p.outputSpecified or false) " (${p.tlOutputName or p.outputName})")
|
||||
) (requiredTeXPackages tl);
|
||||
};
|
||||
|
||||
# other outputs
|
||||
nonEnvOutputs = lib.genAttrs pkgList.nonEnvOutputs (
|
||||
outName:
|
||||
buildEnv {
|
||||
inherit name;
|
||||
paths = builtins.catAttrs "outPath" (
|
||||
pkgList.otherOutputs.${outName} or [ ] ++ pkgList.specifiedOutputs.${outName} or [ ]
|
||||
# group the specified outputs
|
||||
specified = builtins.partition (p: p.outputSpecified or false) all;
|
||||
specifiedOutputs = lib.groupBy (p: p.tlOutputName or p.outputName) specified.right;
|
||||
otherOutputNames = builtins.catAttrs "key" (
|
||||
builtins.genericClosure {
|
||||
startSet = map (key: { inherit key; }) (
|
||||
lib.concatLists (builtins.catAttrs "outputs" specified.wrong)
|
||||
);
|
||||
operator = _: [ ];
|
||||
}
|
||||
);
|
||||
derivationArgs = {
|
||||
outputs = [ outName ];
|
||||
nativeBuildInputs = [
|
||||
# force the output to be ${outName} or nix-env will not work
|
||||
(writeShellScript "force-output.sh" ''
|
||||
export out="''${${outName}-}"
|
||||
'')
|
||||
];
|
||||
inherit meta passthru;
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
passthru = {
|
||||
# This is set primarily to help find-tarballs.nix to do its job
|
||||
requiredTeXPackages = builtins.filter lib.isDerivation (
|
||||
pkgList.bin
|
||||
++ pkgList.nonbin
|
||||
++ lib.optionals (!__fromCombineWrapper) (
|
||||
lib.concatMap (
|
||||
n: (pkgList.otherOutputs.${n} or [ ] ++ pkgList.specifiedOutputs.${n} or [ ])
|
||||
) pkgList.nonEnvOutputs
|
||||
)
|
||||
);
|
||||
# useful for inclusion in the `fonts.packages` nixos option or for use in devshells
|
||||
fonts = "${texmfroot}/texmf-dist/fonts";
|
||||
# support variants attrs, (prev: attrs)
|
||||
__overrideTeXConfig =
|
||||
newArgs:
|
||||
let
|
||||
appliedArgs = if builtins.isFunction newArgs then newArgs args else newArgs;
|
||||
in
|
||||
self (args // { __fromCombineWrapper = false; } // appliedArgs);
|
||||
withPackages =
|
||||
reqs:
|
||||
self (
|
||||
args
|
||||
// {
|
||||
requiredTeXPackages = ps: reqs ps ++ requiredTeXPackages ps;
|
||||
__fromCombineWrapper = false;
|
||||
otherOutputs = lib.genAttrs otherOutputNames (n: builtins.catAttrs n specified.wrong);
|
||||
outputsToInstall = builtins.catAttrs "key" (
|
||||
builtins.genericClosure {
|
||||
startSet = map (key: { inherit key; }) (
|
||||
[ "out" ]
|
||||
++ lib.optional (otherOutputs ? man) "man"
|
||||
++ lib.concatLists (builtins.catAttrs "outputsToInstall" (builtins.catAttrs "meta" specified.wrong))
|
||||
);
|
||||
operator = _: [ ];
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
# TeXLive::TLOBJ::fmtutil_cnf_lines
|
||||
fmtutilLine =
|
||||
{
|
||||
name,
|
||||
engine,
|
||||
enabled ? true,
|
||||
patterns ? [ "-" ],
|
||||
options ? "",
|
||||
...
|
||||
}:
|
||||
lib.optionalString (!enabled) "#! "
|
||||
+ "${name} ${engine} ${lib.concatStringsSep "," patterns} ${options}";
|
||||
fmtutilLines =
|
||||
{ pname, formats, ... }:
|
||||
[
|
||||
"#"
|
||||
"# from ${pname}:"
|
||||
]
|
||||
++ map fmtutilLine formats;
|
||||
# split binary and tlpkg from tex, texdoc, texsource
|
||||
bin =
|
||||
if finalAttrs.passthru.__fromCombineWrapper then
|
||||
builtins.filter (p: p.tlType == "bin") all # texlive.combine: legacy filter
|
||||
else
|
||||
otherOutputs.out or [ ] ++ specifiedOutputs.out or [ ];
|
||||
tlpkg =
|
||||
if finalAttrs.passthru.__fromCombineWrapper then
|
||||
builtins.filter (p: p.tlType == "tlpkg") all # texlive.combine: legacy filter
|
||||
else
|
||||
otherOutputs.tlpkg or [ ] ++ specifiedOutputs.tlpkg or [ ];
|
||||
|
||||
# TeXLive::TLOBJ::language_dat_lines
|
||||
langDatLine =
|
||||
{
|
||||
name,
|
||||
file,
|
||||
synonyms ? [ ],
|
||||
...
|
||||
}:
|
||||
[ "${name} ${file}" ] ++ map (s: "=" + s) synonyms;
|
||||
langDatLines =
|
||||
{ pname, hyphenPatterns, ... }:
|
||||
[ "% from ${pname}:" ] ++ builtins.concatMap langDatLine hyphenPatterns;
|
||||
nonbin =
|
||||
if finalAttrs.passthru.__fromCombineWrapper then
|
||||
builtins.filter (p: p.tlType != "bin" && p.tlType != "tlpkg") all # texlive.combine: legacy filter
|
||||
else
|
||||
(
|
||||
if finalAttrs.__combine then # texlive.combine: emulate old input ordering to avoid rebuilds
|
||||
lib.concatMap (
|
||||
p:
|
||||
lib.optional (p ? tex) p.tex
|
||||
++ lib.optional ((withDocs || p ? man) && p ? texdoc) p.texdoc
|
||||
++ lib.optional (withSources && p ? texsource) p.texsource
|
||||
) specified.wrong
|
||||
else
|
||||
otherOutputs.tex or [ ]
|
||||
++ lib.optionals withDocs (otherOutputs.texdoc or [ ])
|
||||
++ lib.optionals withSources (otherOutputs.texsource or [ ])
|
||||
)
|
||||
++ specifiedOutputs.tex or [ ]
|
||||
++ specifiedOutputs.texdoc or [ ]
|
||||
++ specifiedOutputs.texsource or [ ];
|
||||
|
||||
# TeXLive::TLOBJ::language_def_lines
|
||||
# see TeXLive::TLUtils::parse_AddHyphen_line for default values
|
||||
langDefLine =
|
||||
{
|
||||
name,
|
||||
file,
|
||||
lefthyphenmin ? "",
|
||||
righthyphenmin ? "",
|
||||
synonyms ? [ ],
|
||||
...
|
||||
}:
|
||||
map (
|
||||
n:
|
||||
"\\addlanguage{${n}}{${file}}{}{${if lefthyphenmin == "" then "2" else lefthyphenmin}}{${
|
||||
if righthyphenmin == "" then "3" else righthyphenmin
|
||||
}}"
|
||||
) ([ name ] ++ synonyms);
|
||||
langDefLines =
|
||||
{ pname, hyphenPatterns, ... }:
|
||||
[ "% from ${pname}:" ] ++ builtins.concatMap langDefLine hyphenPatterns;
|
||||
# outputs that do not become part of the environment
|
||||
nonEnvOutputs = lib.subtractLists [ "out" "tex" "texdoc" "texsource" "tlpkg" ] otherOutputNames;
|
||||
|
||||
# TeXLive::TLOBJ::language_lua_lines
|
||||
# see TeXLive::TLUtils::parse_AddHyphen_line for default values
|
||||
langLuaLine =
|
||||
{
|
||||
name,
|
||||
file,
|
||||
lefthyphenmin ? "",
|
||||
righthyphenmin ? "",
|
||||
synonyms ? [ ],
|
||||
...
|
||||
}@args:
|
||||
''
|
||||
''\t['${name}'] = {
|
||||
''\t''\tloader = '${file}',
|
||||
''\t''\tlefthyphenmin = ${if lefthyphenmin == "" then "2" else lefthyphenmin},
|
||||
''\t''\trighthyphenmin = ${if righthyphenmin == "" then "3" else righthyphenmin},
|
||||
''\t''\tsynonyms = { ${lib.concatStringsSep ", " (map (s: "'${s}'") synonyms)} },
|
||||
''
|
||||
+ lib.optionalString (args ? file_patterns) "\t\tpatterns = '${args.file_patterns}',\n"
|
||||
+ lib.optionalString (args ? file_exceptions) "\t\thyphenation = '${args.file_exceptions}',\n"
|
||||
+ lib.optionalString (args ? luaspecial) "\t\tspecial = '${args.luaspecial}',\n"
|
||||
+ "\t},";
|
||||
langLuaLines =
|
||||
{ pname, hyphenPatterns, ... }: [ "-- from ${pname}:" ] ++ map langLuaLine hyphenPatterns;
|
||||
# packages that contribute to config files and formats
|
||||
fontMaps = lib.filter (p: p ? fontMaps && (p.tlOutputName or p.outputName == "tex")) nonbin;
|
||||
sortedFontMaps = builtins.sort (a: b: a.pname < b.pname) fontMaps;
|
||||
hyphenPatterns = lib.filter (
|
||||
p: p ? hyphenPatterns && (p.tlOutputName or p.outputName == "tex")
|
||||
) nonbin;
|
||||
sortedHyphenPatterns = builtins.sort (a: b: a.pname < b.pname) hyphenPatterns;
|
||||
formatPkgs = lib.filter (
|
||||
p:
|
||||
p ? formats
|
||||
&& (p.outputSpecified or false -> p.tlOutputName or p.outputName == "tex")
|
||||
&& builtins.any (f: f.enabled or true) p.formats
|
||||
) all;
|
||||
sortedFormatPkgs =
|
||||
if __formatsOf != null then [ __formatsOf ] else builtins.sort (a: b: a.pname < b.pname) formatPkgs;
|
||||
formats = map (
|
||||
p:
|
||||
buildTeXEnv {
|
||||
requiredTeXPackages =
|
||||
ps:
|
||||
[
|
||||
ps.scheme-infraonly
|
||||
p
|
||||
]
|
||||
++ hyphenPatterns;
|
||||
__formatsOf = p;
|
||||
}
|
||||
) sortedFormatPkgs;
|
||||
};
|
||||
|
||||
assembleConfigLines = f: packages: builtins.concatStringsSep "\n" (builtins.concatMap f packages);
|
||||
# list generated by inspecting `grep -IR '\([^a-zA-Z]\|^\)gs\( \|$\|"\)' "$TEXMFDIST"/scripts`
|
||||
# and `grep -IR rungs "$TEXMFDIST"`
|
||||
# and ignoring luatex, perl, and shell scripts (those must be patched using postFixup)
|
||||
needsGhostscript = lib.any (
|
||||
p:
|
||||
lib.elem p.pname [
|
||||
"context"
|
||||
"dvipdfmx"
|
||||
"latex-papersize"
|
||||
"lyluatex"
|
||||
]
|
||||
) pkgList.bin;
|
||||
|
||||
updmapLines = { pname, fontMaps, ... }: [ "# from ${pname}:" ] ++ fontMaps;
|
||||
pname =
|
||||
if finalAttrs.__combine then
|
||||
"texlive-${finalAttrs.passthru.__extraName}" # texlive.combine: old name
|
||||
else
|
||||
"texlive";
|
||||
version =
|
||||
if finalAttrs.__combine then
|
||||
"${toString tlpdbVersion.year}${finalAttrs.passthru.__extraVersion}" # texlive.combine: old version
|
||||
else
|
||||
"${toString tlpdbVersion.year}-r${toString tlpdbVersion.revision}-"
|
||||
+ (lib.optionalString tlpdbVersion.frozen "final-")
|
||||
+ (if __formatsOf != null then "${__formatsOf.pname}-fmt" else "env");
|
||||
|
||||
in
|
||||
buildEnv {
|
||||
name = "${pname}-${version}";
|
||||
|
||||
inherit name;
|
||||
texmfdist = buildEnv {
|
||||
name = "${name}-texmfdist";
|
||||
|
||||
# remove fake derivations (without 'outPath') to avoid undesired build dependencies
|
||||
paths =
|
||||
builtins.catAttrs "outPath" pkgList.bin
|
||||
++ lib.optionals (!__combine && __formatsOf == null) pkgList.formats
|
||||
++ lib.optional __combine doc;
|
||||
pathsToLink = [
|
||||
"/"
|
||||
"/share/texmf-var/scripts"
|
||||
"/share/texmf-var/tex/generic/config"
|
||||
"/share/texmf-var/web2c"
|
||||
"/share/texmf-config"
|
||||
"/bin" # ensure these are writeable directories
|
||||
];
|
||||
# remove fake derivations (without 'outPath') to avoid undesired build dependencies
|
||||
paths = builtins.catAttrs "outPath" pkgList.nonbin;
|
||||
|
||||
postBuild = ''
|
||||
. "${./build-tex-env.sh}"
|
||||
'';
|
||||
# mktexlsr
|
||||
nativeBuildInputs = [
|
||||
tl.texlive-scripts # for mktexlsr.pl with --sort support
|
||||
perl
|
||||
];
|
||||
|
||||
derivationArgs = {
|
||||
# use attrNames, attrValues to ensure the two lists are sorted in the same way
|
||||
outputs = [
|
||||
"out"
|
||||
]
|
||||
++ lib.optionals (!__combine && __formatsOf == null) (builtins.attrNames nonEnvOutputs);
|
||||
otherOutputs = lib.optionals (!__combine && __formatsOf == null) (
|
||||
builtins.attrValues nonEnvOutputs
|
||||
postBuild = # generate ls-R database
|
||||
''
|
||||
perl ${tl.texlive-scripts.tex}/scripts/texlive/mktexlsr.pl --sort "$out"
|
||||
'';
|
||||
};
|
||||
|
||||
tlpkg = buildEnv {
|
||||
name = "${name}-tlpkg";
|
||||
|
||||
# remove fake derivations (without 'outPath') to avoid undesired build dependencies
|
||||
paths = builtins.catAttrs "outPath" pkgList.tlpkg;
|
||||
};
|
||||
|
||||
# the 'non-relocated' packages must live in $TEXMFROOT/texmf-dist
|
||||
# and sometimes look into $TEXMFROOT/tlpkg (notably fmtutil, updmap look for perl modules in both)
|
||||
texmfroot =
|
||||
runCommand "${name}-texmfroot"
|
||||
{
|
||||
inherit texmfdist tlpkg;
|
||||
}
|
||||
''
|
||||
mkdir -p "$out"
|
||||
ln -s "$texmfdist" "$out"/texmf-dist
|
||||
ln -s "$tlpkg" "$out"/tlpkg
|
||||
'';
|
||||
|
||||
# texlive.combine: expose info and man pages in usual /share/{info,man} location
|
||||
doc = buildEnv {
|
||||
name = "${name}-doc";
|
||||
|
||||
paths = [ (texmfdist.outPath + "/doc") ];
|
||||
extraPrefix = "/share";
|
||||
|
||||
pathsToLink = [
|
||||
"/info"
|
||||
"/man"
|
||||
];
|
||||
};
|
||||
|
||||
meta = {
|
||||
description =
|
||||
"TeX Live environment"
|
||||
+ lib.optionalString withDocs " with documentation"
|
||||
+ lib.optionalString (withDocs && withSources) " and"
|
||||
+ lib.optionalString withSources " with sources";
|
||||
platforms = lib.platforms.all;
|
||||
longDescription =
|
||||
"Contains the following packages and their transitive dependencies:\n - "
|
||||
+ lib.concatMapStringsSep "\n - " (
|
||||
p:
|
||||
p.pname + (lib.optionalString (p.outputSpecified or false) " (${p.tlOutputName or p.outputName})")
|
||||
) (finalAttrs.passthru.requiredTeXPackages tl);
|
||||
};
|
||||
|
||||
# other outputs
|
||||
nonEnvOutputs = lib.genAttrs pkgList.nonEnvOutputs (
|
||||
outName:
|
||||
buildEnv {
|
||||
inherit name;
|
||||
paths = builtins.catAttrs "outPath" (
|
||||
pkgList.otherOutputs.${outName} or [ ] ++ pkgList.specifiedOutputs.${outName} or [ ]
|
||||
);
|
||||
derivationArgs = {
|
||||
outputs = [ outName ];
|
||||
nativeBuildInputs = [
|
||||
# force the output to be ${outName} or nix-env will not work
|
||||
(writeShellScript "force-output.sh" ''
|
||||
export out="''${${outName}-}"
|
||||
'')
|
||||
];
|
||||
inherit meta passthru;
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
nativeBuildInputs = [
|
||||
makeWrapper
|
||||
libfaketime
|
||||
tl."texlive.infra" # mktexlsr
|
||||
tl.texlive-scripts # fmtutil, updmap
|
||||
tl.texlive-scripts-extra # texlinks
|
||||
perl
|
||||
passthru = {
|
||||
inherit
|
||||
requiredTeXPackages
|
||||
__fromCombineWrapper
|
||||
__extraName
|
||||
__extraVersion
|
||||
;
|
||||
# This is set primarily to help find-tarballs.nix to do its job
|
||||
includedTeXPackages = builtins.filter lib.isDerivation (
|
||||
pkgList.bin
|
||||
++ pkgList.nonbin
|
||||
++ lib.optionals (!finalAttrs.passthru.__fromCombineWrapper) (
|
||||
lib.concatMap (
|
||||
n: (pkgList.otherOutputs.${n} or [ ] ++ pkgList.specifiedOutputs.${n} or [ ])
|
||||
) pkgList.nonEnvOutputs
|
||||
)
|
||||
);
|
||||
# useful for inclusion in the `fonts.packages` nixos option or for use in devshells
|
||||
fonts = "${texmfroot}/texmf-dist/fonts";
|
||||
__overrideTeXConfig = lib.warn "__overrideTeXConfig is deprecated, please switch to overrideAttrs" (
|
||||
newArgs:
|
||||
let
|
||||
# arguments of buildTeXEnv before deprecation of __overrideTeXConfig
|
||||
prevArgs = {
|
||||
withDocs = finalAttrs.passthru.withDocs or false;
|
||||
withSources = finalAttrs.passthru.withSources or false;
|
||||
inherit (finalAttrs)
|
||||
__combine
|
||||
;
|
||||
inherit (finalAttrs.passthru)
|
||||
requiredTeXPackages
|
||||
__extraName
|
||||
__extraVersion
|
||||
__fromCombineWrapper
|
||||
;
|
||||
};
|
||||
appliedArgs = prevArgs // (if builtins.isFunction newArgs then newArgs prevArgs else newArgs);
|
||||
in
|
||||
finalAttrs.finalPackage.overrideAttrs (prevAttrs: {
|
||||
passthru = prevAttrs.passthru // {
|
||||
inherit (appliedArgs)
|
||||
withDocs
|
||||
withSources
|
||||
requiredTeXPackages
|
||||
__extraName
|
||||
__extraVersion
|
||||
;
|
||||
__fromCombineWrapper = false;
|
||||
};
|
||||
inherit (appliedArgs) __combine;
|
||||
})
|
||||
);
|
||||
withPackages =
|
||||
reqs:
|
||||
finalAttrs.finalPackage.overrideAttrs (prevAttrs: {
|
||||
passthru = prevAttrs.passthru // {
|
||||
requiredTeXPackages = ps: reqs ps ++ prevAttrs.passthru.requiredTeXPackages ps;
|
||||
__fromCombineWrapper = false;
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
# TeXLive::TLOBJ::fmtutil_cnf_lines
|
||||
fmtutilLine =
|
||||
{
|
||||
name,
|
||||
engine,
|
||||
enabled ? true,
|
||||
patterns ? [ "-" ],
|
||||
options ? "",
|
||||
...
|
||||
}:
|
||||
lib.optionalString (!enabled) "#! "
|
||||
+ "${name} ${engine} ${lib.concatStringsSep "," patterns} ${options}";
|
||||
fmtutilLines =
|
||||
{ pname, formats, ... }:
|
||||
[
|
||||
"#"
|
||||
"# from ${pname}:"
|
||||
]
|
||||
++ map fmtutilLine formats;
|
||||
|
||||
# TeXLive::TLOBJ::language_dat_lines
|
||||
langDatLine =
|
||||
{
|
||||
name,
|
||||
file,
|
||||
synonyms ? [ ],
|
||||
...
|
||||
}:
|
||||
[ "${name} ${file}" ] ++ map (s: "=" + s) synonyms;
|
||||
langDatLines =
|
||||
{ pname, hyphenPatterns, ... }:
|
||||
[ "% from ${pname}:" ] ++ builtins.concatMap langDatLine hyphenPatterns;
|
||||
|
||||
# TeXLive::TLOBJ::language_def_lines
|
||||
# see TeXLive::TLUtils::parse_AddHyphen_line for default values
|
||||
langDefLine =
|
||||
{
|
||||
name,
|
||||
file,
|
||||
lefthyphenmin ? "",
|
||||
righthyphenmin ? "",
|
||||
synonyms ? [ ],
|
||||
...
|
||||
}:
|
||||
map (
|
||||
n:
|
||||
"\\addlanguage{${n}}{${file}}{}{${if lefthyphenmin == "" then "2" else lefthyphenmin}}{${
|
||||
if righthyphenmin == "" then "3" else righthyphenmin
|
||||
}}"
|
||||
) ([ name ] ++ synonyms);
|
||||
langDefLines =
|
||||
{ pname, hyphenPatterns, ... }:
|
||||
[ "% from ${pname}:" ] ++ builtins.concatMap langDefLine hyphenPatterns;
|
||||
|
||||
# TeXLive::TLOBJ::language_lua_lines
|
||||
# see TeXLive::TLUtils::parse_AddHyphen_line for default values
|
||||
langLuaLine =
|
||||
{
|
||||
name,
|
||||
file,
|
||||
lefthyphenmin ? "",
|
||||
righthyphenmin ? "",
|
||||
synonyms ? [ ],
|
||||
...
|
||||
}@args:
|
||||
''
|
||||
''\t['${name}'] = {
|
||||
''\t''\tloader = '${file}',
|
||||
''\t''\tlefthyphenmin = ${if lefthyphenmin == "" then "2" else lefthyphenmin},
|
||||
''\t''\trighthyphenmin = ${if righthyphenmin == "" then "3" else righthyphenmin},
|
||||
''\t''\tsynonyms = { ${lib.concatStringsSep ", " (map (s: "'${s}'") synonyms)} },
|
||||
''
|
||||
+ lib.optionalString (args ? file_patterns) "\t\tpatterns = '${args.file_patterns}',\n"
|
||||
+ lib.optionalString (args ? file_exceptions) "\t\thyphenation = '${args.file_exceptions}',\n"
|
||||
+ lib.optionalString (args ? luaspecial) "\t\tspecial = '${args.luaspecial}',\n"
|
||||
+ "\t},";
|
||||
langLuaLines =
|
||||
{ pname, hyphenPatterns, ... }: [ "-- from ${pname}:" ] ++ map langLuaLine hyphenPatterns;
|
||||
|
||||
assembleConfigLines = f: packages: builtins.concatStringsSep "\n" (builtins.concatMap f packages);
|
||||
|
||||
updmapLines = { pname, fontMaps, ... }: [ "# from ${pname}:" ] ++ fontMaps;
|
||||
|
||||
in
|
||||
{
|
||||
|
||||
inherit name;
|
||||
|
||||
# remove fake derivations (without 'outPath') to avoid undesired build dependencies
|
||||
paths =
|
||||
builtins.catAttrs "outPath" pkgList.bin
|
||||
++ lib.optionals (!finalAttrs.__combine && __formatsOf == null) pkgList.formats
|
||||
++ lib.optional finalAttrs.__combine doc;
|
||||
pathsToLink = [
|
||||
"/"
|
||||
"/share/texmf-var/scripts"
|
||||
"/share/texmf-var/tex/generic/config"
|
||||
"/share/texmf-var/web2c"
|
||||
"/share/texmf-config"
|
||||
"/bin" # ensure these are writeable directories
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
coreutils
|
||||
gawk
|
||||
gnugrep
|
||||
gnused
|
||||
]
|
||||
++ lib.optional needsGhostscript ghostscript;
|
||||
postBuild = ''
|
||||
. "${./build-tex-env.sh}"
|
||||
'';
|
||||
|
||||
inherit passthru __combine;
|
||||
__formatsOf = __formatsOf.pname or null;
|
||||
derivationArgs = {
|
||||
# use attrNames, attrValues to ensure the two lists are sorted in the same way
|
||||
outputs = [
|
||||
"out"
|
||||
]
|
||||
++ lib.optionals (!finalAttrs.__combine && __formatsOf == null) (builtins.attrNames nonEnvOutputs);
|
||||
otherOutputs = lib.optionals (!finalAttrs.__combine && __formatsOf == null) (
|
||||
builtins.attrValues nonEnvOutputs
|
||||
);
|
||||
|
||||
inherit texmfdist texmfroot;
|
||||
nativeBuildInputs = [
|
||||
makeWrapper
|
||||
libfaketime
|
||||
tl."texlive.infra" # mktexlsr
|
||||
tl.texlive-scripts # fmtutil, updmap
|
||||
tl.texlive-scripts-extra # texlinks
|
||||
perl
|
||||
];
|
||||
|
||||
fontconfigFile = makeFontsConf { fontDirectories = [ "${texmfroot}/texmf-dist/fonts" ]; };
|
||||
buildInputs = [
|
||||
coreutils
|
||||
gawk
|
||||
gnugrep
|
||||
gnused
|
||||
]
|
||||
++ lib.optional needsGhostscript ghostscript;
|
||||
|
||||
fmtutilCnf = assembleConfigLines fmtutilLines pkgList.sortedFormatPkgs;
|
||||
updmapCfg = assembleConfigLines updmapLines pkgList.sortedFontMaps;
|
||||
inherit passthru __combine;
|
||||
__formatsOf = __formatsOf.pname or null;
|
||||
|
||||
languageDat = assembleConfigLines langDatLines pkgList.sortedHyphenPatterns;
|
||||
languageDef = assembleConfigLines langDefLines pkgList.sortedHyphenPatterns;
|
||||
languageLua = assembleConfigLines langLuaLines pkgList.sortedHyphenPatterns;
|
||||
inherit texmfdist texmfroot;
|
||||
|
||||
postactionScripts = builtins.catAttrs "postactionScript" pkgList.tlpkg;
|
||||
fontconfigFile = makeFontsConf { fontDirectories = [ "${texmfroot}/texmf-dist/fonts" ]; };
|
||||
|
||||
allowSubstitutes = true;
|
||||
preferLocalBuild = false;
|
||||
fmtutilCnf = assembleConfigLines fmtutilLines pkgList.sortedFormatPkgs;
|
||||
updmapCfg = assembleConfigLines updmapLines pkgList.sortedFontMaps;
|
||||
|
||||
meta =
|
||||
meta
|
||||
// lib.optionalAttrs (!__combine && __formatsOf == null) {
|
||||
inherit (pkgList) outputsToInstall;
|
||||
};
|
||||
};
|
||||
}
|
||||
languageDat = assembleConfigLines langDatLines pkgList.sortedHyphenPatterns;
|
||||
languageDef = assembleConfigLines langDefLines pkgList.sortedHyphenPatterns;
|
||||
languageLua = assembleConfigLines langLuaLines pkgList.sortedHyphenPatterns;
|
||||
|
||||
postactionScripts = builtins.catAttrs "postactionScript" pkgList.tlpkg;
|
||||
|
||||
allowSubstitutes = true;
|
||||
preferLocalBuild = false;
|
||||
|
||||
meta =
|
||||
meta
|
||||
// lib.optionalAttrs (!finalAttrs.__combine && __formatsOf == null) {
|
||||
inherit (pkgList) outputsToInstall;
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
@@ -233,7 +233,7 @@ let
|
||||
|
||||
# function for creating a working environment
|
||||
buildTeXEnv = import ./build-tex-env.nix {
|
||||
inherit bin tl;
|
||||
inherit tl;
|
||||
inherit tlpdbVersion;
|
||||
ghostscript = ghostscript_headless;
|
||||
inherit
|
||||
@@ -244,9 +244,7 @@ let
|
||||
makeWrapper
|
||||
runCommand
|
||||
writeShellScript
|
||||
writeText
|
||||
toTLPkgSets
|
||||
bash
|
||||
perl
|
||||
coreutils
|
||||
gawk
|
||||
|
||||
Reference in New Issue
Block a user