diff options
Diffstat (limited to 'pkgs/tools/typesetting/tex/texlive/build-texlive-package.nix')
-rw-r--r-- | pkgs/tools/typesetting/tex/texlive/build-texlive-package.nix | 267 |
1 files changed, 165 insertions, 102 deletions
diff --git a/pkgs/tools/typesetting/tex/texlive/build-texlive-package.nix b/pkgs/tools/typesetting/tex/texlive/build-texlive-package.nix index c1e98d710b9..efbb3a1fb56 100644 --- a/pkgs/tools/typesetting/tex/texlive/build-texlive-package.nix +++ b/pkgs/tools/typesetting/tex/texlive/build-texlive-package.nix @@ -15,17 +15,27 @@ , texliveBinaries }: +/* Convert an attribute set extracted from tlpdb.nix (with the deps attribute + already processed) to a fake multi-output derivation with possible outputs + [ "tex" "texdoc" "texsource" "tlpkg" "out" "man" "info" ] +*/ + +# TODO stabilise a generic interface decoupled from the finer details of the +# translation from texlive.tlpdb to tlpdb.nix { pname , revision , version ? toString revision +, extraRevision ? "" +, extraVersion ? "" , sha512 , mirrors -, extraVersion ? "" , fixedHashes ? { } , postUnpack ? "" +, postFixup ? "" , stripPrefix ? 1 , license ? [ ] , hasHyphens ? false +, hasInfo ? false , hasManpages ? false , hasRunfiles ? false , hasTlpkg ? false @@ -34,112 +44,165 @@ }@args: let - meta = { license = map (x: lib.licenses.${x}) license; }; - - commonPassthru = { - inherit pname revision version; - } // lib.optionalAttrs (args ? extraRevision) { - inherit (args) extraRevision; + # common metadata + name = "${pname}-${version}${extraVersion}"; + meta = { + license = map (x: lib.licenses.${x}) license; + # TeX Live packages should not be installed directly into the user profile + outputsToInstall = [ ]; }; + hasBinfiles = args ? binfiles && args.binfiles != [ ]; + hasDocfiles = sha512 ? doc; + hasSource = sha512 ? source; + + # emulate drv.all, drv.outputs lists + all = lib.optional hasBinfiles bin ++ + lib.optional hasRunfiles tex ++ + lib.optional hasDocfiles texdoc ++ + lib.optional hasSource texsource ++ + lib.optional hasTlpkg tlpkg ++ + lib.optional hasManpages man ++ + lib.optional hasInfo info; + outputs = lib.catAttrs "tlOutputName" all; + + mainDrv = if hasBinfiles then bin + else if hasRunfiles then tex + else if hasTlpkg then tlpkg + else if hasDocfiles then texdoc + else if hasSource then texsource + else tex; # fall back to attrset tex if there is no derivation + + # emulate multi-output derivation plus additional metadata + # (out is handled in mkContainer) + passthru = { + inherit all outputs pname; + revision = toString revision + extraRevision; + version = version + extraVersion; + outputSpecified = true; + inherit tex; + } // lib.optionalAttrs (args ? deps) { tlDeps = args.deps; } + // lib.optionalAttrs (args ? formats) { inherit (args) formats; } + // lib.optionalAttrs hasHyphens { inherit hasHyphens; } + // lib.optionalAttrs (args ? postactionScript) { inherit (args) postactionScript; } + // lib.optionalAttrs hasDocfiles { texdoc = texdoc; } + // lib.optionalAttrs hasSource { texsource = texsource; } + // lib.optionalAttrs hasTlpkg { tlpkg = tlpkg; } + // lib.optionalAttrs hasManpages { man = man; } + // lib.optionalAttrs hasInfo { info = info; }; + # build run, doc, source, tlpkg containers - mkContainer = tlType: passthru: sha512: + mkContainer = tlType: tlOutputName: sha512: let - # NOTE: the fixed naming scheme must match generated-fixed-hashes.nix + fixedHash = fixedHashes.${tlType} or null; # be graceful about missing hashes # the basename used by upstream (without ".tar.xz" suffix) + # tlpkg is not a true container but a subfolder of the run container urlName = pname + (lib.optionalString (tlType != "run" && tlType != "tlpkg") ".${tlType}"); - # name + version for the derivation - tlName = urlName + (lib.optionalString (tlType == "tlpkg") ".tlpkg") + "-${version}${extraVersion}"; - fixedHash = fixedHashes.${tlType} or null; # be graceful about missing hashes - - urls = args.urls or (if args ? url then [ args.url ] else - map (up: "${up}/archive/${urlName}.r${toString revision}.tar.xz") mirrors); + urls = map (up: "${up}/archive/${urlName}.r${toString revision}.tar.xz") mirrors; + # TODO switch to simpler "${name}-${tlOutputName}" (requires new fixed hashes) + container = runCommand "texlive-${pname}${lib.optionalString (tlType != "run") ".${tlType}"}-${version}${extraVersion}" + ({ + src = fetchurl { inherit urls sha512; }; + # save outputName as fixed output derivations cannot change nor override outputName + passthru = passthru // { inherit tlOutputName; }; + # TODO remove tlType from derivation (requires a rebuild) + inherit meta stripPrefix tlType; + } // lib.optionalAttrs (fixedHash != null) { + outputHash = fixedHash; + outputHashAlgo = "sha256"; + outputHashMode = "recursive"; + }) + ('' + mkdir "$out" + if [[ "$tlType" == "tlpkg" ]]; then + tar -xf "$src" \ + --strip-components=1 \ + -C "$out" --anchored --exclude=tlpkg/tlpobj --keep-old-files \ + tlpkg + else + tar -xf "$src" \ + --strip-components="$stripPrefix" \ + -C "$out" --anchored --exclude=tlpkg --keep-old-files + fi + '' + postUnpack); in - runCommand "texlive-${tlName}" - ({ - src = fetchurl { inherit urls sha512; }; - inherit meta passthru stripPrefix tlType; - } // lib.optionalAttrs (fixedHash != null) { - outputHash = fixedHash; - outputHashAlgo = "sha256"; - outputHashMode = "recursive"; - }) - ('' - mkdir "$out" - if [[ "$tlType" == "tlpkg" ]]; then - tar -xf "$src" \ - --strip-components=1 \ - -C "$out" --anchored --exclude=tlpkg/tlpobj --keep-old-files \ - tlpkg - else - tar -xf "$src" \ - --strip-components="$stripPrefix" \ - -C "$out" --anchored --exclude=tlpkg --keep-old-files - fi - '' + postUnpack); - - tex = [ - ( - let passthru = commonPassthru - // lib.optionalAttrs (args ? deps) { tlDeps = args.deps; } - // lib.optionalAttrs (args ? formats) { inherit (args) formats; } - // lib.optionalAttrs hasHyphens { inherit hasHyphens; }; in - if hasRunfiles then mkContainer "run" passthru sha512.run - else (passthru // { tlType = "run"; }) - ) - ]; - - doc = let passthru = commonPassthru - // lib.optionalAttrs hasManpages { inherit hasManpages; }; in - lib.optional (sha512 ? doc) (mkContainer "doc" passthru sha512.doc); - - source = lib.optional (sha512 ? source) (mkContainer "source" commonPassthru sha512.source); - - tlpkg = let passthru = commonPassthru - // lib.optionalAttrs (args ? postactionScript) { postactionScript = args.postactionScript; }; in - lib.optional hasTlpkg (mkContainer "tlpkg" passthru sha512.run); - - bin = lib.optional (args ? binfiles && args.binfiles != [ ]) ( - let - # find interpreters for the script extensions found in tlpdb - extToInput = { - jar = jdk; - lua = texliveBinaries.luatex; - py = python3; - rb = ruby; - sno = snobol4; - tcl = tk; - texlua = texliveBinaries.luatex; - tlu = texliveBinaries.luatex; - }; - run = lib.head tex; - in - runCommand "texlive-${pname}.bin-${version}" - { - passthru = commonPassthru // { tlType = "bin"; }; - inherit meta; - # shebang interpreters and compiled binaries - buildInputs = let outName = builtins.replaceStrings [ "-" ] [ "_" ] pname; in - [ texliveBinaries.core.${outName} or null - texliveBinaries.${pname} or null - texliveBinaries.core-big.${outName} or null ] - ++ (args.extraBuildInputs or [ ]) ++ [ bash perl ] - ++ (lib.attrVals (args.scriptExts or [ ]) extToInput); - nativeBuildInputs = extraNativeBuildInputs; - # absolute scripts folder - scriptsFolder = lib.optionalString (run ? outPath) (run.outPath + "/scripts/" + args.scriptsFolder or pname); - # binaries info - inherit (args) binfiles; - binlinks = builtins.attrNames (args.binlinks or { }); - bintargets = builtins.attrValues (args.binlinks or { }); - # build scripts - patchScripts = ./patch-scripts.sed; - makeBinContainers = ./make-bin-containers.sh; - } - '' - . "$makeBinContainers" - ${args.postFixup or ""} - '' - ); + # remove the standard drv.out, optionally replace it with the bin container + builtins.removeAttrs container [ "out" ] // lib.optionalAttrs hasBinfiles { out = bin; }; + + tex = + if hasRunfiles then mkContainer "run" "tex" sha512.run + else passthru + // { inherit meta; tlOutputName = "tex"; } + // lib.optionalAttrs hasBinfiles { out = bin; }; + + texdoc = mkContainer "doc" "texdoc" sha512.doc; + + texsource = mkContainer "source" "texsource" sha512.source; + + tlpkg = mkContainer "tlpkg" "tlpkg" sha512.run; + + # build bin container + extToInput = { + # find interpreters for the script extensions found in tlpdb + jar = jdk; + lua = texliveBinaries.luatex; + py = python3; + rb = ruby; + sno = snobol4; + tcl = tk; + texlua = texliveBinaries.luatex; + tlu = texliveBinaries.luatex; + }; + + # TODO switch to simpler "${name}" (requires a rebuild) + bin = runCommand "texlive-${pname}.bin-${version}" + { + inherit meta; + passthru = passthru // { tlOutputName = "out"; }; + # shebang interpreters + buildInputs =let outName = builtins.replaceStrings [ "-" ] [ "_" ] pname; in + [ texliveBinaries.core.${outName} or null + texliveBinaries.${pname} or null + texliveBinaries.core-big.${outName} or null ] + ++ (args.extraBuildInputs or [ ]) ++ [ bash perl ] + ++ (lib.attrVals (args.scriptExts or [ ]) extToInput); + nativeBuildInputs = extraNativeBuildInputs; + # absolute scripts folder + scriptsFolder = lib.optionalString (tex ? outPath) (tex.outPath + "/scripts/" + args.scriptsFolder or pname); + # binaries info + inherit (args) binfiles; + binlinks = builtins.attrNames (args.binlinks or { }); + bintargets = builtins.attrValues (args.binlinks or { }); + # build scripts + patchScripts = ./patch-scripts.sed; + makeBinContainers = ./make-bin-containers.sh; + } + '' + . "$makeBinContainers" + ${args.postFixup or ""} + ''; + + # build man, info containers + # TODO switch to simpler "${name}-man" (requires a rebuild) + man = builtins.removeAttrs (runCommand "texlive-${pname}.man-${version}${extraVersion}" + { + inherit meta texdoc; + passthru = passthru // { tlOutputName = "man"; }; + } + '' + mkdir -p "$out"/share + ln -s {"$texdoc"/doc,"$out"/share}/man + '') [ "out" ] // lib.optionalAttrs hasBinfiles { out = bin; }; + + # TODO switch to simpler "${name}-info" (requires a rebuild) + info = builtins.removeAttrs (runCommand "texlive-${pname}.info-${version}${extraVersion}" + { + inherit meta texdoc; + passthru = passthru // { tlOutputName = "info"; }; + } + '' + mkdir -p "$out"/share + ln -s {"$texdoc"/doc,"$out"/share}/info + '') [ "out" ] // lib.optionalAttrs hasBinfiles { out = bin; }; in -{ pkgs = tex ++ doc ++ source ++ tlpkg ++ bin; } +builtins.removeAttrs mainDrv [ "outputSpecified" ] |