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";