diff --git a/pkgs/test/texlive/default.nix b/pkgs/test/texlive/default.nix index e28b33d117ba..36a5dbb9b8a6 100644 --- a/pkgs/test/texlive/default.nix +++ b/pkgs/test/texlive/default.nix @@ -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 = diff --git a/pkgs/tools/typesetting/tex/texlive/build-tex-env.nix b/pkgs/tools/typesetting/tex/texlive/build-tex-env.nix index 1e3c1948d6d2..bfc196dd0d8d 100644 --- a/pkgs/tools/typesetting/tex/texlive/build-tex-env.nix +++ b/pkgs/tools/typesetting/tex/texlive/build-tex-env.nix @@ -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; + }; + }; + } + ) ) diff --git a/pkgs/tools/typesetting/tex/texlive/default.nix b/pkgs/tools/typesetting/tex/texlive/default.nix index a5d81fbbaa7c..9e1cd3913fa3 100644 --- a/pkgs/tools/typesetting/tex/texlive/default.nix +++ b/pkgs/tools/typesetting/tex/texlive/default.nix @@ -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