diff --git a/doc/languages-frameworks/perl.xml b/doc/languages-frameworks/perl.xml index d0f124f29d42..065212a0e180 100644 --- a/doc/languages-frameworks/perl.xml +++ b/doc/languages-frameworks/perl.xml @@ -75,7 +75,8 @@ foo = import ../path/to/foo.nix { It adds the contents of the PERL5LIB environment variable to #! .../bin/perl line of Perl scripts as -Idir flags. This ensures - that a script can find its dependencies. + that a script can find its dependencies. (This can cause this shebang line + to become too long for Darwin to handle; see the note below.) @@ -137,6 +138,36 @@ ClassC3Componentised = buildPerlPackage rec { + + On Darwin, if a script has too many + -Idir flags in its first line + (its “shebang line”), it will not run. This can be worked around by calling + the shortenPerlShebang function from the + postInstall phase: + +{ stdenv, buildPerlPackage, fetchurl, shortenPerlShebang }: + +ImageExifTool = buildPerlPackage { + pname = "Image-ExifTool"; + version = "11.50"; + + src = fetchurl { + url = "https://www.sno.phy.queensu.ca/~phil/exiftool/Image-ExifTool-11.50.tar.gz"; + sha256 = "0d8v48y94z8maxkmw1rv7v9m0jg2dc8xbp581njb6yhr7abwqdv3"; + }; + + buildInputs = stdenv.lib.optional stdenv.isDarwin shortenPerlShebang; + postInstall = stdenv.lib.optional stdenv.isDarwin '' + shortenPerlShebang $out/bin/exiftool + ''; +}; + + This will remove the -I flags from the shebang line, + rewrite them in the use lib form, and put them on the next + line instead. This function can be given any number of Perl scripts as + arguments; it will modify them in-place. + +
Generation from CPAN diff --git a/pkgs/build-support/setup-hooks/shorten-perl-shebang.sh b/pkgs/build-support/setup-hooks/shorten-perl-shebang.sh new file mode 100644 index 000000000000..4bf7c0ff1af4 --- /dev/null +++ b/pkgs/build-support/setup-hooks/shorten-perl-shebang.sh @@ -0,0 +1,88 @@ +# This setup hook modifies a Perl script so that any "-I" flags in its shebang +# line are rewritten into a "use lib ..." statement on the next line. This gets +# around a limitation in Darwin, which will not properly handle a script whose +# shebang line exceeds 511 characters. +# +# Each occurrence of "-I /path/to/lib1" or "-I/path/to/lib2" is removed from +# the shebang line, along with the single space that preceded it. These library +# paths are placed into a new line of the form +# +# use lib "/path/to/lib1", "/path/to/lib2"; +# +# immediately following the shebang line. If a library appeared in the original +# list more than once, only its first occurrence will appear in the output +# list. In other words, the libraries are deduplicated, but the ordering of the +# first appearance of each one is preserved. +# +# Any flags other than "-I" in the shebang line are left as-is, and the +# interpreter is also left alone (although the script will abort if the +# interpreter does not seem to be either "perl" or else "env" with "perl" as +# its argument). Each line after the shebang line is left unchanged. Each file +# is modified in place. +# +# Usage: +# shortenPerlShebang SCRIPT... + +shortenPerlShebang() { + while [ $# -gt 0 ]; do + _shortenPerlShebang "$1" + shift + done +} + +_shortenPerlShebang() { + local program="$1" + + echo "shortenPerlShebang: rewriting shebang line in $program" + + if ! isScript "$program"; then + die "shortenPerlShebang: refusing to modify $program because it is not a script" + fi + + local temp="$(mktemp)" + + gawk ' + (NR == 1) { + if (!($0 ~ /\/(perl|env +perl)\>/)) { + print "shortenPerlShebang: script does not seem to be a Perl script" > "/dev/stderr" + exit 1 + } + idx = 0 + while (match($0, / -I ?([^ ]+)/, pieces)) { + matches[idx] = pieces[1] + idx++ + $0 = gensub(/ -I ?[^ ]+/, "", 1, $0) + } + print $0 + if (idx > 0) { + prefix = "use lib " + for (idx in matches) { + path = matches[idx] + if (!(path in seen)) { + printf "%s\"%s\"", prefix, path + seen[path] = 1 + prefix = ", " + } + } + print ";" + } + } + (NR > 1 ) { + print + } + ' "$program" > "$temp" || die + # Preserve the mode of the original file + cp --preserve=mode --attributes-only "$program" "$temp" + mv "$temp" "$program" + + # Measure the new shebang line length and make sure it's okay. We subtract + # one to account for the trailing newline that "head" included in its + # output. + local new_length=$(( $(head -n 1 "$program" | wc -c) - 1 )) + + # Darwin is okay when the shebang line contains 511 characters, but not + # when it contains 512 characters. + if [ $new_length -ge 512 ]; then + die "shortenPerlShebang: shebang line is $new_length characters--still too long for Darwin!" + fi +} diff --git a/pkgs/tools/typesetting/biber/default.nix b/pkgs/tools/typesetting/biber/default.nix index 3f9ba73e13d9..6d26129f2c12 100644 --- a/pkgs/tools/typesetting/biber/default.nix +++ b/pkgs/tools/typesetting/biber/default.nix @@ -1,4 +1,4 @@ -{ stdenv, perlPackages, texlive }: +{ stdenv, perlPackages, shortenPerlShebang, texlive }: let biberSource = stdenv.lib.head (builtins.filter (p: p.tlType == "source") texlive.biber.pkgs); @@ -21,6 +21,11 @@ perlPackages.buildPerlModule { TestDifferences PerlIOutf8_strict ]; + nativeBuildInputs = stdenv.lib.optional stdenv.isDarwin shortenPerlShebang; + + postInstall = stdenv.lib.optionalString stdenv.isDarwin '' + shortenPerlShebang $out/bin/biber + ''; meta = with stdenv.lib; { description = "Backend for BibLaTeX"; diff --git a/pkgs/tools/typesetting/tex/texlive/bin.nix b/pkgs/tools/typesetting/tex/texlive/bin.nix index 5aab4c80d275..57347a120214 100644 --- a/pkgs/tools/typesetting/tex/texlive/bin.nix +++ b/pkgs/tools/typesetting/tex/texlive/bin.nix @@ -5,7 +5,7 @@ , perl, perlPackages, pkgconfig, autoreconfHook , poppler, libpaper, graphite2, zziplib, harfbuzz, potrace, gmp, mpfr , cairo, pixman, xorg, clisp, biber -, makeWrapper +, makeWrapper, shortenPerlShebang }: # Useful resource covering build options: @@ -292,6 +292,7 @@ latexindent = perlPackages.buildPerlPackage rec { outputs = [ "out" ]; + nativeBuildInputs = stdenv.lib.optional stdenv.isDarwin shortenPerlShebang; propagatedBuildInputs = with perlPackages; [ FileHomeDir LogDispatch LogLog4perl UnicodeLineBreak YAMLTiny ]; postPatch = '' @@ -308,6 +309,8 @@ latexindent = perlPackages.buildPerlPackage rec { install -D ./scripts/latexindent/latexindent.pl "$out"/bin/latexindent mkdir -p "$out"/${perl.libPrefix} cp -r ./scripts/latexindent/LatexIndent "$out"/${perl.libPrefix}/ + '' + stdenv.lib.optionalString stdenv.isDarwin '' + shortenPerlShebang "$out"/bin/latexindent ''; }; diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 0e4cf55cf61c..83ff4350e195 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -384,6 +384,10 @@ in setupSystemdUnits = callPackage ../build-support/setup-systemd-units.nix { }; + shortenPerlShebang = makeSetupHook + { deps = [ dieHook ]; } + ../build-support/setup-hooks/shorten-perl-shebang.sh; + singularity-tools = callPackage ../build-support/singularity-tools { }; srcOnly = args: callPackage ../build-support/src-only args; diff --git a/pkgs/top-level/perl-packages.nix b/pkgs/top-level/perl-packages.nix index 9ff9045600be..44fa8639516e 100644 --- a/pkgs/top-level/perl-packages.nix +++ b/pkgs/top-level/perl-packages.nix @@ -6,7 +6,7 @@ be almost as much code as the function itself. */ {config, pkgs, fetchurl, fetchFromGitHub, stdenv, gnused, perl, overrides, - buildPerl}: + buildPerl, shortenPerlShebang}: # cpan2nix assumes that perl-packages.nix will be used only with perl 5.28.2 or above assert stdenv.lib.versionAtLeast perl.version "5.28.2"; @@ -89,22 +89,29 @@ let ack = buildPerlPackage { pname = "ack"; version = "3.0.2"; + src = fetchurl { url = mirror://cpan/authors/id/P/PE/PETDANCE/ack-v3.0.2.tar.gz; sha256 = "0a4mriclnmwvm8rn9crkfr00qjy6ffgf0b0bg0qz46drpnyv7d33"; }; + outputs = ["out" "man"]; - # use gnused so that the preCheck command passes - buildInputs = stdenv.lib.optional stdenv.isDarwin gnused; + + nativeBuildInputs = stdenv.lib.optional stdenv.isDarwin shortenPerlShebang; propagatedBuildInputs = [ FileNext ]; + postInstall = stdenv.lib.optionalString stdenv.isDarwin '' + shortenPerlShebang $out/bin/ack + ''; + + # tests fails on nixos and hydra because of different purity issues + doCheck = false; + meta = with stdenv.lib; { description = "A grep-like tool tailored to working with large trees of source code"; homepage = https://beyondgrep.com; license = licenses.artistic2; maintainers = with maintainers; [ lovek323 ]; }; - # tests fails on nixos and hydra because of different purity issues - doCheck = false; }; AlgorithmAnnotate = buildPerlPackage { @@ -8855,6 +8862,11 @@ let sha256 = "0d8v48y94z8maxkmw1rv7v9m0jg2dc8xbp581njb6yhr7abwqdv3"; }; + nativeBuildInputs = stdenv.lib.optional stdenv.isDarwin shortenPerlShebang; + postInstall = stdenv.lib.optionalString stdenv.isDarwin '' + shortenPerlShebang $out/bin/exiftool + ''; + meta = with stdenv.lib; { description = "A tool to read, write and edit EXIF meta information"; homepage = https://www.sno.phy.queensu.ca/~phil/exiftool/; @@ -19282,12 +19294,16 @@ let sha256 = "15xyrwv08fw8jmpydwzks26ipxnzliwddgyjcfqiaj0p7lwlhmx1"; }; + nativeBuildInputs = stdenv.lib.optional stdenv.isDarwin shortenPerlShebang; propagatedBuildInputs = [ LWP LWPProtocolHttps DataDump JSON ]; + postInstall = stdenv.lib.optionalString stdenv.isDarwin '' + shortenPerlShebang $out/bin/youtube-viewer + ''; meta = { description = "A lightweight application for searching and streaming videos from YouTube";