Merge pull request #250805 from xworld21/texlive-buildenv-minimal

texlive: overrideTeXConfig/withPackages

authored by Dmitry Kalinkin and committed by GitHub ec2e217c f77fc56a

+823 -523
+18
doc/languages-frameworks/texlive.section.md
··· 38 39 - Note that the wrapper assumes that the result has a chance to be useful. For example, the core executables should be present, as well as some core data files. The supported way of ensuring this is by including some scheme, for example `scheme-basic`, into the combination. 40 41 ## Custom packages {#sec-language-texlive-custom-packages} 42 43 You may find that you need to use an external TeX package. A derivation for such package has to provide the contents of the "texmf" directory in its output and provide the appropriate `tlType` attribute (one of `"run"`, `"bin"`, `"doc"`, `"source"`). Dependencies on other TeX packages can be listed in the attribute `tlDeps`.
··· 38 39 - Note that the wrapper assumes that the result has a chance to be useful. For example, the core executables should be present, as well as some core data files. The supported way of ensuring this is by including some scheme, for example `scheme-basic`, into the combination. 40 41 + - TeX Live packages are also available under `texlive.pkgs` as derivations with outputs `out`, `tex`, `texdoc`, `texsource`, `tlpkg`, `man`, `info`. They cannot be installed outside of `texlive.combine` but are available for other uses. To repackage a font, for instance, use 42 + 43 + ```nix 44 + stdenvNoCC.mkDerivation rec { 45 + src = texlive.pkgs.iwona; 46 + 47 + inherit (src) pname version; 48 + 49 + installPhase = '' 50 + runHook preInstall 51 + install -Dm644 fonts/opentype/nowacki/iwona/*.otf -t $out/share/fonts/opentype 52 + runHook postInstall 53 + ''; 54 + } 55 + ``` 56 + 57 + See `biber`, `iwona` for complete examples. 58 + 59 ## Custom packages {#sec-language-texlive-custom-packages} 60 61 You may find that you need to use an external TeX package. A derivation for such package has to provide the contents of the "texmf" directory in its output and provide the appropriate `tlType` attribute (one of `"run"`, `"bin"`, `"doc"`, `"source"`). Dependencies on other TeX packages can be listed in the attribute `tlDeps`.
+4 -5
pkgs/data/fonts/iwona/default.nix
··· 1 { lib, stdenvNoCC, texlive }: 2 3 - stdenvNoCC.mkDerivation { 4 - pname = "iwona"; 5 - version = "0.995b"; 6 7 - src = lib.head (builtins.filter (p: p.tlType == "run") texlive.iwona.pkgs); 8 9 installPhase = '' 10 runHook preInstall ··· 20 # "[...] GUST Font License (GFL), which is a free license, legally 21 # equivalent to the LaTeX Project Public # License (LPPL), version 1.3c or 22 # later." - GUST website 23 - license = licenses.lppl13c; 24 maintainers = with maintainers; [ siddharthist ]; 25 platforms = platforms.all; 26 };
··· 1 { lib, stdenvNoCC, texlive }: 2 3 + stdenvNoCC.mkDerivation rec { 4 + inherit (src) pname version; 5 6 + src = texlive.pkgs.iwona; 7 8 installPhase = '' 9 runHook preInstall ··· 19 # "[...] GUST Font License (GFL), which is a free license, legally 20 # equivalent to the LaTeX Project Public # License (LPPL), version 1.3c or 21 # later." - GUST website 22 + license = src.meta.license; 23 maintainers = with maintainers; [ siddharthist ]; 24 platforms = platforms.all; 25 };
+10 -8
pkgs/misc/sagetex/default.nix
··· 1 { lib 2 , stdenv 3 , fetchFromGitHub 4 , texlive 5 }: 6 7 - stdenv.mkDerivation (finalAttrs: rec { 8 pname = "sagetex"; 9 version = "3.6.1"; 10 ··· 15 sha256 = "sha256-OfhbXHbGI+DaDHqZCOGiSHJPHjGuT7ZqSEjKweloW38="; 16 }; 17 18 - buildInputs = [ 19 texlive.combined.scheme-basic 20 ]; 21 22 buildPhase = '' ··· 29 cp -va *.sty *.cfg *.def "$path/" 30 ''; 31 32 - passthru = { 33 - tlType = "run"; 34 - pkgs = [ finalAttrs.finalPackage ]; 35 - }; 36 - 37 meta = with lib; { 38 description = "Embed code, results of computations, and plots from Sage into LaTeX documents"; 39 homepage = "https://github.com/sagemath/sagetex"; ··· 41 maintainers = with maintainers; [ alexnortung ]; 42 platforms = platforms.all; 43 }; 44 - })
··· 1 { lib 2 , stdenv 3 , fetchFromGitHub 4 + , writeShellScript 5 , texlive 6 }: 7 8 + stdenv.mkDerivation rec { 9 pname = "sagetex"; 10 version = "3.6.1"; 11 ··· 16 sha256 = "sha256-OfhbXHbGI+DaDHqZCOGiSHJPHjGuT7ZqSEjKweloW38="; 17 }; 18 19 + outputs = [ "tex" ]; 20 + 21 + nativeBuildInputs = [ 22 texlive.combined.scheme-basic 23 + # multiple-outputs.sh fails if $out is not defined 24 + (writeShellScript "force-tex-output.sh" '' 25 + out="''${tex-}" 26 + '') 27 ]; 28 29 buildPhase = '' ··· 36 cp -va *.sty *.cfg *.def "$path/" 37 ''; 38 39 meta = with lib; { 40 description = "Embed code, results of computations, and plots from Sage into LaTeX documents"; 41 homepage = "https://github.com/sagemath/sagetex"; ··· 43 maintainers = with maintainers; [ alexnortung ]; 44 platforms = platforms.all; 45 }; 46 + }
+10 -9
pkgs/test/texlive/default.nix
··· 454 ''; 455 456 # link all binaries in single derivation 457 - allPackages = with lib; concatLists (catAttrs "pkgs" (filter isAttrs (attrValues texlive))); 458 - binPackages = lib.filter (p: p.tlType == "bin") allPackages; 459 binaries = buildEnv { name = "texlive-binaries"; paths = binPackages; }; 460 in 461 runCommand "texlive-test-binaries" ··· 565 566 # check that all scripts have a Nix shebang 567 shebangs = let 568 - allPackages = with lib; concatLists (catAttrs "pkgs" (filter isAttrs (attrValues texlive))); 569 - binPackages = lib.filter (p: p.tlType == "bin") allPackages; 570 in 571 runCommand "texlive-test-shebangs" { } 572 ('' ··· 615 correctLicenses = scheme: builtins.foldl' 616 (acc: pkg: concatLicenses acc (lib.toList (pkg.meta.license or []))) 617 [] 618 - scheme.passthru.packages; 619 correctLicensesAttrNames = scheme: 620 lib.sort lt 621 (map licenseToAttrName (correctLicenses scheme)); ··· 648 # this is effectively an eval-time assertion, converted into a derivation for 649 # ease of testing 650 fixedHashes = with lib; let 651 - combine = findFirst (p: (head p.pkgs).pname == "combine") { pkgs = []; } (head texlive.collection-latexextra.pkgs).tlDeps; 652 - all = concatLists (map (p: p.pkgs or []) (attrValues (removeAttrs texlive [ "bin" "combine" "combined" "tlpdb" ]))) ++ combine.pkgs; 653 - fods = filter (p: isDerivation p && p.tlType != "bin") all; 654 - errorText = concatMapStrings (p: optionalString (! p ? outputHash) "${p.pname + optionalString (p.tlType != "run") ("." + p.tlType)} does not have a fixed output hash\n") fods; 655 in runCommand "texlive-test-fixed-hashes" { 656 inherit errorText; 657 passAsFile = [ "errorText" ];
··· 454 ''; 455 456 # link all binaries in single derivation 457 + binPackages = lib.catAttrs "out" (lib.attrValues texlive.pkgs); 458 binaries = buildEnv { name = "texlive-binaries"; paths = binPackages; }; 459 in 460 runCommand "texlive-test-binaries" ··· 564 565 # check that all scripts have a Nix shebang 566 shebangs = let 567 + binPackages = lib.catAttrs "out" (lib.attrValues texlive.pkgs); 568 in 569 runCommand "texlive-test-shebangs" { } 570 ('' ··· 613 correctLicenses = scheme: builtins.foldl' 614 (acc: pkg: concatLicenses acc (lib.toList (pkg.meta.license or []))) 615 [] 616 + scheme.passthru.requiredTeXPackages; 617 correctLicensesAttrNames = scheme: 618 lib.sort lt 619 (map licenseToAttrName (correctLicenses scheme)); ··· 646 # this is effectively an eval-time assertion, converted into a derivation for 647 # ease of testing 648 fixedHashes = with lib; let 649 + fods = lib.concatMap 650 + (p: lib.optional (p ? tex) p.tex 651 + ++ lib.optional (p ? texdoc) p.texdoc 652 + ++ lib.optional (p ? texsource) p.texsource 653 + ++ lib.optional (p ? tlpkg) p.tlpkg) 654 + (attrValues texlive.pkgs); 655 + errorText = concatMapStrings (p: optionalString (! p ? outputHash) "${p.pname}-${p.tlOutputName} does not have a fixed output hash\n") fods; 656 in runCommand "texlive-test-fixed-hashes" { 657 inherit errorText; 658 passAsFile = [ "errorText" ];
+2 -3
pkgs/tools/typesetting/biber-ms/default.nix
··· 1 { lib, stdenv, fetchFromGitHub, fetchurl, perlPackages, shortenPerlShebang, texlive }: 2 3 let 4 - biberSource = lib.head (builtins.filter (p: p.tlType == "source") texlive.biber-ms.pkgs); 5 # missing test file 6 multiscriptBltxml = (fetchFromGitHub { 7 owner = "plk"; ··· 12 in 13 14 perlPackages.buildPerlModule { 15 - pname = "biber-ms"; 16 - inherit (biberSource) version; 17 18 src = "${biberSource}/source/bibtex/biber-ms/biblatex-biber-ms.tar.gz"; 19
··· 1 { lib, stdenv, fetchFromGitHub, fetchurl, perlPackages, shortenPerlShebang, texlive }: 2 3 let 4 + biberSource = texlive.pkgs.biber-ms.texsource; 5 # missing test file 6 multiscriptBltxml = (fetchFromGitHub { 7 owner = "plk"; ··· 12 in 13 14 perlPackages.buildPerlModule { 15 + inherit (biberSource) pname version; 16 17 src = "${biberSource}/source/bibtex/biber-ms/biblatex-biber-ms.tar.gz"; 18
+2 -3
pkgs/tools/typesetting/biber/default.nix
··· 1 { lib, stdenv, fetchurl, perlPackages, shortenPerlShebang, texlive }: 2 3 let 4 - biberSource = lib.head (builtins.filter (p: p.tlType == "source") texlive.biber.pkgs); 5 in 6 7 perlPackages.buildPerlModule { 8 - pname = "biber"; 9 - inherit (biberSource) version; 10 11 src = "${biberSource}/source/bibtex/biber/biblatex-biber.tar.gz"; 12
··· 1 { lib, stdenv, fetchurl, perlPackages, shortenPerlShebang, texlive }: 2 3 let 4 + biberSource = texlive.pkgs.biber.texsource; 5 in 6 7 perlPackages.buildPerlModule { 8 + inherit (biberSource) pname version; 9 10 src = "${biberSource}/source/bibtex/biber/biblatex-biber.tar.gz"; 11
+1 -5
pkgs/tools/typesetting/tex/mftrace/default.nix
··· 43 44 # experimental texlive.combine support 45 # (note that only the bin/ folder will be combined into texlive) 46 - passthru = { 47 - tlType = "bin"; 48 - tlDeps = with texlive; [ kpathsea t1utils metafont ]; 49 - pkgs = [ finalAttrs.finalPackage ]; 50 - }; 51 52 meta = with lib; { 53 description = "Scalable PostScript Fonts for MetaFont";
··· 43 44 # experimental texlive.combine support 45 # (note that only the bin/ folder will be combined into texlive) 46 + passthru.tlDeps = with texlive; [ kpathsea t1utils metafont ]; 47 48 meta = with lib; { 49 description = "Scalable PostScript Fonts for MetaFont";
+2 -2
pkgs/tools/typesetting/tex/texlive/bin.nix
··· 355 inherit (src) version; 356 format = "other"; 357 358 - src = assertFixedHash pname (lib.head (builtins.filter (p: p.tlType == "run") texlive.pygmentex.pkgs)); 359 360 propagatedBuildInputs = with python3Packages; [ pygments chardet ]; 361 ··· 436 437 xpdfopen = stdenv.mkDerivation { 438 pname = "texlive-xpdfopen.bin"; 439 - inherit (lib.head texlive.xpdfopen.pkgs) version; 440 441 inherit (common) src; 442
··· 355 inherit (src) version; 356 format = "other"; 357 358 + src = assertFixedHash pname texlive.pkgs.pygmentex.tex; 359 360 propagatedBuildInputs = with python3Packages; [ pygments chardet ]; 361 ··· 436 437 xpdfopen = stdenv.mkDerivation { 438 pname = "texlive-xpdfopen.bin"; 439 + inherit (texlive.pkgs.xpdfopen) version; 440 441 inherit (common) src; 442
+434
pkgs/tools/typesetting/tex/texlive/build-tex-env.nix
···
··· 1 + { 2 + # texlive package set 3 + tl 4 + , bin 5 + 6 + , lib 7 + , buildEnv 8 + , libfaketime 9 + , makeFontsConf 10 + , makeWrapper 11 + , runCommand 12 + , writeShellScript 13 + , writeText 14 + , toTLPkgSets 15 + , bash 16 + , perl 17 + 18 + # common runtime dependencies 19 + , coreutils 20 + , gawk 21 + , gnugrep 22 + , gnused 23 + , ghostscript 24 + }: 25 + 26 + lib.fix (self: { 27 + withDocs ? false 28 + , withSources ? false 29 + , requiredTeXPackages ? ps: [ ps.scheme-infraonly ] 30 + 31 + ### texlive.combine backward compatibility 32 + , __extraName ? "combined" 33 + , __extraVersion ? "" 34 + # emulate the old texlive.combine (e.g. add man pages to main output) 35 + , __combine ? false 36 + # adjust behavior further if called from the texlive.combine wrapper 37 + , __fromCombineWrapper ? false 38 + }@args: 39 + 40 + let 41 + ### texlive.combine backward compatibility 42 + # if necessary, convert old style { pkgs = [ ... ]; } packages to attribute sets 43 + ensurePkgSets = ps: if ! __fromCombineWrapper && builtins.any (p: p ? pkgs && builtins.all (p: p ? tlType) p.pkgs) ps 44 + then let oldStyle = builtins.partition (p: p ? pkgs && builtins.all (p: p ? tlType) p.pkgs) ps; 45 + in oldStyle.wrong ++ lib.concatMap toTLPkgSets oldStyle.right 46 + else ps; 47 + 48 + pkgList = rec { 49 + # resolve dependencies of the packages that affect the runtime 50 + all = 51 + let 52 + # order of packages is irrelevant 53 + packages = builtins.sort (a: b: a.pname < b.pname) (ensurePkgSets (requiredTeXPackages tl)); 54 + runtime = builtins.partition 55 + (p: p.outputSpecified or false -> builtins.elem (p.tlOutputName or p.outputName) [ "out" "tex" "tlpkg" ]) 56 + packages; 57 + keySet = p: { 58 + key = ((p.name or "${p.pname}-${p.version}") + "-" + p.tlOutputName or p.outputName or ""); 59 + inherit p; 60 + tlDeps = p.tlDeps or (p.requiredTeXPackages or (_: [ ]) [ ]); 61 + }; 62 + in 63 + # texlive.combine: the wrapper already resolves all dependencies 64 + if __fromCombineWrapper then requiredTeXPackages null else 65 + builtins.catAttrs "p" (builtins.genericClosure { 66 + startSet = map keySet runtime.right; 67 + operator = p: map keySet p.tlDeps; 68 + }) ++ runtime.wrong; 69 + 70 + # group the specified outputs 71 + specified = builtins.partition (p: p.outputSpecified or false) all; 72 + specifiedOutputs = builtins.groupBy (p: p.tlOutputName or p.outputName) specified.right; 73 + otherOutputNames = builtins.catAttrs "key" (builtins.genericClosure { 74 + startSet = map (key: { inherit key; }) (lib.concatLists (builtins.catAttrs "outputs" specified.wrong)); 75 + operator = _: [ ]; 76 + }); 77 + otherOutputs = lib.genAttrs otherOutputNames (n: builtins.catAttrs n specified.wrong); 78 + outputsToInstall = builtins.catAttrs "key" (builtins.genericClosure { 79 + startSet = map (key: { inherit key; }) 80 + ([ "out" ] ++ lib.optional (splitOutputs ? man) "man" 81 + ++ lib.concatLists (builtins.catAttrs "outputsToInstall" (builtins.catAttrs "meta" specified.wrong))); 82 + operator = _: [ ]; 83 + }); 84 + 85 + # split binary and tlpkg from tex, texdoc, texsource 86 + bin = if __fromCombineWrapper 87 + then builtins.filter (p: p.tlType == "bin") all # texlive.combine: legacy filter 88 + else otherOutputs.out or [ ] ++ specifiedOutputs.out or [ ]; 89 + tlpkg = if __fromCombineWrapper 90 + then builtins.filter (p: p.tlType == "tlpkg") all # texlive.combine: legacy filter 91 + else otherOutputs.tlpkg or [ ] ++ specifiedOutputs.tlpkg or [ ]; 92 + 93 + nonbin = if __fromCombineWrapper then builtins.filter (p: p.tlType != "bin" && p.tlType != "tlpkg") all # texlive.combine: legacy filter 94 + else (if __combine then # texlive.combine: emulate old input ordering to avoid rebuilds 95 + lib.concatMap (p: lib.optional (p ? tex) p.tex 96 + ++ lib.optional ((withDocs || p ? man) && p ? texdoc) p.texdoc 97 + ++ lib.optional (withSources && p ? texsource) p.texsource) specified.wrong 98 + else otherOutputs.tex or [ ] 99 + ++ lib.optionals withDocs (otherOutputs.texdoc or [ ]) 100 + ++ lib.optionals withSources (otherOutputs.texsource or [ ])) 101 + ++ specifiedOutputs.tex or [ ] ++ specifiedOutputs.texdoc or [ ] ++ specifiedOutputs.texsource or [ ]; 102 + 103 + # outputs that do not become part of the environment 104 + nonEnvOutputs = lib.subtractLists [ "out" "tex" "texdoc" "texsource" "tlpkg" ] otherOutputNames; 105 + }; 106 + 107 + # list generated by inspecting `grep -IR '\([^a-zA-Z]\|^\)gs\( \|$\|"\)' "$TEXMFDIST"/scripts` 108 + # and `grep -IR rungs "$TEXMFDIST"` 109 + # and ignoring luatex, perl, and shell scripts (those must be patched using postFixup) 110 + needsGhostscript = lib.any (p: lib.elem p.pname [ "context" "dvipdfmx" "latex-papersize" "lyluatex" ]) pkgList.bin; 111 + 112 + name = if __combine then "texlive-${__extraName}-${bin.texliveYear}${__extraVersion}" # texlive.combine: old name name 113 + else "texlive-${bin.texliveYear}-env"; 114 + 115 + texmfdist = (buildEnv { 116 + name = "${name}-texmfdist"; 117 + 118 + # remove fake derivations (without 'outPath') to avoid undesired build dependencies 119 + paths = builtins.catAttrs "outPath" pkgList.nonbin; 120 + 121 + # mktexlsr 122 + nativeBuildInputs = [ tl."texlive.infra" ]; 123 + 124 + postBuild = # generate ls-R database 125 + '' 126 + mktexlsr "$out" 127 + ''; 128 + }).overrideAttrs (_: { allowSubstitutes = true; }); 129 + 130 + tlpkg = (buildEnv { 131 + name = "${name}-tlpkg"; 132 + 133 + # remove fake derivations (without 'outPath') to avoid undesired build dependencies 134 + paths = builtins.catAttrs "outPath" pkgList.tlpkg; 135 + }).overrideAttrs (_: { allowSubstitutes = true; }); 136 + 137 + # the 'non-relocated' packages must live in $TEXMFROOT/texmf-dist 138 + # and sometimes look into $TEXMFROOT/tlpkg (notably fmtutil, updmap look for perl modules in both) 139 + texmfroot = runCommand "${name}-texmfroot" { 140 + inherit texmfdist tlpkg; 141 + } '' 142 + mkdir -p "$out" 143 + ln -s "$texmfdist" "$out"/texmf-dist 144 + ln -s "$tlpkg" "$out"/tlpkg 145 + ''; 146 + 147 + # texlive.combine: expose info and man pages in usual /share/{info,man} location 148 + doc = buildEnv { 149 + name = "${name}-doc"; 150 + 151 + paths = [ (texmfdist.outPath + "/doc") ]; 152 + extraPrefix = "/share"; 153 + 154 + pathsToLink = [ 155 + "/info" 156 + "/man" 157 + ]; 158 + }; 159 + 160 + meta = { 161 + description = "TeX Live environment" 162 + + lib.optionalString withDocs " with documentation" 163 + + lib.optionalString (withDocs && withSources) " and" 164 + + lib.optionalString withSources " with sources"; 165 + platforms = lib.platforms.all; 166 + longDescription = "Contains the following packages and their transitive dependencies:\n - " 167 + + lib.concatMapStringsSep "\n - " 168 + (p: p.pname + (lib.optionalString (p.outputSpecified or false) " (${p.tlOutputName or p.outputName})")) 169 + (requiredTeXPackages tl); 170 + }; 171 + 172 + # emulate split output derivation 173 + splitOutputs = { 174 + out = out // { outputSpecified = true; }; 175 + texmfdist = texmfdist // { outputSpecified = true; }; 176 + texmfroot = texmfroot // { outputSpecified = true; }; 177 + } // (lib.genAttrs pkgList.nonEnvOutputs (outName: (buildEnv { 178 + inherit name; 179 + paths = builtins.catAttrs "outPath" 180 + (pkgList.otherOutputs.${outName} or [ ] ++ pkgList.specifiedOutputs.${outName} or [ ]); 181 + # force the output to be ${outName} or nix-env will not work 182 + nativeBuildInputs = [ (writeShellScript "force-output.sh" '' 183 + export out="''${${outName}-}" 184 + '') ]; 185 + inherit meta passthru; 186 + }).overrideAttrs { outputs = [ outName ]; } // { outputSpecified = true; })); 187 + 188 + passthru = lib.optionalAttrs (! __combine) (splitOutputs // { 189 + all = builtins.attrValues splitOutputs; 190 + outputs = [ "out" ] ++ pkgList.nonEnvOutputs; 191 + }) // { 192 + # This is set primarily to help find-tarballs.nix to do its job 193 + requiredTeXPackages = builtins.filter lib.isDerivation (pkgList.bin ++ pkgList.nonbin 194 + ++ lib.optionals (! __fromCombineWrapper) 195 + (lib.concatMap (n: (pkgList.otherOutputs.${n} or [ ] ++ pkgList.specifiedOutputs.${n} or [ ]))) pkgList.nonEnvOutputs); 196 + # useful for inclusion in the `fonts.packages` nixos option or for use in devshells 197 + fonts = "${texmfroot}/texmf-dist/fonts"; 198 + # support variants attrs, (prev: attrs) 199 + __overrideTeXConfig = newArgs: 200 + let appliedArgs = if builtins.isFunction newArgs then newArgs args else newArgs; in 201 + self (args // { __fromCombineWrapper = false; } // appliedArgs); 202 + withPackages = reqs: self (args // { requiredTeXPackages = ps: requiredTeXPackages ps ++ reqs ps; __fromCombineWrapper = false; }); 203 + }; 204 + 205 + out = (if (! __combine) 206 + # meta.outputsToInstall = [ "out" "man" ] is invalid within buildEnv: 207 + # checkMeta will notice that there is no actual "man" output, and fail 208 + # so we set outputsToInstall from the outside, where it is safe 209 + then lib.addMetaAttrs { inherit (pkgList) outputsToInstall; } 210 + else x: x) # texlive.combine: man pages used to be part of out 211 + # no indent for git diff purposes 212 + ((buildEnv { 213 + 214 + inherit name; 215 + 216 + ignoreCollisions = false; 217 + 218 + # remove fake derivations (without 'outPath') to avoid undesired build dependencies 219 + paths = builtins.catAttrs "outPath" pkgList.bin 220 + ++ lib.optional __combine doc; 221 + pathsToLink = [ 222 + "/" 223 + "/share/texmf-var/scripts" 224 + "/share/texmf-var/tex/generic/config" 225 + "/share/texmf-var/web2c" 226 + "/share/texmf-config" 227 + "/bin" # ensure these are writeable directories 228 + ]; 229 + 230 + nativeBuildInputs = [ 231 + makeWrapper 232 + libfaketime 233 + tl."texlive.infra" # mktexlsr 234 + tl.texlive-scripts # fmtutil, updmap 235 + tl.texlive-scripts-extra # texlinks 236 + perl 237 + ]; 238 + 239 + inherit meta passthru; 240 + 241 + postBuild = 242 + # environment variables (note: only export the ones that are used in the wrappers) 243 + '' 244 + TEXMFROOT="${texmfroot}" 245 + TEXMFDIST="${texmfdist}" 246 + export PATH="$out/bin:$PATH" 247 + TEXMFSYSCONFIG="$out/share/texmf-config" 248 + TEXMFSYSVAR="$out/share/texmf-var" 249 + export TEXMFCNF="$TEXMFSYSVAR/web2c" 250 + '' + 251 + # wrap executables with required env vars as early as possible 252 + # 1. we use the wrapped binaries in the scripts below, to catch bugs 253 + # 2. we do not want to wrap links generated by texlinks 254 + '' 255 + enable -f '${bash}/lib/bash/realpath' realpath 256 + declare -i wrapCount=0 257 + for link in "$out"/bin/*; do 258 + target="$(realpath "$link")" 259 + if [[ "''${target##*/}" != "''${link##*/}" ]] ; then 260 + # detected alias with different basename, use immediate target of $link to preserve $0 261 + # relevant for mktexfmt, repstopdf, ... 262 + target="$(readlink "$link")" 263 + fi 264 + 265 + rm "$link" 266 + makeWrapper "$target" "$link" \ 267 + --inherit-argv0 \ 268 + --prefix PATH : "${ 269 + # very common dependencies that are not detected by tests.texlive.binaries 270 + lib.makeBinPath ([ coreutils gawk gnugrep gnused ] ++ lib.optional needsGhostscript ghostscript)}:$out/bin" \ 271 + --set-default TEXMFCNF "$TEXMFCNF" \ 272 + --set-default FONTCONFIG_FILE "${ 273 + # necessary for XeTeX to find the fonts distributed with texlive 274 + makeFontsConf { fontDirectories = [ "${texmfroot}/texmf-dist/fonts" ]; } 275 + }" 276 + wrapCount=$((wrapCount + 1)) 277 + done 278 + echo "wrapped $wrapCount binaries and scripts" 279 + '' + 280 + # patch texmf-dist -> $TEXMFDIST 281 + # patch texmf-local -> $out/share/texmf-local 282 + # patch texmf.cnf -> $TEXMFSYSVAR/web2c/texmf.cnf 283 + # TODO: perhaps do lua actions? 284 + # tried inspiration from install-tl, sub do_texmf_cnf 285 + '' 286 + mkdir -p "$TEXMFCNF" 287 + if [ -e "$TEXMFDIST/web2c/texmfcnf.lua" ]; then 288 + sed \ 289 + -e "s,\(TEXMFOS[ ]*=[ ]*\)[^\,]*,\1\"$TEXMFROOT\",g" \ 290 + -e "s,\(TEXMFDIST[ ]*=[ ]*\)[^\,]*,\1\"$TEXMFDIST\",g" \ 291 + -e "s,\(TEXMFSYSVAR[ ]*=[ ]*\)[^\,]*,\1\"$TEXMFSYSVAR\",g" \ 292 + -e "s,\(TEXMFSYSCONFIG[ ]*=[ ]*\)[^\,]*,\1\"$TEXMFSYSCONFIG\",g" \ 293 + -e "s,\(TEXMFLOCAL[ ]*=[ ]*\)[^\,]*,\1\"$out/share/texmf-local\",g" \ 294 + -e "s,\$SELFAUTOLOC,$out,g" \ 295 + -e "s,selfautodir:/,$out/share/,g" \ 296 + -e "s,selfautodir:,$out/share/,g" \ 297 + -e "s,selfautoparent:/,$out/share/,g" \ 298 + -e "s,selfautoparent:,$out/share/,g" \ 299 + "$TEXMFDIST/web2c/texmfcnf.lua" > "$TEXMFCNF/texmfcnf.lua" 300 + fi 301 + 302 + sed \ 303 + -e "s,\(TEXMFROOT[ ]*=[ ]*\)[^\,]*,\1$TEXMFROOT,g" \ 304 + -e "s,\(TEXMFDIST[ ]*=[ ]*\)[^\,]*,\1$TEXMFDIST,g" \ 305 + -e "s,\(TEXMFSYSVAR[ ]*=[ ]*\)[^\,]*,\1$TEXMFSYSVAR,g" \ 306 + -e "s,\(TEXMFSYSCONFIG[ ]*=[ ]*\)[^\,]*,\1$TEXMFSYSCONFIG,g" \ 307 + -e "s,\$SELFAUTOLOC,$out,g" \ 308 + -e "s,\$SELFAUTODIR,$out/share,g" \ 309 + -e "s,\$SELFAUTOPARENT,$out/share,g" \ 310 + -e "s,\$SELFAUTOGRANDPARENT,$out/share,g" \ 311 + -e "/^mpost,/d" `# CVE-2016-10243` \ 312 + "$TEXMFDIST/web2c/texmf.cnf" > "$TEXMFCNF/texmf.cnf" 313 + '' + 314 + # now filter hyphenation patterns and formats 315 + (let 316 + hyphens = lib.filter (p: p.hasHyphens or false && p.tlOutputName or p.outputName == "tex") pkgList.nonbin; 317 + hyphenPNames = map (p: p.pname) hyphens; 318 + formats = lib.filter (p: p ? formats && p.tlOutputName or p.outputName == "tex") pkgList.nonbin; 319 + formatPNames = map (p: p.pname) formats; 320 + # sed expression that prints the lines in /start/,/end/ except for /end/ 321 + section = start: end: "/${start}/,/${end}/{ /${start}/p; /${end}/!p; };\n"; 322 + script = 323 + writeText "hyphens.sed" ( 324 + # document how the file was generated (for language.dat) 325 + "1{ s/^(% Generated by .*)$/\\1, modified by ${if __combine then "texlive.combine" else "Nixpkgs"}/; p; }\n" 326 + # pick up the header 327 + + "2,/^% from/{ /^% from/!p; };\n" 328 + # pick up all sections matching packages that we combine 329 + + lib.concatMapStrings (pname: section "^% from ${pname}:$" "^% from|^%%% No changes may be made beyond this point.$") hyphenPNames 330 + # pick up the footer (for language.def) 331 + + "/^%%% No changes may be made beyond this point.$/,$p;\n" 332 + ); 333 + scriptLua = 334 + writeText "hyphens.lua.sed" ( 335 + "1{ s/^(-- Generated by .*)$/\\1, modified by ${if __combine then "texlive.combine" else "Nixpkgs"}/; p; }\n" 336 + + "2,/^-- END of language.us.lua/p;\n" 337 + + lib.concatMapStrings (pname: section "^-- from ${pname}:$" "^}$|^-- from") hyphenPNames 338 + + "$p;\n" 339 + ); 340 + # formats not being installed must be disabled by prepending #! (see man fmtutil) 341 + # sed expression that enables the formats in /start/,/end/ 342 + enableFormats = pname: "/^# from ${pname}:$/,/^# from/{ s/^#! //; };\n"; 343 + fmtutilSed = 344 + writeText "fmtutil.sed" ( 345 + # document how file was generated 346 + "1{ s/^(# Generated by .*)$/\\1, modified by ${if __combine then "texlive.combine" else "Nixpkgs"}/; }\n" 347 + # disable all formats, even those already disabled 348 + + "s/^([^#]|#! )/#! \\1/;\n" 349 + # enable the formats from the packages being installed 350 + + lib.concatMapStrings enableFormats formatPNames 351 + # clean up formats that have been disabled twice 352 + + "s/^#! #! /#! /;\n" 353 + ); 354 + in '' 355 + mkdir -p "$TEXMFSYSVAR/tex/generic/config" 356 + for fname in tex/generic/config/language.{dat,def}; do 357 + [[ -e "$TEXMFDIST/$fname" ]] && sed -E -n -f '${script}' "$TEXMFDIST/$fname" > "$TEXMFSYSVAR/$fname" 358 + done 359 + [[ -e "$TEXMFDIST"/tex/generic/config/language.dat.lua ]] && sed -E -n -f '${scriptLua}' \ 360 + "$TEXMFDIST"/tex/generic/config/language.dat.lua > "$TEXMFSYSVAR"/tex/generic/config/language.dat.lua 361 + [[ -e "$TEXMFDIST"/web2c/fmtutil.cnf ]] && sed -E -f '${fmtutilSed}' "$TEXMFDIST"/web2c/fmtutil.cnf > "$TEXMFCNF"/fmtutil.cnf 362 + 363 + # create $TEXMFSYSCONFIG database, make new $TEXMFSYSVAR files visible to kpathsea 364 + mktexlsr "$TEXMFSYSCONFIG" "$TEXMFSYSVAR" 365 + '') + 366 + # generate format links (reads fmtutil.cnf to know which ones) *after* the wrappers have been generated 367 + '' 368 + texlinks --quiet "$out/bin" 369 + '' + 370 + # texlive postactions (see TeXLive::TLUtils::_do_postaction_script) 371 + (lib.concatMapStrings (pkg: '' 372 + postaction='${pkg.postactionScript}' 373 + case "$postaction" in 374 + *.pl) postInterp=perl ;; 375 + *.texlua) postInterp=texlua ;; 376 + *) postInterp= ;; 377 + esac 378 + echo "postaction install script for ${pkg.pname}: ''${postInterp:+$postInterp }$postaction install $TEXMFROOT" 379 + $postInterp "$TEXMFROOT/$postaction" install "$TEXMFROOT" 380 + '') (lib.filter (pkg: pkg ? postactionScript) pkgList.tlpkg)) + 381 + # generate formats 382 + '' 383 + # many formats still ignore SOURCE_DATE_EPOCH even when FORCE_SOURCE_DATE=1 384 + # libfaketime fixes non-determinism related to timestamps ignoring FORCE_SOURCE_DATE 385 + # we cannot fix further randomness caused by luatex; for further details, see 386 + # https://salsa.debian.org/live-team/live-build/-/blob/master/examples/hooks/reproducible/2006-reproducible-texlive-binaries-fmt-files.hook.chroot#L52 387 + # note that calling faketime and fmtutil is fragile (faketime uses LD_PRELOAD, fmtutil calls /bin/sh, causing potential glibc issues on non-NixOS) 388 + # so we patch fmtutil to use faketime, rather than calling faketime fmtutil 389 + substitute "$TEXMFDIST"/scripts/texlive/fmtutil.pl fmtutil \ 390 + --replace 'my $cmdline = "$eng -ini ' 'my $cmdline = "faketime -f '"'"'\@1980-01-01 00:00:00 x0.001'"'"' $eng -ini ' 391 + FORCE_SOURCE_DATE=1 TZ= perl fmtutil --sys --all | grep '^fmtutil' # too verbose 392 + 393 + # Disable unavailable map files 394 + echo y | updmap --sys --syncwithtrees --force 2>&1 | grep '^\(updmap\| /\)' 395 + # Regenerate the map files (this is optional) 396 + updmap --sys --force 2>&1 | grep '^\(updmap\| /\)' 397 + 398 + # sort entries to improve reproducibility 399 + [[ -f "$TEXMFSYSCONFIG"/web2c/updmap.cfg ]] && sort -o "$TEXMFSYSCONFIG"/web2c/updmap.cfg "$TEXMFSYSCONFIG"/web2c/updmap.cfg 400 + 401 + mktexlsr "$TEXMFSYSCONFIG" "$TEXMFSYSVAR" # to make sure (of what?) 402 + '' + 403 + # remove *-sys scripts since /nix/store is readonly 404 + '' 405 + rm "$out"/bin/*-sys 406 + '' + 407 + # TODO: a context trigger https://www.preining.info/blog/2015/06/debian-tex-live-2015-the-new-layout/ 408 + # http://wiki.contextgarden.net/ConTeXt_Standalone#Unix-like_platforms_.28Linux.2FMacOS_X.2FFreeBSD.2FSolaris.29 409 + 410 + # MkIV uses its own lookup mechanism and we need to initialize 411 + # caches for it. 412 + # We use faketime to fix the embedded timestamps and patch the uuids 413 + # with some random but constant values. 414 + '' 415 + if [[ -e "$out/bin/mtxrun" ]]; then 416 + substitute "$TEXMFDIST"/scripts/context/lua/mtxrun.lua mtxrun.lua \ 417 + --replace 'cache_uuid=osuuid()' 'cache_uuid="e2402e51-133d-4c73-a278-006ea4ed734f"' \ 418 + --replace 'uuid=osuuid(),' 'uuid="242be807-d17e-4792-8e39-aa93326fc871",' 419 + FORCE_SOURCE_DATE=1 TZ= faketime -f '@1980-01-01 00:00:00 x0.001' luatex --luaonly mtxrun.lua --generate 420 + fi 421 + '' + 422 + # Get rid of all log files. They are not needed, but take up space 423 + # and render the build unreproducible by their embedded timestamps 424 + # and other non-deterministic diagnostics. 425 + '' 426 + find "$TEXMFSYSVAR"/web2c -name '*.log' -delete 427 + '' + 428 + # link TEXMFDIST in $out/share for backward compatibility 429 + '' 430 + ln -s "$TEXMFDIST" "$out"/share/texmf 431 + '' 432 + ; 433 + }).overrideAttrs (_: { allowSubstitutes = true; })); 434 + in out)
+160 -97
pkgs/tools/typesetting/tex/texlive/build-texlive-package.nix
··· 15 , texliveBinaries 16 }: 17 18 { pname 19 , revision 20 , version ? toString revision 21 , sha512 22 , mirrors 23 - , extraVersion ? "" 24 , fixedHashes ? { } 25 , postUnpack ? "" 26 , stripPrefix ? 1 27 , license ? [ ] 28 , hasHyphens ? false 29 , hasManpages ? false 30 , hasRunfiles ? false 31 , hasTlpkg ? false ··· 34 }@args: 35 36 let 37 - meta = { license = map (x: lib.licenses.${x}) license; }; 38 39 - commonPassthru = { 40 - inherit pname revision version; 41 - } // lib.optionalAttrs (args ? extraRevision) { 42 - inherit (args) extraRevision; 43 - }; 44 45 # build run, doc, source, tlpkg containers 46 - mkContainer = tlType: passthru: sha512: 47 let 48 - # NOTE: the fixed naming scheme must match generated-fixed-hashes.nix 49 # the basename used by upstream (without ".tar.xz" suffix) 50 urlName = pname + (lib.optionalString (tlType != "run" && tlType != "tlpkg") ".${tlType}"); 51 - # name + version for the derivation 52 - tlName = urlName + (lib.optionalString (tlType == "tlpkg") ".tlpkg") + "-${version}${extraVersion}"; 53 - fixedHash = fixedHashes.${tlType} or null; # be graceful about missing hashes 54 - 55 - urls = args.urls or (if args ? url then [ args.url ] else 56 - map (up: "${up}/archive/${urlName}.r${toString revision}.tar.xz") mirrors); 57 in 58 - runCommand "texlive-${tlName}" 59 - ({ 60 - src = fetchurl { inherit urls sha512; }; 61 - inherit meta passthru stripPrefix tlType; 62 - } // lib.optionalAttrs (fixedHash != null) { 63 - outputHash = fixedHash; 64 - outputHashAlgo = "sha256"; 65 - outputHashMode = "recursive"; 66 - }) 67 - ('' 68 - mkdir "$out" 69 - if [[ "$tlType" == "tlpkg" ]]; then 70 - tar -xf "$src" \ 71 - --strip-components=1 \ 72 - -C "$out" --anchored --exclude=tlpkg/tlpobj --keep-old-files \ 73 - tlpkg 74 - else 75 - tar -xf "$src" \ 76 - --strip-components="$stripPrefix" \ 77 - -C "$out" --anchored --exclude=tlpkg --keep-old-files 78 - fi 79 - '' + postUnpack); 80 81 - tex = [ 82 - ( 83 - let passthru = commonPassthru 84 - // lib.optionalAttrs (args ? deps) { tlDeps = args.deps; } 85 - // lib.optionalAttrs (args ? formats) { inherit (args) formats; } 86 - // lib.optionalAttrs hasHyphens { inherit hasHyphens; }; in 87 - if hasRunfiles then mkContainer "run" passthru sha512.run 88 - else (passthru // { tlType = "run"; }) 89 - ) 90 - ]; 91 92 - doc = let passthru = commonPassthru 93 - // lib.optionalAttrs hasManpages { inherit hasManpages; }; in 94 - lib.optional (sha512 ? doc) (mkContainer "doc" passthru sha512.doc); 95 96 - source = lib.optional (sha512 ? source) (mkContainer "source" commonPassthru sha512.source); 97 98 - tlpkg = let passthru = commonPassthru 99 - // lib.optionalAttrs (args ? postactionScript) { postactionScript = args.postactionScript; }; in 100 - lib.optional hasTlpkg (mkContainer "tlpkg" passthru sha512.run); 101 102 - bin = lib.optional (args ? binfiles && args.binfiles != [ ]) ( 103 - let 104 - # find interpreters for the script extensions found in tlpdb 105 - extToInput = { 106 - jar = jdk; 107 - lua = texliveBinaries.luatex; 108 - py = python3; 109 - rb = ruby; 110 - sno = snobol4; 111 - tcl = tk; 112 - texlua = texliveBinaries.luatex; 113 - tlu = texliveBinaries.luatex; 114 - }; 115 - run = lib.head tex; 116 - in 117 - runCommand "texlive-${pname}.bin-${version}" 118 - { 119 - passthru = commonPassthru // { tlType = "bin"; }; 120 - inherit meta; 121 - # shebang interpreters and compiled binaries 122 - buildInputs = let outName = builtins.replaceStrings [ "-" ] [ "_" ] pname; in 123 - [ texliveBinaries.core.${outName} or null 124 - texliveBinaries.${pname} or null 125 - texliveBinaries.core-big.${outName} or null ] 126 - ++ (args.extraBuildInputs or [ ]) ++ [ bash perl ] 127 - ++ (lib.attrVals (args.scriptExts or [ ]) extToInput); 128 - nativeBuildInputs = extraNativeBuildInputs; 129 - # absolute scripts folder 130 - scriptsFolder = lib.optionalString (run ? outPath) (run.outPath + "/scripts/" + args.scriptsFolder or pname); 131 - # binaries info 132 - inherit (args) binfiles; 133 - binlinks = builtins.attrNames (args.binlinks or { }); 134 - bintargets = builtins.attrValues (args.binlinks or { }); 135 - # build scripts 136 - patchScripts = ./patch-scripts.sed; 137 - makeBinContainers = ./make-bin-containers.sh; 138 - } 139 - '' 140 - . "$makeBinContainers" 141 - ${args.postFixup or ""} 142 - '' 143 - ); 144 in 145 - { pkgs = tex ++ doc ++ source ++ tlpkg ++ bin; }
··· 15 , texliveBinaries 16 }: 17 18 + /* Convert an attribute set extracted from tlpdb.nix (with the deps attribute 19 + already processed) to a fake multi-output derivation with possible outputs 20 + [ "tex" "texdoc" "texsource" "tlpkg" "out" "man" "info" ] 21 + */ 22 + 23 + # TODO stabilise a generic interface decoupled from the finer details of the 24 + # translation from texlive.tlpdb to tlpdb.nix 25 { pname 26 , revision 27 , version ? toString revision 28 + , extraRevision ? "" 29 + , extraVersion ? "" 30 , sha512 31 , mirrors 32 , fixedHashes ? { } 33 , postUnpack ? "" 34 + , postFixup ? "" 35 , stripPrefix ? 1 36 , license ? [ ] 37 , hasHyphens ? false 38 + , hasInfo ? false 39 , hasManpages ? false 40 , hasRunfiles ? false 41 , hasTlpkg ? false ··· 44 }@args: 45 46 let 47 + # common metadata 48 + name = "${pname}-${version}${extraVersion}"; 49 + meta = { 50 + license = map (x: lib.licenses.${x}) license; 51 + # TeX Live packages should not be installed directly into the user profile 52 + outputsToInstall = [ ]; 53 + }; 54 + 55 + hasBinfiles = args ? binfiles && args.binfiles != [ ]; 56 + hasDocfiles = sha512 ? doc; 57 + hasSource = sha512 ? source; 58 + 59 + # emulate drv.all, drv.outputs lists 60 + all = lib.optional hasBinfiles bin ++ 61 + lib.optional hasRunfiles tex ++ 62 + lib.optional hasDocfiles texdoc ++ 63 + lib.optional hasSource texsource ++ 64 + lib.optional hasTlpkg tlpkg ++ 65 + lib.optional hasManpages man ++ 66 + lib.optional hasInfo info; 67 + outputs = lib.catAttrs "tlOutputName" all; 68 69 + mainDrv = if hasBinfiles then bin 70 + else if hasRunfiles then tex 71 + else if hasTlpkg then tlpkg 72 + else if hasDocfiles then texdoc 73 + else if hasSource then texsource 74 + else tex; # fall back to attrset tex if there is no derivation 75 + 76 + # emulate multi-output derivation plus additional metadata 77 + # (out is handled in mkContainer) 78 + passthru = { 79 + inherit all outputs pname; 80 + revision = toString revision + extraRevision; 81 + version = version + extraVersion; 82 + outputSpecified = true; 83 + inherit tex; 84 + } // lib.optionalAttrs (args ? deps) { tlDeps = args.deps; } 85 + // lib.optionalAttrs (args ? formats) { inherit (args) formats; } 86 + // lib.optionalAttrs hasHyphens { inherit hasHyphens; } 87 + // lib.optionalAttrs (args ? postactionScript) { inherit (args) postactionScript; } 88 + // lib.optionalAttrs hasDocfiles { texdoc = texdoc; } 89 + // lib.optionalAttrs hasSource { texsource = texsource; } 90 + // lib.optionalAttrs hasTlpkg { tlpkg = tlpkg; } 91 + // lib.optionalAttrs hasManpages { man = man; } 92 + // lib.optionalAttrs hasInfo { info = info; }; 93 94 # build run, doc, source, tlpkg containers 95 + mkContainer = tlType: tlOutputName: sha512: 96 let 97 + fixedHash = fixedHashes.${tlType} or null; # be graceful about missing hashes 98 # the basename used by upstream (without ".tar.xz" suffix) 99 + # tlpkg is not a true container but a subfolder of the run container 100 urlName = pname + (lib.optionalString (tlType != "run" && tlType != "tlpkg") ".${tlType}"); 101 + urls = map (up: "${up}/archive/${urlName}.r${toString revision}.tar.xz") mirrors; 102 + # TODO switch to simpler "${name}-${tlOutputName}" (requires new fixed hashes) 103 + container = runCommand "texlive-${pname}${lib.optionalString (tlType != "run") ".${tlType}"}-${version}${extraVersion}" 104 + ({ 105 + src = fetchurl { inherit urls sha512; }; 106 + # save outputName as fixed output derivations cannot change nor override outputName 107 + passthru = passthru // { inherit tlOutputName; }; 108 + # TODO remove tlType from derivation (requires a rebuild) 109 + inherit meta stripPrefix tlType; 110 + } // lib.optionalAttrs (fixedHash != null) { 111 + outputHash = fixedHash; 112 + outputHashAlgo = "sha256"; 113 + outputHashMode = "recursive"; 114 + }) 115 + ('' 116 + mkdir "$out" 117 + if [[ "$tlType" == "tlpkg" ]]; then 118 + tar -xf "$src" \ 119 + --strip-components=1 \ 120 + -C "$out" --anchored --exclude=tlpkg/tlpobj --keep-old-files \ 121 + tlpkg 122 + else 123 + tar -xf "$src" \ 124 + --strip-components="$stripPrefix" \ 125 + -C "$out" --anchored --exclude=tlpkg --keep-old-files 126 + fi 127 + '' + postUnpack); 128 in 129 + # remove the standard drv.out, optionally replace it with the bin container 130 + builtins.removeAttrs container [ "out" ] // lib.optionalAttrs hasBinfiles { out = bin; }; 131 + 132 + tex = 133 + if hasRunfiles then mkContainer "run" "tex" sha512.run 134 + else passthru 135 + // { inherit meta; tlOutputName = "tex"; } 136 + // lib.optionalAttrs hasBinfiles { out = bin; }; 137 + 138 + texdoc = mkContainer "doc" "texdoc" sha512.doc; 139 + 140 + texsource = mkContainer "source" "texsource" sha512.source; 141 142 + tlpkg = mkContainer "tlpkg" "tlpkg" sha512.run; 143 144 + # build bin container 145 + extToInput = { 146 + # find interpreters for the script extensions found in tlpdb 147 + jar = jdk; 148 + lua = texliveBinaries.luatex; 149 + py = python3; 150 + rb = ruby; 151 + sno = snobol4; 152 + tcl = tk; 153 + texlua = texliveBinaries.luatex; 154 + tlu = texliveBinaries.luatex; 155 + }; 156 157 + # TODO switch to simpler "${name}" (requires a rebuild) 158 + bin = runCommand "texlive-${pname}.bin-${version}" 159 + { 160 + inherit meta; 161 + passthru = passthru // { tlOutputName = "out"; }; 162 + # shebang interpreters 163 + buildInputs =let outName = builtins.replaceStrings [ "-" ] [ "_" ] pname; in 164 + [ texliveBinaries.core.${outName} or null 165 + texliveBinaries.${pname} or null 166 + texliveBinaries.core-big.${outName} or null ] 167 + ++ (args.extraBuildInputs or [ ]) ++ [ bash perl ] 168 + ++ (lib.attrVals (args.scriptExts or [ ]) extToInput); 169 + nativeBuildInputs = extraNativeBuildInputs; 170 + # absolute scripts folder 171 + scriptsFolder = lib.optionalString (tex ? outPath) (tex.outPath + "/scripts/" + args.scriptsFolder or pname); 172 + # binaries info 173 + inherit (args) binfiles; 174 + binlinks = builtins.attrNames (args.binlinks or { }); 175 + bintargets = builtins.attrValues (args.binlinks or { }); 176 + # build scripts 177 + patchScripts = ./patch-scripts.sed; 178 + makeBinContainers = ./make-bin-containers.sh; 179 + } 180 + '' 181 + . "$makeBinContainers" 182 + ${args.postFixup or ""} 183 + ''; 184 185 + # build man, info containers 186 + # TODO switch to simpler "${name}-man" (requires a rebuild) 187 + man = builtins.removeAttrs (runCommand "texlive-${pname}.man-${version}${extraVersion}" 188 + { 189 + inherit meta texdoc; 190 + passthru = passthru // { tlOutputName = "man"; }; 191 + } 192 + '' 193 + mkdir -p "$out"/share 194 + ln -s {"$texdoc"/doc,"$out"/share}/man 195 + '') [ "out" ] // lib.optionalAttrs hasBinfiles { out = bin; }; 196 197 + # TODO switch to simpler "${name}-info" (requires a rebuild) 198 + info = builtins.removeAttrs (runCommand "texlive-${pname}.info-${version}${extraVersion}" 199 + { 200 + inherit meta texdoc; 201 + passthru = passthru // { tlOutputName = "info"; }; 202 + } 203 + '' 204 + mkdir -p "$out"/share 205 + ln -s {"$texdoc"/doc,"$out"/share}/info 206 + '') [ "out" ] // lib.optionalAttrs hasBinfiles { out = bin; }; 207 in 208 + builtins.removeAttrs mainDrv [ "outputSpecified" ]
+42
pkgs/tools/typesetting/tex/texlive/combine-wrapper.nix
···
··· 1 + # legacy texlive.combine wrapper 2 + { lib, toTLPkgList, toTLPkgSets, buildTeXEnv }: 3 + args@{ 4 + pkgFilter ? (pkg: pkg.tlType == "run" || pkg.tlType == "bin" || pkg.pname == "core" 5 + || pkg.hasManpages or false) 6 + , extraName ? "combined" 7 + , extraVersion ? "" 8 + , ... 9 + }: 10 + let 11 + pkgSet = removeAttrs args [ "pkgFilter" "extraName" "extraVersion" ]; 12 + 13 + # combine a set of TL packages into a single TL meta-package 14 + combinePkgs = pkgList: lib.catAttrs "pkg" ( 15 + let 16 + # a TeX package used to be an attribute set { pkgs = [ ... ]; ... } where pkgs is a list of derivations 17 + # the derivations make up the TeX package and optionally (for backward compatibility) its dependencies 18 + tlPkgToSets = drv: map ({ tlType, version ? "", outputName ? "", ... }@pkg: { 19 + # outputName required to distinguish among bin.core-big outputs 20 + key = "${pkg.pname or pkg.name}.${tlType}-${version}-${outputName}"; 21 + inherit pkg; 22 + }) (drv.pkgs or (toTLPkgList drv)); 23 + pkgListToSets = lib.concatMap tlPkgToSets; in 24 + builtins.genericClosure { 25 + startSet = pkgListToSets pkgList; 26 + operator = { pkg, ... }: pkgListToSets (pkg.tlDeps or []); 27 + }); 28 + combined = combinePkgs (lib.attrValues pkgSet); 29 + 30 + # convert to specified outputs 31 + tlTypeToOut = { run = "tex"; doc = "texdoc"; source = "texsource"; bin = "out"; tlpkg = "tlpkg"; }; 32 + toSpecified = { tlType, ... }@drv: drv // { outputSpecified = true; tlOutputName = tlTypeToOut.${tlType}; }; 33 + all = lib.filter pkgFilter combined ++ lib.filter (pkg: pkg.tlType == "tlpkg") combined; 34 + converted = builtins.map toSpecified all; 35 + in 36 + buildTeXEnv { 37 + __extraName = extraName; 38 + __extraVersion = extraVersion; 39 + requiredTeXPackages = _: converted; 40 + __combine = true; 41 + __fromCombineWrapper = true; 42 + }
-315
pkgs/tools/typesetting/tex/texlive/combine.nix
··· 1 - { lib, buildEnv, runCommand, writeText, makeWrapper, libfaketime, makeFontsConf 2 - , perl, bash, coreutils, gnused, gnugrep, gawk, ghostscript 3 - , bin, tl }: 4 - # combine = 5 - args@{ 6 - pkgFilter ? (pkg: pkg.tlType == "run" || pkg.tlType == "bin" || pkg.pname == "core" 7 - || pkg.hasManpages or false) 8 - , extraName ? "combined" 9 - , extraVersion ? "" 10 - , ... 11 - }: 12 - let 13 - # combine a set of TL packages into a single TL meta-package 14 - combinePkgs = pkgList: lib.catAttrs "pkg" ( 15 - let 16 - # a TeX package is an attribute set { pkgs = [ ... ]; ... } where pkgs is a list of derivations 17 - # the derivations make up the TeX package and optionally (for backward compatibility) its dependencies 18 - tlPkgToSets = { pkgs, ... }: map ({ tlType, version ? "", outputName ? "", ... }@pkg: { 19 - # outputName required to distinguish among bin.core-big outputs 20 - key = "${pkg.pname or pkg.name}.${tlType}-${version}-${outputName}"; 21 - inherit pkg; 22 - }) pkgs; 23 - pkgListToSets = lib.concatMap tlPkgToSets; in 24 - builtins.genericClosure { 25 - startSet = pkgListToSets pkgList; 26 - operator = { pkg, ... }: pkgListToSets (pkg.tlDeps or []); 27 - }); 28 - 29 - pkgSet = removeAttrs args [ "pkgFilter" "extraName" "extraVersion" ]; 30 - pkgList = rec { 31 - combined = combinePkgs (lib.attrValues pkgSet); 32 - all = lib.filter pkgFilter combined; 33 - splitBin = builtins.partition (p: p.tlType == "bin") all; 34 - bin = splitBin.right; 35 - nonbin = splitBin.wrong; 36 - tlpkg = lib.filter (pkg: pkg.tlType == "tlpkg") combined; 37 - }; 38 - # list generated by inspecting `grep -IR '\([^a-zA-Z]\|^\)gs\( \|$\|"\)' "$TEXMFDIST"/scripts` 39 - # and `grep -IR rungs "$TEXMFDIST"` 40 - # and ignoring luatex, perl, and shell scripts (those must be patched using postFixup) 41 - needsGhostscript = lib.any (p: lib.elem p.pname [ "context" "dvipdfmx" "latex-papersize" "lyluatex" ]) pkgList.bin; 42 - 43 - name = "texlive-${extraName}-${bin.texliveYear}${extraVersion}"; 44 - 45 - texmfdist = (buildEnv { 46 - name = "${name}-texmfdist"; 47 - 48 - # remove fake derivations (without 'outPath') to avoid undesired build dependencies 49 - paths = lib.catAttrs "outPath" pkgList.nonbin; 50 - 51 - # mktexlsr 52 - nativeBuildInputs = [ (lib.last tl."texlive.infra".pkgs) ]; 53 - 54 - postBuild = # generate ls-R database 55 - '' 56 - mktexlsr "$out" 57 - ''; 58 - }).overrideAttrs (_: { allowSubstitutes = true; }); 59 - 60 - tlpkg = (buildEnv { 61 - name = "${name}-tlpkg"; 62 - 63 - # remove fake derivations (without 'outPath') to avoid undesired build dependencies 64 - paths = lib.catAttrs "outPath" pkgList.tlpkg; 65 - }).overrideAttrs (_: { allowSubstitutes = true; }); 66 - 67 - # the 'non-relocated' packages must live in $TEXMFROOT/texmf-dist 68 - # and sometimes look into $TEXMFROOT/tlpkg (notably fmtutil, updmap look for perl modules in both) 69 - texmfroot = runCommand "${name}-texmfroot" { 70 - inherit texmfdist tlpkg; 71 - } '' 72 - mkdir -p "$out" 73 - ln -s "$texmfdist" "$out"/texmf-dist 74 - ln -s "$tlpkg" "$out"/tlpkg 75 - ''; 76 - 77 - # expose info and man pages in usual /share/{info,man} location 78 - doc = buildEnv { 79 - name = "${name}-doc"; 80 - 81 - paths = [ (texmfdist.outPath + "/doc") ]; 82 - extraPrefix = "/share"; 83 - 84 - pathsToLink = [ 85 - "/info" 86 - "/man" 87 - ]; 88 - }; 89 - 90 - in (buildEnv { 91 - 92 - inherit name; 93 - 94 - ignoreCollisions = false; 95 - 96 - # remove fake derivations (without 'outPath') to avoid undesired build dependencies 97 - paths = lib.catAttrs "outPath" pkgList.bin ++ [ doc ]; 98 - pathsToLink = [ 99 - "/" 100 - "/share/texmf-var/scripts" 101 - "/share/texmf-var/tex/generic/config" 102 - "/share/texmf-var/web2c" 103 - "/share/texmf-config" 104 - "/bin" # ensure these are writeable directories 105 - ]; 106 - 107 - nativeBuildInputs = [ 108 - makeWrapper 109 - libfaketime 110 - (lib.last tl."texlive.infra".pkgs) # mktexlsr 111 - (lib.last tl.texlive-scripts.pkgs) # fmtutil, updmap 112 - (lib.last tl.texlive-scripts-extra.pkgs) # texlinks 113 - perl 114 - ]; 115 - 116 - passthru = { 117 - # This is set primarily to help find-tarballs.nix to do its job 118 - packages = pkgList.all; 119 - # useful for inclusion in the `fonts.packages` nixos option or for use in devshells 120 - fonts = "${texmfroot}/texmf-dist/fonts"; 121 - }; 122 - 123 - postBuild = 124 - # environment variables (note: only export the ones that are used in the wrappers) 125 - '' 126 - TEXMFROOT="${texmfroot}" 127 - TEXMFDIST="${texmfdist}" 128 - export PATH="$out/bin:$PATH" 129 - TEXMFSYSCONFIG="$out/share/texmf-config" 130 - TEXMFSYSVAR="$out/share/texmf-var" 131 - export TEXMFCNF="$TEXMFSYSVAR/web2c" 132 - '' + 133 - # wrap executables with required env vars as early as possible 134 - # 1. we want texlive.combine to use the wrapped binaries, to catch bugs 135 - # 2. we do not want to wrap links generated by texlinks 136 - '' 137 - enable -f '${bash}/lib/bash/realpath' realpath 138 - declare -i wrapCount=0 139 - for link in "$out"/bin/*; do 140 - target="$(realpath "$link")" 141 - if [[ "''${target##*/}" != "''${link##*/}" ]] ; then 142 - # detected alias with different basename, use immediate target of $link to preserve $0 143 - # relevant for mktexfmt, repstopdf, ... 144 - target="$(readlink "$link")" 145 - fi 146 - 147 - rm "$link" 148 - makeWrapper "$target" "$link" \ 149 - --inherit-argv0 \ 150 - --prefix PATH : "${ 151 - # very common dependencies that are not detected by tests.texlive.binaries 152 - lib.makeBinPath ([ coreutils gawk gnugrep gnused ] ++ lib.optional needsGhostscript ghostscript)}:$out/bin" \ 153 - --set-default TEXMFCNF "$TEXMFCNF" \ 154 - --set-default FONTCONFIG_FILE "${ 155 - # necessary for XeTeX to find the fonts distributed with texlive 156 - makeFontsConf { fontDirectories = [ "${texmfroot}/texmf-dist/fonts" ]; } 157 - }" 158 - wrapCount=$((wrapCount + 1)) 159 - done 160 - echo "wrapped $wrapCount binaries and scripts" 161 - '' + 162 - # patch texmf-dist -> $TEXMFDIST 163 - # patch texmf-local -> $out/share/texmf-local 164 - # patch texmf.cnf -> $TEXMFSYSVAR/web2c/texmf.cnf 165 - # TODO: perhaps do lua actions? 166 - # tried inspiration from install-tl, sub do_texmf_cnf 167 - '' 168 - mkdir -p "$TEXMFCNF" 169 - if [ -e "$TEXMFDIST/web2c/texmfcnf.lua" ]; then 170 - sed \ 171 - -e "s,\(TEXMFOS[ ]*=[ ]*\)[^\,]*,\1\"$TEXMFROOT\",g" \ 172 - -e "s,\(TEXMFDIST[ ]*=[ ]*\)[^\,]*,\1\"$TEXMFDIST\",g" \ 173 - -e "s,\(TEXMFSYSVAR[ ]*=[ ]*\)[^\,]*,\1\"$TEXMFSYSVAR\",g" \ 174 - -e "s,\(TEXMFSYSCONFIG[ ]*=[ ]*\)[^\,]*,\1\"$TEXMFSYSCONFIG\",g" \ 175 - -e "s,\(TEXMFLOCAL[ ]*=[ ]*\)[^\,]*,\1\"$out/share/texmf-local\",g" \ 176 - -e "s,\$SELFAUTOLOC,$out,g" \ 177 - -e "s,selfautodir:/,$out/share/,g" \ 178 - -e "s,selfautodir:,$out/share/,g" \ 179 - -e "s,selfautoparent:/,$out/share/,g" \ 180 - -e "s,selfautoparent:,$out/share/,g" \ 181 - "$TEXMFDIST/web2c/texmfcnf.lua" > "$TEXMFCNF/texmfcnf.lua" 182 - fi 183 - 184 - sed \ 185 - -e "s,\(TEXMFROOT[ ]*=[ ]*\)[^\,]*,\1$TEXMFROOT,g" \ 186 - -e "s,\(TEXMFDIST[ ]*=[ ]*\)[^\,]*,\1$TEXMFDIST,g" \ 187 - -e "s,\(TEXMFSYSVAR[ ]*=[ ]*\)[^\,]*,\1$TEXMFSYSVAR,g" \ 188 - -e "s,\(TEXMFSYSCONFIG[ ]*=[ ]*\)[^\,]*,\1$TEXMFSYSCONFIG,g" \ 189 - -e "s,\$SELFAUTOLOC,$out,g" \ 190 - -e "s,\$SELFAUTODIR,$out/share,g" \ 191 - -e "s,\$SELFAUTOPARENT,$out/share,g" \ 192 - -e "s,\$SELFAUTOGRANDPARENT,$out/share,g" \ 193 - -e "/^mpost,/d" `# CVE-2016-10243` \ 194 - "$TEXMFDIST/web2c/texmf.cnf" > "$TEXMFCNF/texmf.cnf" 195 - '' + 196 - # now filter hyphenation patterns and formats 197 - (let 198 - hyphens = lib.filter (p: p.hasHyphens or false && p.tlType == "run") pkgList.splitBin.wrong; 199 - hyphenPNames = map (p: p.pname) hyphens; 200 - formats = lib.filter (p: p ? formats && p.tlType == "run") pkgList.splitBin.wrong; 201 - formatPNames = map (p: p.pname) formats; 202 - # sed expression that prints the lines in /start/,/end/ except for /end/ 203 - section = start: end: "/${start}/,/${end}/{ /${start}/p; /${end}/!p; };\n"; 204 - script = 205 - writeText "hyphens.sed" ( 206 - # document how the file was generated (for language.dat) 207 - "1{ s/^(% Generated by .*)$/\\1, modified by texlive.combine/; p; }\n" 208 - # pick up the header 209 - + "2,/^% from/{ /^% from/!p; };\n" 210 - # pick up all sections matching packages that we combine 211 - + lib.concatMapStrings (pname: section "^% from ${pname}:$" "^% from|^%%% No changes may be made beyond this point.$") hyphenPNames 212 - # pick up the footer (for language.def) 213 - + "/^%%% No changes may be made beyond this point.$/,$p;\n" 214 - ); 215 - scriptLua = 216 - writeText "hyphens.lua.sed" ( 217 - "1{ s/^(-- Generated by .*)$/\\1, modified by texlive.combine/; p; }\n" 218 - + "2,/^-- END of language.us.lua/p;\n" 219 - + lib.concatMapStrings (pname: section "^-- from ${pname}:$" "^}$|^-- from") hyphenPNames 220 - + "$p;\n" 221 - ); 222 - # formats not being installed must be disabled by prepending #! (see man fmtutil) 223 - # sed expression that enables the formats in /start/,/end/ 224 - enableFormats = pname: "/^# from ${pname}:$/,/^# from/{ s/^#! //; };\n"; 225 - fmtutilSed = 226 - writeText "fmtutil.sed" ( 227 - # document how file was generated 228 - "1{ s/^(# Generated by .*)$/\\1, modified by texlive.combine/; }\n" 229 - # disable all formats, even those already disabled 230 - + "s/^([^#]|#! )/#! \\1/;\n" 231 - # enable the formats from the packages being installed 232 - + lib.concatMapStrings enableFormats formatPNames 233 - # clean up formats that have been disabled twice 234 - + "s/^#! #! /#! /;\n" 235 - ); 236 - in '' 237 - mkdir -p "$TEXMFSYSVAR/tex/generic/config" 238 - for fname in tex/generic/config/language.{dat,def}; do 239 - [[ -e "$TEXMFDIST/$fname" ]] && sed -E -n -f '${script}' "$TEXMFDIST/$fname" > "$TEXMFSYSVAR/$fname" 240 - done 241 - [[ -e "$TEXMFDIST"/tex/generic/config/language.dat.lua ]] && sed -E -n -f '${scriptLua}' \ 242 - "$TEXMFDIST"/tex/generic/config/language.dat.lua > "$TEXMFSYSVAR"/tex/generic/config/language.dat.lua 243 - [[ -e "$TEXMFDIST"/web2c/fmtutil.cnf ]] && sed -E -f '${fmtutilSed}' "$TEXMFDIST"/web2c/fmtutil.cnf > "$TEXMFCNF"/fmtutil.cnf 244 - 245 - # create $TEXMFSYSCONFIG database, make new $TEXMFSYSVAR files visible to kpathsea 246 - mktexlsr "$TEXMFSYSCONFIG" "$TEXMFSYSVAR" 247 - '') + 248 - # generate format links (reads fmtutil.cnf to know which ones) *after* the wrappers have been generated 249 - '' 250 - texlinks --quiet "$out/bin" 251 - '' + 252 - # texlive postactions (see TeXLive::TLUtils::_do_postaction_script) 253 - (lib.concatMapStrings (pkg: '' 254 - postaction='${pkg.postactionScript}' 255 - case "$postaction" in 256 - *.pl) postInterp=perl ;; 257 - *.texlua) postInterp=texlua ;; 258 - *) postInterp= ;; 259 - esac 260 - echo "postaction install script for ${pkg.pname}: ''${postInterp:+$postInterp }$postaction install $TEXMFROOT" 261 - $postInterp "$TEXMFROOT/$postaction" install "$TEXMFROOT" 262 - '') (lib.filter (pkg: pkg ? postactionScript) pkgList.tlpkg)) + 263 - # generate formats 264 - '' 265 - # many formats still ignore SOURCE_DATE_EPOCH even when FORCE_SOURCE_DATE=1 266 - # libfaketime fixes non-determinism related to timestamps ignoring FORCE_SOURCE_DATE 267 - # we cannot fix further randomness caused by luatex; for further details, see 268 - # https://salsa.debian.org/live-team/live-build/-/blob/master/examples/hooks/reproducible/2006-reproducible-texlive-binaries-fmt-files.hook.chroot#L52 269 - # note that calling faketime and fmtutil is fragile (faketime uses LD_PRELOAD, fmtutil calls /bin/sh, causing potential glibc issues on non-NixOS) 270 - # so we patch fmtutil to use faketime, rather than calling faketime fmtutil 271 - substitute "$TEXMFDIST"/scripts/texlive/fmtutil.pl fmtutil \ 272 - --replace 'my $cmdline = "$eng -ini ' 'my $cmdline = "faketime -f '"'"'\@1980-01-01 00:00:00 x0.001'"'"' $eng -ini ' 273 - FORCE_SOURCE_DATE=1 TZ= perl fmtutil --sys --all | grep '^fmtutil' # too verbose 274 - 275 - # Disable unavailable map files 276 - echo y | updmap --sys --syncwithtrees --force 2>&1 | grep '^\(updmap\| /\)' 277 - # Regenerate the map files (this is optional) 278 - updmap --sys --force 2>&1 | grep '^\(updmap\| /\)' 279 - 280 - # sort entries to improve reproducibility 281 - [[ -f "$TEXMFSYSCONFIG"/web2c/updmap.cfg ]] && sort -o "$TEXMFSYSCONFIG"/web2c/updmap.cfg "$TEXMFSYSCONFIG"/web2c/updmap.cfg 282 - 283 - mktexlsr "$TEXMFSYSCONFIG" "$TEXMFSYSVAR" # to make sure (of what?) 284 - '' + 285 - # remove *-sys scripts since /nix/store is readonly 286 - '' 287 - rm "$out"/bin/*-sys 288 - '' + 289 - # TODO: a context trigger https://www.preining.info/blog/2015/06/debian-tex-live-2015-the-new-layout/ 290 - # http://wiki.contextgarden.net/ConTeXt_Standalone#Unix-like_platforms_.28Linux.2FMacOS_X.2FFreeBSD.2FSolaris.29 291 - 292 - # MkIV uses its own lookup mechanism and we need to initialize 293 - # caches for it. 294 - # We use faketime to fix the embedded timestamps and patch the uuids 295 - # with some random but constant values. 296 - '' 297 - if [[ -e "$out/bin/mtxrun" ]]; then 298 - substitute "$TEXMFDIST"/scripts/context/lua/mtxrun.lua mtxrun.lua \ 299 - --replace 'cache_uuid=osuuid()' 'cache_uuid="e2402e51-133d-4c73-a278-006ea4ed734f"' \ 300 - --replace 'uuid=osuuid(),' 'uuid="242be807-d17e-4792-8e39-aa93326fc871",' 301 - FORCE_SOURCE_DATE=1 TZ= faketime -f '@1980-01-01 00:00:00 x0.001' luatex --luaonly mtxrun.lua --generate 302 - fi 303 - '' + 304 - # Get rid of all log files. They are not needed, but take up space 305 - # and render the build unreproducible by their embedded timestamps 306 - # and other non-deterministic diagnostics. 307 - '' 308 - find "$TEXMFSYSVAR"/web2c -name '*.log' -delete 309 - '' + 310 - # link TEXMFDIST in $out/share for backward compatibility 311 - '' 312 - ln -s "$TEXMFDIST" "$out"/share/texmf 313 - '' 314 - ; 315 - }).overrideAttrs (_: { allowSubstitutes = true; })
···
+103 -56
pkgs/tools/typesetting/tex/texlive/default.nix
··· 2 - source: ../../../../../doc/languages-frameworks/texlive.xml 3 - current html: https://nixos.org/nixpkgs/manual/#sec-language-texlive 4 */ 5 - { stdenv, lib, fetchurl, runCommand, writeText, buildEnv 6 , callPackage, ghostscript_headless, harfbuzz 7 , makeWrapper, installShellFiles 8 , python3, ruby, perl, tk, jdk, bash, snobol4 ··· 20 }; 21 inherit useFixedHashes; 22 tlpdb = overriddenTlpdb; 23 - }; 24 - 25 - # function for creating a working environment from a set of TL packages 26 - combine = import ./combine.nix { 27 - inherit bin buildEnv lib makeWrapper writeText runCommand 28 - perl libfaketime makeFontsConf bash tl coreutils gawk gnugrep gnused; 29 - ghostscript = ghostscript_headless; 30 }; 31 32 tlpdb = import ./tlpdb.nix; ··· 101 // lib.optionalAttrs (args ? deps) { deps = map (n: tl.${n}) (args.deps or [ ]); }) 102 ) overriddenTlpdb; 103 104 assertions = with lib; 105 assertMsg (tlpdbVersion.year == version.texliveYear) "TeX Live year in texlive does not match tlpdb.nix, refusing to evaluate" && 106 assertMsg (tlpdbVersion.frozen == version.final) "TeX Live final status in texlive does not match tlpdb.nix, refusing to evaluate"; 107 108 in 109 - tl // { 110 111 tlpdb = { 112 # nested in an attribute set to prevent them from appearing in search ··· 116 117 bin = assert assertions; bin // { 118 # for backward compatibility 119 - latexindent = lib.findFirst (p: p.tlType == "bin") tl.latexindent.pkgs; 120 }; 121 122 combine = assert assertions; combine; 123 124 - # Pre-defined combined packages for TeX Live schemes, 125 - # to make nix-env usage more comfortable and build selected on Hydra. 126 - combined = with lib; 127 - let 128 - # these license lists should be the sorted union of the licenses of the packages the schemes contain. 129 - # The correctness of this collation is tested by tests.texlive.licenses 130 - licenses = with lib.licenses; { 131 - scheme-basic = [ free gfl gpl1Only gpl2 gpl2Plus knuth lgpl21 lppl1 lppl13c mit ofl publicDomain ]; 132 - scheme-context = [ bsd2 bsd3 cc-by-sa-40 free gfl gfsl gpl1Only gpl2 gpl2Plus gpl3 gpl3Plus knuth lgpl2 lgpl21 133 - lppl1 lppl13c mit ofl publicDomain x11 ]; 134 - scheme-full = [ artistic1-cl8 artistic2 asl20 bsd2 bsd3 bsdOriginal cc-by-10 cc-by-40 cc-by-sa-10 cc-by-sa-20 135 - cc-by-sa-30 cc-by-sa-40 cc0 fdl13Only free gfl gfsl gpl1Only gpl2 gpl2Plus gpl3 gpl3Plus isc knuth 136 - lgpl2 lgpl21 lgpl3 lppl1 lppl12 lppl13a lppl13c mit ofl publicDomain x11 ]; 137 - scheme-gust = [ artistic1-cl8 asl20 bsd2 bsd3 cc-by-40 cc-by-sa-40 cc0 fdl13Only free gfl gfsl gpl1Only gpl2 138 - gpl2Plus gpl3 gpl3Plus knuth lgpl2 lgpl21 lppl1 lppl12 lppl13a lppl13c mit ofl publicDomain x11 ]; 139 - scheme-infraonly = [ gpl2 gpl2Plus lgpl21 ]; 140 - scheme-medium = [ artistic1-cl8 asl20 bsd2 bsd3 cc-by-40 cc-by-sa-20 cc-by-sa-30 cc-by-sa-40 cc0 fdl13Only 141 - free gfl gpl1Only gpl2 gpl2Plus gpl3 gpl3Plus isc knuth lgpl2 lgpl21 lgpl3 lppl1 lppl12 lppl13a lppl13c mit ofl 142 - publicDomain x11 ]; 143 - scheme-minimal = [ free gpl1Only gpl2 gpl2Plus knuth lgpl21 lppl1 lppl13c mit ofl publicDomain ]; 144 - scheme-small = [ asl20 cc-by-40 cc-by-sa-40 cc0 fdl13Only free gfl gpl1Only gpl2 gpl2Plus gpl3 gpl3Plus knuth 145 - lgpl2 lgpl21 lppl1 lppl12 lppl13a lppl13c mit ofl publicDomain x11 ]; 146 - scheme-tetex = [ artistic1-cl8 asl20 bsd2 bsd3 cc-by-40 cc-by-sa-10 cc-by-sa-20 cc-by-sa-30 cc-by-sa-40 cc0 147 - fdl13Only free gfl gpl1Only gpl2 gpl2Plus gpl3 gpl3Plus isc knuth lgpl2 lgpl21 lgpl3 lppl1 lppl12 lppl13a 148 - lppl13c mit ofl publicDomain x11]; 149 - }; 150 - in recurseIntoAttrs ( 151 - mapAttrs 152 - (pname: attrs: 153 - addMetaAttrs rec { 154 - description = "TeX Live environment for ${pname}"; 155 - platforms = lib.platforms.all; 156 - maintainers = with lib.maintainers; [ veprbl ]; 157 - license = licenses.${pname}; 158 - } 159 - (combine { 160 - ${pname} = attrs; 161 - extraName = "combined" + lib.removePrefix "scheme" pname; 162 - extraVersion = with version; if final then "-final" else ".${year}${month}${day}"; 163 - }) 164 - ) 165 - { inherit (tl) 166 - scheme-basic scheme-context scheme-full scheme-gust scheme-infraonly 167 - scheme-medium scheme-minimal scheme-small scheme-tetex; 168 - } 169 - ); 170 }
··· 2 - source: ../../../../../doc/languages-frameworks/texlive.xml 3 - current html: https://nixos.org/nixpkgs/manual/#sec-language-texlive 4 */ 5 + { stdenv, lib, fetchurl, runCommand, writeShellScript, writeText, buildEnv 6 , callPackage, ghostscript_headless, harfbuzz 7 , makeWrapper, installShellFiles 8 , python3, ruby, perl, tk, jdk, bash, snobol4 ··· 20 }; 21 inherit useFixedHashes; 22 tlpdb = overriddenTlpdb; 23 }; 24 25 tlpdb = import ./tlpdb.nix; ··· 94 // lib.optionalAttrs (args ? deps) { deps = map (n: tl.${n}) (args.deps or [ ]); }) 95 ) overriddenTlpdb; 96 97 + # function for creating a working environment 98 + buildTeXEnv = import ./build-tex-env.nix { 99 + inherit bin tl; 100 + ghostscript = ghostscript_headless; 101 + inherit lib buildEnv libfaketime makeFontsConf makeWrapper runCommand 102 + writeShellScript writeText toTLPkgSets bash perl coreutils gawk gnugrep gnused; 103 + }; 104 + 105 + ### texlive.combine compatibility layer: 106 + # convert TeX packages to { pkgs = [ ... ]; } lists 107 + # respecting specified outputs 108 + toTLPkgList = drv: if drv.outputSpecified or false 109 + then let tlType = drv.tlType or tlOutToType.${drv.tlOutputName or drv.outputName} or null; in 110 + lib.optional (tlType != null) (drv // { inherit tlType; }) 111 + else [ (drv.tex // { tlType = "run"; }) ] ++ 112 + lib.optional (drv ? texdoc) (drv.texdoc // { tlType = "doc"; } // lib.optionalAttrs (drv ? man) { hasManpages = true; }) ++ 113 + lib.optional (drv ? texsource) (drv.texsource // { tlType = "source"; }) ++ 114 + lib.optional (drv ? tlpkg) (drv.tlpkg // { tlType = "tlpkg"; }) ++ 115 + lib.optional (drv ? out) (drv.out // { tlType = "bin"; }); 116 + tlOutToType = { out = "bin"; tex = "run"; texsource = "source"; texdoc = "doc"; tlpkg = "tlpkg"; }; 117 + 118 + # convert { pkgs = [ ... ]; } lists to TeX packages 119 + # possibly more than one, if pkgs is also used to specify dependencies 120 + tlTypeToOut = { run = "tex"; doc = "texdoc"; source = "texsource"; bin = "out"; tlpkg = "tlpkg"; }; 121 + toSpecifiedNV = p: rec { 122 + name = value.tlOutputName; 123 + value = builtins.removeAttrs p [ "pkgs" ] 124 + // { outputSpecified = true; tlOutputName = tlTypeToOut.${p.tlType}; }; 125 + }; 126 + toTLPkgSet = pname: drvs: 127 + let set = lib.listToAttrs (builtins.map toSpecifiedNV drvs); 128 + mainDrv = set.out or set.tex or set.tlpkg or set.texdoc or set.texsource; in 129 + builtins.removeAttrs mainDrv [ "outputSpecified" ]; 130 + toTLPkgSets = { pkgs, ... }: lib.mapAttrsToList toTLPkgSet 131 + (builtins.groupBy (p: p.pname) pkgs); 132 + 133 + # export TeX packages as { pkgs = [ ... ]; } in the top attribute set 134 + allPkgLists = lib.mapAttrs (n: drv: { pkgs = toTLPkgList drv; }) tl; 135 + 136 + # function for creating a working environment from a set of TL packages 137 + # now a legacy wrapper around buildTeXEnv 138 + combine = import ./combine-wrapper.nix { inherit buildTeXEnv lib toTLPkgList toTLPkgSets; }; 139 + 140 assertions = with lib; 141 assertMsg (tlpdbVersion.year == version.texliveYear) "TeX Live year in texlive does not match tlpdb.nix, refusing to evaluate" && 142 assertMsg (tlpdbVersion.frozen == version.final) "TeX Live final status in texlive does not match tlpdb.nix, refusing to evaluate"; 143 144 + # Pre-defined evironment packages for TeX Live schemes, 145 + # to make nix-env usage more comfortable and build selected on Hydra. 146 + 147 + # these license lists should be the sorted union of the licenses of the packages the schemes contain. 148 + # The correctness of this collation is tested by tests.texlive.licenses 149 + licenses = with lib.licenses; { 150 + scheme-basic = [ free gfl gpl1Only gpl2 gpl2Plus knuth lgpl21 lppl1 lppl13c mit ofl publicDomain ]; 151 + scheme-context = [ bsd2 bsd3 cc-by-sa-40 free gfl gfsl gpl1Only gpl2 gpl2Plus gpl3 gpl3Plus knuth lgpl2 lgpl21 152 + lppl1 lppl13c mit ofl publicDomain x11 ]; 153 + scheme-full = [ artistic1-cl8 artistic2 asl20 bsd2 bsd3 bsdOriginal cc-by-10 cc-by-40 cc-by-sa-10 cc-by-sa-20 154 + cc-by-sa-30 cc-by-sa-40 cc0 fdl13Only free gfl gfsl gpl1Only gpl2 gpl2Plus gpl3 gpl3Plus isc knuth 155 + lgpl2 lgpl21 lgpl3 lppl1 lppl12 lppl13a lppl13c mit ofl publicDomain x11 ]; 156 + scheme-gust = [ artistic1-cl8 asl20 bsd2 bsd3 cc-by-40 cc-by-sa-40 cc0 fdl13Only free gfl gfsl gpl1Only gpl2 157 + gpl2Plus gpl3 gpl3Plus knuth lgpl2 lgpl21 lppl1 lppl12 lppl13a lppl13c mit ofl publicDomain x11 ]; 158 + scheme-infraonly = [ gpl2 gpl2Plus lgpl21 ]; 159 + scheme-medium = [ artistic1-cl8 asl20 bsd2 bsd3 cc-by-40 cc-by-sa-20 cc-by-sa-30 cc-by-sa-40 cc0 fdl13Only 160 + free gfl gpl1Only gpl2 gpl2Plus gpl3 gpl3Plus isc knuth lgpl2 lgpl21 lgpl3 lppl1 lppl12 lppl13a lppl13c mit ofl 161 + publicDomain x11 ]; 162 + scheme-minimal = [ free gpl1Only gpl2 gpl2Plus knuth lgpl21 lppl1 lppl13c mit ofl publicDomain ]; 163 + scheme-small = [ asl20 cc-by-40 cc-by-sa-40 cc0 fdl13Only free gfl gpl1Only gpl2 gpl2Plus gpl3 gpl3Plus knuth 164 + lgpl2 lgpl21 lppl1 lppl12 lppl13a lppl13c mit ofl publicDomain x11 ]; 165 + scheme-tetex = [ artistic1-cl8 asl20 bsd2 bsd3 cc-by-40 cc-by-sa-10 cc-by-sa-20 cc-by-sa-30 cc-by-sa-40 cc0 166 + fdl13Only free gfl gpl1Only gpl2 gpl2Plus gpl3 gpl3Plus isc knuth lgpl2 lgpl21 lgpl3 lppl1 lppl12 lppl13a 167 + lppl13c mit ofl publicDomain x11]; 168 + }; 169 + 170 + meta = { 171 + description = "TeX Live environment"; 172 + platforms = lib.platforms.all; 173 + maintainers = with lib.maintainers; [ veprbl ]; 174 + license = licenses.scheme-infraonly; 175 + }; 176 + 177 + combined = recurseIntoAttrs ( 178 + lib.genAttrs [ "scheme-basic" "scheme-context" "scheme-full" "scheme-gust" "scheme-infraonly" 179 + "scheme-medium" "scheme-minimal" "scheme-small" "scheme-tetex" ] 180 + (pname: 181 + (buildTeXEnv { 182 + __extraName = "combined" + lib.removePrefix "scheme" pname; 183 + __extraVersion = with version; if final then "-final" else ".${year}${month}${day}"; 184 + requiredTeXPackages = ps: [ ps.${pname} ]; 185 + # to maintain full backward compatibility, enable texlive.combine behavior 186 + __combine = true; 187 + }).overrideAttrs { 188 + meta = meta // { 189 + description = "TeX Live environment for ${pname}"; 190 + license = licenses.${pname}; 191 + }; 192 + } 193 + ) 194 + ); 195 + 196 in 197 + allPkgLists // { 198 + pkgs = tl; 199 200 tlpdb = { 201 # nested in an attribute set to prevent them from appearing in search ··· 205 206 bin = assert assertions; bin // { 207 # for backward compatibility 208 + latexindent = tl.latexindent; 209 }; 210 211 combine = assert assertions; combine; 212 213 + combined = assert assertions; combined; 214 + 215 + # convenience alias 216 + withPackages = (buildTeXEnv { }).withPackages; 217 }
+14 -15
pkgs/tools/typesetting/tex/texlive/generate-fixed-hashes.nix
··· 1 with import ../../../../.. { }; 2 3 with lib; let 4 - isFod = p: p.tlType != "bin" && isDerivation p; 5 6 - # ugly hack to extract combine from collection-latexextra, since it is masked by texlive.combine 7 - combine = lib.findFirst (p: (lib.head p.pkgs).pname == "combine") { pkgs = [ ]; } (lib.head texlive.collection-latexextra.pkgs).tlDeps; 8 - all = filter (p: p ? pkgs) (attrValues (removeAttrs texlive [ "bin" "combine" "combined" "tlpdb" ])) ++ [ combine ]; 9 - sorted = sort (a: b: (head a.pkgs).pname < (head b.pkgs).pname) all; 10 - fods = filter isFod (concatMap (p: p.pkgs or [ ]) all); 11 12 computeHash = fod: runCommand "${fod.pname}-${fod.tlType}-fixed-hash" 13 { buildInputs = [ nix ]; inherit fod; } ··· 15 16 hash = fod: fod.outputHash or (builtins.readFile (computeHash fod)); 17 18 - hashes = { pkgs }: 19 - concatMapStrings ({ tlType, ... }@p: lib.optionalString (isFod p) (''${tlType}="${hash p}";'')) pkgs; 20 21 - hashLine = { pkgs }@pkg: 22 let 23 - fods = lib.filter isFod pkgs; 24 - first = lib.head fods; 25 # NOTE: the fixed naming scheme must match default.nix 26 - fixedName = with first; "${pname}-${toString revision}${first.extraRevision or ""}"; 27 in 28 - lib.optionalString (fods != [ ]) '' 29 - ${strings.escapeNixIdentifier fixedName}={${hashes pkg}}; 30 ''; 31 in 32 { ··· 37 fixedHashesNix = writeText "fixed-hashes.nix" 38 '' 39 { 40 - ${lib.concatMapStrings hashLine sorted}} 41 ''; 42 }
··· 1 with import ../../../../.. { }; 2 3 with lib; let 4 + getFods = drv: lib.optional (isDerivation drv.tex) (drv.tex // { tlType = "run"; }) 5 + ++ lib.optional (drv ? texdoc) (drv.texdoc // { tlType = "doc"; }) 6 + ++ lib.optional (drv ? texsource) (drv.texsource // { tlType = "source"; }) 7 + ++ lib.optional (drv ? tlpkg) (drv.tlpkg // { tlType = "tlpkg"; }); 8 9 + sorted = sort (a: b: a.pname < b.pname) (attrValues texlive.pkgs); 10 + fods = concatMap getFods sorted; 11 12 computeHash = fod: runCommand "${fod.pname}-${fod.tlType}-fixed-hash" 13 { buildInputs = [ nix ]; inherit fod; } ··· 15 16 hash = fod: fod.outputHash or (builtins.readFile (computeHash fod)); 17 18 + hashes = fods: 19 + concatMapStrings ({ tlType, ... }@p: ''${tlType}="${hash p}";'') fods; 20 21 + hashLine = { pname, revision, extraRevision ? "", ... }@drv: 22 let 23 + fods = getFods drv; 24 # NOTE: the fixed naming scheme must match default.nix 25 + fixedName = "${pname}-${toString revision}${extraRevision}"; 26 in 27 + optionalString (fods != [ ]) '' 28 + ${strings.escapeNixIdentifier fixedName}={${hashes fods}}; 29 ''; 30 in 31 { ··· 36 fixedHashesNix = writeText "fixed-hashes.nix" 37 '' 38 { 39 + ${concatMapStrings hashLine sorted}} 40 ''; 41 }
+1
pkgs/tools/typesetting/tex/texlive/tl2nix.sed
··· 91 t next-doc # loop if the previous lines matched 92 93 / (texmf-dist|RELOC)\/doc\/man\//i\ hasManpages = true; 94 95 D # restart cycle 96 }
··· 91 t next-doc # loop if the previous lines matched 92 93 / (texmf-dist|RELOC)\/doc\/man\//i\ hasManpages = true; 94 + / (texmf-dist|RELOC)\/doc\/info\//i\ hasInfo = true; 95 96 D # restart cycle 97 }
+5 -5
pkgs/tools/typesetting/tex/texlive/tlpdb-overrides.nix
··· 126 127 texlive-scripts.binlinks = { 128 mktexfmt = "fmtutil"; 129 - texhash = (lib.last tl."texlive.infra".pkgs) + "/bin/mktexlsr"; 130 }; 131 132 texlive-scripts-extra.binlinks = { ··· 352 mkdir -p support/texdoc 353 touch support/texdoc/NEWS 354 355 - TEXMFCNF="${lib.head tl.kpathsea.pkgs}/web2c" TEXMF="$out" TEXDOCS=. TEXMFVAR=. \ 356 "${bin.luatex}"/bin/texlua "$out"/scripts/texdoc/texdoc.tlu \ 357 -c texlive_tlpdb=texlive.tlpdb -lM texdoc 358 ··· 362 363 # install zsh completion 364 postFixup = '' 365 - TEXMFCNF="${lib.head tl.kpathsea.pkgs}"/web2c TEXMF="$scriptsFolder/../.." \ 366 texlua "$out"/bin/texdoc --print-completion zsh > "$TMPDIR"/_texdoc 367 substituteInPlace "$TMPDIR"/_texdoc \ 368 --replace 'compdef __texdoc texdoc' '#compdef texdoc' \ ··· 381 license = [ "gpl2Plus" ] ++ lib.toList bin.core.meta.license.shortName ++ orig."texlive.infra".license or [ ]; 382 383 scriptsFolder = "texlive"; 384 - extraBuildInputs = [ coreutils gnused gnupg (lib.last tl.kpathsea.pkgs) (perl.withPackages (ps: with ps; [ Tk ])) ]; 385 386 # make tlmgr believe it can use kpsewhich to evaluate TEXMFROOT 387 postFixup = '' 388 substituteInPlace "$out"/bin/tlmgr \ 389 --replace 'if (-r "$bindir/$kpsewhichname")' 'if (1)' 390 sed -i '2i$ENV{PATH}='"'"'${lib.makeBinPath [ gnupg ]}'"'"' . ($ENV{PATH} ? ":$ENV{PATH}" : '"'''"');' "$out"/bin/tlmgr 391 - sed -i '2iPATH="${lib.makeBinPath [ coreutils gnused (lib.last tl.kpathsea.pkgs) ]}''${PATH:+:$PATH}"' "$out"/bin/mktexlsr 392 ''; 393 394 # add minimal texlive.tlpdb
··· 126 127 texlive-scripts.binlinks = { 128 mktexfmt = "fmtutil"; 129 + texhash = tl."texlive.infra" + "/bin/mktexlsr"; 130 }; 131 132 texlive-scripts-extra.binlinks = { ··· 352 mkdir -p support/texdoc 353 touch support/texdoc/NEWS 354 355 + TEXMFCNF="${tl.kpathsea.tex}/web2c" TEXMF="$out" TEXDOCS=. TEXMFVAR=. \ 356 "${bin.luatex}"/bin/texlua "$out"/scripts/texdoc/texdoc.tlu \ 357 -c texlive_tlpdb=texlive.tlpdb -lM texdoc 358 ··· 362 363 # install zsh completion 364 postFixup = '' 365 + TEXMFCNF="${tl.kpathsea.tex}"/web2c TEXMF="$scriptsFolder/../.." \ 366 texlua "$out"/bin/texdoc --print-completion zsh > "$TMPDIR"/_texdoc 367 substituteInPlace "$TMPDIR"/_texdoc \ 368 --replace 'compdef __texdoc texdoc' '#compdef texdoc' \ ··· 381 license = [ "gpl2Plus" ] ++ lib.toList bin.core.meta.license.shortName ++ orig."texlive.infra".license or [ ]; 382 383 scriptsFolder = "texlive"; 384 + extraBuildInputs = [ coreutils gnused gnupg tl.kpathsea (perl.withPackages (ps: with ps; [ Tk ])) ]; 385 386 # make tlmgr believe it can use kpsewhich to evaluate TEXMFROOT 387 postFixup = '' 388 substituteInPlace "$out"/bin/tlmgr \ 389 --replace 'if (-r "$bindir/$kpsewhichname")' 'if (1)' 390 sed -i '2i$ENV{PATH}='"'"'${lib.makeBinPath [ gnupg ]}'"'"' . ($ENV{PATH} ? ":$ENV{PATH}" : '"'''"');' "$out"/bin/tlmgr 391 + sed -i '2iPATH="${lib.makeBinPath [ coreutils gnused tl.kpathsea ]}''${PATH:+:$PATH}"' "$out"/bin/mktexlsr 392 ''; 393 394 # add minimal texlive.tlpdb
+15
pkgs/tools/typesetting/tex/texlive/tlpdb.nix
··· 1707 sha512.run = "4f97d0d87d1f29985c83c99629fc52e8e18f6eabf95d77aa888429187b49ed9525661d9c06b46a9b2295b03df412778ede1490fa9cd8ec680c3209a4ca6d0be0"; 1708 sha512.doc = "940297c3d69de7e01caa09ff44483f7334aba14705bdcdc83661ca9be2210133e094f99a8355b4b88d076355bb4f13f64c21700bff57f452dd5dbc8d2fddb432"; 1709 hasManpages = true; 1710 hasRunfiles = true; 1711 license = [ "lgpl3" ]; 1712 version = "2.85"; ··· 15500 sha512.run = "d24be610a63a9df22ebe6f53891519ab77900611d1159dec5e97b27160f3552b4cbce42b575a036125d2b15910a72cb5e3793a3409c5d0f4b1df0c2433e828f8"; 15501 sha512.doc = "976ff6c9628fe85adca2287f04d76f2c1605f243e28b4d32cb1ef9a90d30dcae0d202e6d5156914c204fd42b0a66460755a89f7dbdeb9ec1ccf6010cfe8daf78"; 15502 hasManpages = true; 15503 license = [ "lgpl3" ]; 15504 version = "1.17"; 15505 }; ··· 15521 sha512.run = "a680a4685d3cbb429ad9dada0d48098f7755253ad1d7c808731f0f4fb4c37971cb937a9fa68bcecd892de93cc35a8086b742c86338460585c2912f36d00ade67"; 15522 sha512.doc = "a6acb780a45663fb21976622d7b6c3ea8d4adf1fe405ee97cd7c4cf09fa49b59069ba72b2aa14b53d3ba631b37c5cbd979929adaa274a0bec8b1272d85e1cd43"; 15523 hasManpages = true; 15524 hasRunfiles = true; 15525 license = [ "free" ]; 15526 }; ··· 16610 sha512.run = "fda8158ae2bdc96187b6e6ace2a94be3e0f68201adbc02553b48a3848481352ac10ddd72babcbc2835e089ce751ade7dfa6cfd1c642c94155c2861db865f5c29"; 16611 sha512.doc = "60902b2422d2f5d7570a19daf7f586df7882505d7c156539699a0aa47a0f3bde5688dcbdc92c8a6a9878f11392bc9b9f147626aad230eecd2740d56f104928ed"; 16612 hasManpages = true; 16613 sha512.source = "015de2eeeaec99bd15882a190f9ef3f2112520f8c591c7e6d2351c52d8690b024750adea426bcf95f438aaa20c97dd321881ac7212ff181e148337b57f6d386c"; 16614 hasRunfiles = true; 16615 license = [ "gpl2Plus" ]; ··· 16666 revision = 66119; 16667 sha512.run = "f155834a9636991c8ae752f61f70bdf22ab3172270c85aebb05462cf26e44f6e81fb83842c8515bfa54e632a3beab8bb91cccf2b5eef459d77738443c77df56d"; 16668 sha512.doc = "5d06f8a4ef295e0fac8cd1dc73ff98e266dcf4394ed76223c92d20758fa8195ef5bea9bde49b1a247acfdf67aa7717092f978b55fc4fbc8665922487d57985d6"; 16669 hasRunfiles = true; 16670 scriptExts = [ 16671 "tcl" ··· 18768 stripPrefix = 0; 18769 sha512.run = "424da4dbbc07c41840e6aeb6fabeef5d4778d206b9cb8a90e752ebeb65d962b96ad41a7e20c86a16665e2bf48ad795d85001da66ff41b01ae3c949c6eefa4593"; 18770 sha512.doc = "78199996913192f5f69423b6f412acc52b74f051b01d3e345b97b7f1d9ea4aea762a7b83488068f3091b41da69471d56b3f18ab4d299cc6adfe4e004072db303"; 18771 hasRunfiles = true; 18772 license = [ "gpl1Only" ]; 18773 }; ··· 24499 sha512.run = "8a9f0dd49470bec5ba0f963a0385bea45141d6b805682bd65e95291b02158b9d2cedd5bd43592de7c447fe87f04efa00e4d1aa191a490147adcb57ec3922b5db"; 24500 sha512.doc = "51500943de0184fd9794dbf6af80aed2fc7bbaf2a7949facb1840ad0e32344d217aa4d58ee76e3934aec891858f789b3847b9027cb2bd75e5962be98ddd9d02f"; 24501 hasManpages = true; 24502 hasRunfiles = true; 24503 license = [ "lgpl21" ]; 24504 }; ··· 25258 stripPrefix = 0; 25259 sha512.run = "34b91b19e1b71b1df6d0f57dda4d6976a93b16afac259656c9d4e331b0c23a9b0550563c1a10dd7a95640e3740b3b15597c1023f6c2721bf2a64800466b9cd09"; 25260 sha512.doc = "d4584d9259f3c1867e7445d4a219e4decc5ba3b305e20d1e780180a47fbad8df4d55552726d8288e78c8388823a2b652b81080c8139b00f4ea3ca10e5789375b"; 25261 license = [ "free" ]; 25262 }; 25263 latex2e-help-texinfo-fr = { ··· 25265 stripPrefix = 0; 25266 sha512.run = "96366ea420532f56ae076da48f5402c2ee78ca27fae8180795d6cd18aae118a8c7060208ff43ab64526addcdce9e4d90790583842b20c751f37865cf616e04e4"; 25267 sha512.doc = "52f6aea9ac2393a73d7dc7ce8ad4d6f08e0a224397199d5def97412502026717e8cb966552368899c50718a1049b1ad4610d2d23150a45bee55cc2c776003db7"; 25268 license = [ "publicDomain" ]; 25269 }; 25270 latex2e-help-texinfo-spanish = { ··· 25272 stripPrefix = 0; 25273 sha512.run = "870c8f3af54ac42df5f4958669cf730cd16084c985f0b377c5aba9d526b8f7be14b367791d2c0a1f1a715739390ab63777ff2a92e7f9aad09897c8bbecff495e"; 25274 sha512.doc = "4c751a7305e089dab61bf991436ab1e612cfca0d17e416e21d659c04ef32eeb2d14dbeb09d63649a2b79f842766a218c43ae2c6fbeeba5549f039f991049a79d"; 25275 license = [ "free" ]; 25276 }; 25277 latex2man = { ··· 25279 sha512.run = "2617f6e8059f30c0098ea896cff69f585ea2ddbd3bbbd8066e7296dd833d3a246b8fefc0af71a92abf7e2051c754c0e3e6098175a4b181780563416bc9146b95"; 25280 sha512.doc = "390666cc56ad70342c9a24ca593fe65b3760674a882ed8bba383d193f2578285727a085f823afc03fa0dbc9966612caf9a29222fd2a9f39214f01aa268acdc50"; 25281 hasManpages = true; 25282 hasRunfiles = true; 25283 license = [ "lppl1" ]; 25284 version = "1.29"; ··· 28873 revision = 61217; 28874 sha512.run = "ca93a3ae439f9cd8029720bd1d90fbe75a403e7ab4ebcbe1ba1e5a7a28aa9269197f90a4aee849fea59d734d5dc38f04eedc140ff1be64fd805a10ab5510a2f5"; 28875 sha512.doc = "6c10831fdcc48d25645be675fbf5da29da945bd79032c60e73e04a39d61c287a64e7b884381ac0b08e48f5dc9b6dec27efea874f6e13d6e4a5e3f32c22fa3ce2"; 28876 hasRunfiles = true; 28877 license = [ "lppl13c" ]; 28878 version = "2.7"; ··· 40536 stripPrefix = 0; 40537 sha512.run = "b03911aa9711eb5eeed77c026c4bbcf952da80322b855ac631e78c07a48ad2ff1a4afdd6e25a00257d1b70e054645f07f65c98fe74f6b1389be46625f5eb8487"; 40538 sha512.doc = "f4078e3b1693fedcbe139b67c50824845644a2b1e57dd27f9e46e44504d8fe8ac0ca706590e9149c06e71794a188b20777bfd6bf1afe85f16c806ba4f9b99cd8"; 40539 license = [ "free" ]; 40540 version = "1.1"; 40541 }; ··· 41052 stripPrefix = 0; 41053 sha512.run = "f4d160e494b1579743a83b2a0926df9e8dd69fdaa79d3f4f97e0ed5f4ece31ab380ff6994a1c9015e0af9b842bdfb9b066442ca4b3018df6659922af9f746b0b"; 41054 sha512.doc = "e177209a937fa1d9d683eb805e9e8929612b4b1ff750955d38ca681b657662712a59609990f77021063a223ce61a92fdd567eee91376ef4b67fd3a322db09463"; 41055 hasRunfiles = true; 41056 license = [ "cc-by-40" ]; 41057 version = "v2r3"; ··· 41115 stripPrefix = 0; 41116 sha512.run = "f790f2a94e67573635afb5b4c2d375bede61eb3afe271169078fe905d326119234363ee896ecc93a9892d26e0a394fc350edbda810e218b0b06cc30681fd9cf0"; 41117 sha512.doc = "48ffb3b9053250f4425992c57869c6153601e9dfaa4931ac4ff3c12df44b148dce08496acbae495fd5f9fe37e11044a3fc0669c713515d2cc99506fd6be59859"; 41118 }; 41119 texlive-es = { 41120 revision = 65640;
··· 1707 sha512.run = "4f97d0d87d1f29985c83c99629fc52e8e18f6eabf95d77aa888429187b49ed9525661d9c06b46a9b2295b03df412778ede1490fa9cd8ec680c3209a4ca6d0be0"; 1708 sha512.doc = "940297c3d69de7e01caa09ff44483f7334aba14705bdcdc83661ca9be2210133e094f99a8355b4b88d076355bb4f13f64c21700bff57f452dd5dbc8d2fddb432"; 1709 hasManpages = true; 1710 + hasInfo = true; 1711 hasRunfiles = true; 1712 license = [ "lgpl3" ]; 1713 version = "2.85"; ··· 15501 sha512.run = "d24be610a63a9df22ebe6f53891519ab77900611d1159dec5e97b27160f3552b4cbce42b575a036125d2b15910a72cb5e3793a3409c5d0f4b1df0c2433e828f8"; 15502 sha512.doc = "976ff6c9628fe85adca2287f04d76f2c1605f243e28b4d32cb1ef9a90d30dcae0d202e6d5156914c204fd42b0a66460755a89f7dbdeb9ec1ccf6010cfe8daf78"; 15503 hasManpages = true; 15504 + hasInfo = true; 15505 license = [ "lgpl3" ]; 15506 version = "1.17"; 15507 }; ··· 15523 sha512.run = "a680a4685d3cbb429ad9dada0d48098f7755253ad1d7c808731f0f4fb4c37971cb937a9fa68bcecd892de93cc35a8086b742c86338460585c2912f36d00ade67"; 15524 sha512.doc = "a6acb780a45663fb21976622d7b6c3ea8d4adf1fe405ee97cd7c4cf09fa49b59069ba72b2aa14b53d3ba631b37c5cbd979929adaa274a0bec8b1272d85e1cd43"; 15525 hasManpages = true; 15526 + hasInfo = true; 15527 hasRunfiles = true; 15528 license = [ "free" ]; 15529 }; ··· 16613 sha512.run = "fda8158ae2bdc96187b6e6ace2a94be3e0f68201adbc02553b48a3848481352ac10ddd72babcbc2835e089ce751ade7dfa6cfd1c642c94155c2861db865f5c29"; 16614 sha512.doc = "60902b2422d2f5d7570a19daf7f586df7882505d7c156539699a0aa47a0f3bde5688dcbdc92c8a6a9878f11392bc9b9f147626aad230eecd2740d56f104928ed"; 16615 hasManpages = true; 16616 + hasInfo = true; 16617 sha512.source = "015de2eeeaec99bd15882a190f9ef3f2112520f8c591c7e6d2351c52d8690b024750adea426bcf95f438aaa20c97dd321881ac7212ff181e148337b57f6d386c"; 16618 hasRunfiles = true; 16619 license = [ "gpl2Plus" ]; ··· 16670 revision = 66119; 16671 sha512.run = "f155834a9636991c8ae752f61f70bdf22ab3172270c85aebb05462cf26e44f6e81fb83842c8515bfa54e632a3beab8bb91cccf2b5eef459d77738443c77df56d"; 16672 sha512.doc = "5d06f8a4ef295e0fac8cd1dc73ff98e266dcf4394ed76223c92d20758fa8195ef5bea9bde49b1a247acfdf67aa7717092f978b55fc4fbc8665922487d57985d6"; 16673 + hasInfo = true; 16674 hasRunfiles = true; 16675 scriptExts = [ 16676 "tcl" ··· 18773 stripPrefix = 0; 18774 sha512.run = "424da4dbbc07c41840e6aeb6fabeef5d4778d206b9cb8a90e752ebeb65d962b96ad41a7e20c86a16665e2bf48ad795d85001da66ff41b01ae3c949c6eefa4593"; 18775 sha512.doc = "78199996913192f5f69423b6f412acc52b74f051b01d3e345b97b7f1d9ea4aea762a7b83488068f3091b41da69471d56b3f18ab4d299cc6adfe4e004072db303"; 18776 + hasInfo = true; 18777 hasRunfiles = true; 18778 license = [ "gpl1Only" ]; 18779 }; ··· 24505 sha512.run = "8a9f0dd49470bec5ba0f963a0385bea45141d6b805682bd65e95291b02158b9d2cedd5bd43592de7c447fe87f04efa00e4d1aa191a490147adcb57ec3922b5db"; 24506 sha512.doc = "51500943de0184fd9794dbf6af80aed2fc7bbaf2a7949facb1840ad0e32344d217aa4d58ee76e3934aec891858f789b3847b9027cb2bd75e5962be98ddd9d02f"; 24507 hasManpages = true; 24508 + hasInfo = true; 24509 hasRunfiles = true; 24510 license = [ "lgpl21" ]; 24511 }; ··· 25265 stripPrefix = 0; 25266 sha512.run = "34b91b19e1b71b1df6d0f57dda4d6976a93b16afac259656c9d4e331b0c23a9b0550563c1a10dd7a95640e3740b3b15597c1023f6c2721bf2a64800466b9cd09"; 25267 sha512.doc = "d4584d9259f3c1867e7445d4a219e4decc5ba3b305e20d1e780180a47fbad8df4d55552726d8288e78c8388823a2b652b81080c8139b00f4ea3ca10e5789375b"; 25268 + hasInfo = true; 25269 license = [ "free" ]; 25270 }; 25271 latex2e-help-texinfo-fr = { ··· 25273 stripPrefix = 0; 25274 sha512.run = "96366ea420532f56ae076da48f5402c2ee78ca27fae8180795d6cd18aae118a8c7060208ff43ab64526addcdce9e4d90790583842b20c751f37865cf616e04e4"; 25275 sha512.doc = "52f6aea9ac2393a73d7dc7ce8ad4d6f08e0a224397199d5def97412502026717e8cb966552368899c50718a1049b1ad4610d2d23150a45bee55cc2c776003db7"; 25276 + hasInfo = true; 25277 license = [ "publicDomain" ]; 25278 }; 25279 latex2e-help-texinfo-spanish = { ··· 25281 stripPrefix = 0; 25282 sha512.run = "870c8f3af54ac42df5f4958669cf730cd16084c985f0b377c5aba9d526b8f7be14b367791d2c0a1f1a715739390ab63777ff2a92e7f9aad09897c8bbecff495e"; 25283 sha512.doc = "4c751a7305e089dab61bf991436ab1e612cfca0d17e416e21d659c04ef32eeb2d14dbeb09d63649a2b79f842766a218c43ae2c6fbeeba5549f039f991049a79d"; 25284 + hasInfo = true; 25285 license = [ "free" ]; 25286 }; 25287 latex2man = { ··· 25289 sha512.run = "2617f6e8059f30c0098ea896cff69f585ea2ddbd3bbbd8066e7296dd833d3a246b8fefc0af71a92abf7e2051c754c0e3e6098175a4b181780563416bc9146b95"; 25290 sha512.doc = "390666cc56ad70342c9a24ca593fe65b3760674a882ed8bba383d193f2578285727a085f823afc03fa0dbc9966612caf9a29222fd2a9f39214f01aa268acdc50"; 25291 hasManpages = true; 25292 + hasInfo = true; 25293 hasRunfiles = true; 25294 license = [ "lppl1" ]; 25295 version = "1.29"; ··· 28884 revision = 61217; 28885 sha512.run = "ca93a3ae439f9cd8029720bd1d90fbe75a403e7ab4ebcbe1ba1e5a7a28aa9269197f90a4aee849fea59d734d5dc38f04eedc140ff1be64fd805a10ab5510a2f5"; 28886 sha512.doc = "6c10831fdcc48d25645be675fbf5da29da945bd79032c60e73e04a39d61c287a64e7b884381ac0b08e48f5dc9b6dec27efea874f6e13d6e4a5e3f32c22fa3ce2"; 28887 + hasInfo = true; 28888 hasRunfiles = true; 28889 license = [ "lppl13c" ]; 28890 version = "2.7"; ··· 40548 stripPrefix = 0; 40549 sha512.run = "b03911aa9711eb5eeed77c026c4bbcf952da80322b855ac631e78c07a48ad2ff1a4afdd6e25a00257d1b70e054645f07f65c98fe74f6b1389be46625f5eb8487"; 40550 sha512.doc = "f4078e3b1693fedcbe139b67c50824845644a2b1e57dd27f9e46e44504d8fe8ac0ca706590e9149c06e71794a188b20777bfd6bf1afe85f16c806ba4f9b99cd8"; 40551 + hasInfo = true; 40552 license = [ "free" ]; 40553 version = "1.1"; 40554 }; ··· 41065 stripPrefix = 0; 41066 sha512.run = "f4d160e494b1579743a83b2a0926df9e8dd69fdaa79d3f4f97e0ed5f4ece31ab380ff6994a1c9015e0af9b842bdfb9b066442ca4b3018df6659922af9f746b0b"; 41067 sha512.doc = "e177209a937fa1d9d683eb805e9e8929612b4b1ff750955d38ca681b657662712a59609990f77021063a223ce61a92fdd567eee91376ef4b67fd3a322db09463"; 41068 + hasInfo = true; 41069 hasRunfiles = true; 41070 license = [ "cc-by-40" ]; 41071 version = "v2r3"; ··· 41129 stripPrefix = 0; 41130 sha512.run = "f790f2a94e67573635afb5b4c2d375bede61eb3afe271169078fe905d326119234363ee896ecc93a9892d26e0a394fc350edbda810e218b0b06cc30681fd9cf0"; 41131 sha512.doc = "48ffb3b9053250f4425992c57869c6153601e9dfaa4931ac4ff3c12df44b148dce08496acbae495fd5f9fe37e11044a3fc0669c713515d2cc99506fd6be59859"; 41132 + hasInfo = true; 41133 }; 41134 texlive-es = { 41135 revision = 65640;