nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 stdenv,
3 fetchurl,
4 fetchFromGitHub,
5 buildPackages,
6 lib,
7 self,
8 version,
9 sha256,
10 pkgsBuildBuild,
11 pkgsBuildHost,
12 pkgsBuildTarget,
13 pkgsHostHost,
14 pkgsTargetTarget,
15 zlib,
16 config,
17 passthruFun,
18 perlAttr ? "perl${lib.versions.major version}",
19 enableThreading ? true,
20 coreutils,
21 makeWrapper,
22 enableCrypt ? true,
23 libxcrypt ? null,
24 overrides ? config.perlPackageOverrides or (p: { }), # TODO: (self: super: {}) like in python
25}@inputs:
26
27# Note: this package is used for bootstrapping fetchurl, and thus
28# cannot use fetchpatch! All mutable patches (generated by GitHub or
29# cgit) that are needed here should be included directly in Nixpkgs as
30# files.
31
32assert (enableCrypt -> (libxcrypt != null));
33
34let
35 crossCompiling = !(stdenv.buildPlatform.canExecute stdenv.hostPlatform);
36 commonPatches = [
37 # Do not look in /usr etc. for dependencies.
38 ./no-sys-dirs.patch
39 ]
40
41 # Fix build on Solaris on x86_64
42 # See also:
43 # * perl tracker: https://github.com/Perl/perl5/issues/9669
44 # * netbsd tracker: https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=44999
45 ++ lib.optional stdenv.hostPlatform.isSunOS ./ld-shared.patch
46
47 # Don't pass -no-cpp-precomp, even if it is "supported"
48 #
49 # cpp-precomp is a relic from NeXT days, when there was a separate
50 # cpp preprocessor that produced "precompiled header files" (hence
51 # cpp-precomp) - binary files containing information from .h files, that
52 # sped up the compilation slightly.
53 #
54 # However, cpp-precomp was semi-broken and didn't accept a lot of valid
55 # code, so there was a way to disable it (-no-cpp-precomp).
56 #
57 # This flag seems to have lost all relevance back in 2002 or so, when
58 # cpp-precomp stopped being used; gcc dropped it completely in 4.8 (and
59 # now errors out if you pass it), but for some reason clang still accepts
60 # it (but it's a no-op). This means that if you compile perl with clang,
61 # it will think that this flag is still supported, and it can cause issues
62 # if you compile c code from perl:
63 # https://trac.macports.org/ticket/38913
64 #
65 # More info about -no-cpp-precomp: https://www.mistys-internet.website/blog/blog/2013/10/19/no-cpp-precomp-the-compiler-flag-that-time-forgot
66 #
67 # See also: https://github.com/NixOS/nixpkgs/pull/1160
68 ++ lib.optional stdenv.hostPlatform.isDarwin ./cpp-precomp.patch
69
70 # Miniperl is a "bootstrap" perl which doesn't support dynamic loading, among other things.
71 # It is used to build modules for the "final" perl.
72 #
73 # This patch enables more modules to be loaded with miniperl (mostly by
74 # removing dynamically loaded libraries and using perl builtins instead),
75 # which is needed during cross-compilation because the bootstrapping process
76 # has more stages than the default build and doesn't get to the main perl
77 # binary as early.
78 #
79 # Some more details: https://arsv.github.io/perl-cross/modules.html
80 ++ lib.optional crossCompiling ./cross.patch;
81
82 libc = if stdenv.cc.libc or null != null then stdenv.cc.libc else "/usr";
83 libcInc = lib.getDev libc;
84 libcLib = lib.getLib libc;
85in
86
87stdenv.mkDerivation (
88 finalAttrs:
89 {
90 inherit version;
91 pname = "perl";
92
93 src = fetchurl {
94 url = "mirror://cpan/src/5.0/perl-${version}.tar.gz";
95 inherit sha256;
96 };
97
98 strictDeps = true;
99 # TODO: Add a "dev" output containing the header files.
100 outputs = [
101 "out"
102 "man"
103 "devdoc"
104 ]
105 ++ lib.optional crossCompiling "mini";
106 setOutputFlags = false;
107
108 # On FreeBSD, if Perl is built with threads support, having
109 # libxcrypt available will result in a build failure, because
110 # perl.h will get conflicting definitions of struct crypt_data
111 # from libc's unistd.h and libxcrypt's crypt.h.
112 #
113 # FreeBSD Ports has the same issue building the perl port if
114 # the libxcrypt port has been installed.
115 #
116 # Without libxcrypt, Perl will still find FreeBSD's crypt functions.
117 propagatedBuildInputs = lib.optional (enableCrypt && !stdenv.hostPlatform.isFreeBSD) libxcrypt;
118
119 disallowedReferences = [ stdenv.cc ];
120
121 patches = commonPatches;
122
123 # This is not done for native builds because pwd may need to come from
124 # bootstrap tools when building bootstrap perl.
125 postPatch =
126 (
127 if crossCompiling then
128 ''
129 substituteInPlace dist/PathTools/Cwd.pm \
130 --replace "/bin/pwd" '${coreutils}/bin/pwd'
131 substituteInPlace cnf/configure_tool.sh --replace "cc -E -P" "cc -E"
132 ''
133 else
134 ''
135 substituteInPlace dist/PathTools/Cwd.pm \
136 --replace "/bin/pwd" "$(type -P pwd)"
137 ''
138 )
139 +
140 # Perl's build system uses the src variable, and its value may end up in
141 # the output in some cases (when cross-compiling)
142 ''
143 unset src
144 '';
145
146 # Build a thread-safe Perl with a dynamic libperl.so. We need the
147 # "installstyle" option to ensure that modules are put under
148 # $out/lib/perl5 - this is the general default, but because $out
149 # contains the string "perl", Configure would select $out/lib.
150 # Miniperl needs -lm. perl needs -lrt.
151 configureFlags =
152 (
153 if crossCompiling then
154 [
155 "-Dlibpth=\"\""
156 "-Dglibpth=\"\""
157 "-Ddefault_inc_excludes_dot"
158 # https://github.com/arsv/perl-cross/issues/158
159 "-Dd_gnulibc=define"
160 ]
161 else
162 (
163 [
164 "-de"
165 "-Dprefix=${placeholder "out"}"
166 "-Dman1dir=${placeholder "out"}/share/man/man1"
167 "-Dman3dir=${placeholder "out"}/share/man/man3"
168 ]
169 ++ (
170 if (stdenv.cc.targetPrefix != "") then
171 [
172 "-Dcc=${stdenv.cc.targetPrefix}cc"
173 "-Dnm=${stdenv.cc.targetPrefix}nm"
174 "-Dar=${stdenv.cc.targetPrefix}ar"
175 ]
176 else
177 [
178 "-Dcc=cc"
179 "-Duseshrplib"
180 ]
181 )
182 )
183 )
184 ++ [
185 "-Uinstallusrbinperl"
186 "-Dinstallstyle=lib/perl5"
187 "-Dlocincpth=${libcInc}/include"
188 "-Dloclibpth=${libcLib}/lib"
189 "-Accflags=-D_GNU_SOURCE"
190 ]
191 ++ lib.optional stdenv.hostPlatform.isStatic "-Uusedl"
192 ++ lib.optionals ((builtins.match ''5\.[0-9]*[13579]\..+'' version) != null) [
193 "-Dusedevel"
194 "-Uversiononly"
195 ]
196 ++ lib.optional stdenv.hostPlatform.isSunOS "-Dcc=gcc"
197 ++ lib.optional enableThreading "-Dusethreads"
198 ++ lib.optional (!enableCrypt) "-A clear:d_crypt_r"
199 ++ lib.optionals (stdenv.hostPlatform.isFreeBSD && crossCompiling && enableCrypt) [
200 # https://github.com/Perl/perl5/issues/22295
201 # configure cannot figure out that we have crypt automatically, but we really do
202 "-Dd_crypt"
203 ];
204
205 configureScript = lib.optionalString (!crossCompiling) "${stdenv.shell} ./Configure";
206
207 # !canExecute cross uses miniperl which doesn't have this
208 postConfigure =
209 lib.optionalString (!crossCompiling && stdenv.cc.targetPrefix != "") ''
210 substituteInPlace Makefile \
211 --replace-fail "AR = ar" "AR = ${stdenv.cc.targetPrefix}ar"
212 ''
213 + lib.optionalString crossCompiling ''
214 substituteInPlace miniperl_top --replace-fail '-I$top/lib' '-I$top/cpan/JSON-PP/lib -I$top/cpan/CPAN-Meta-YAML/lib -I$top/lib'
215 '';
216
217 dontAddStaticConfigureFlags = true;
218
219 dontAddPrefix = !crossCompiling;
220
221 enableParallelBuilding = true;
222
223 # perl includes the build date, the uname of the build system and the
224 # username of the build user in some files.
225 # We override these to make it build deterministically.
226 # other distro solutions
227 # https://github.com/bmwiedemann/openSUSE/blob/master/packages/p/perl/perl-reproducible.patch
228 # https://github.com/archlinux/svntogit-packages/blob/packages/perl/trunk/config.over
229 # https://salsa.debian.org/perl-team/interpreter/perl/blob/debian-5.26/debian/config.over
230 # A ticket has been opened upstream to possibly clean some of this up: https://rt.perl.org/Public/Bug/Display.html?id=133452
231 preConfigure = ''
232 cat > config.over <<EOF
233 ${lib.optionalString (
234 stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isGnu
235 ) ''osvers="gnulinux"''}
236 myuname="nixpkgs"
237 myhostname="nixpkgs"
238 cf_by="nixpkgs"
239 cf_time="$(date -d "@$SOURCE_DATE_EPOCH")"
240 EOF
241
242 # Compress::Raw::Zlib should use our zlib package instead of the one
243 # included with the distribution
244 cat > ./cpan/Compress-Raw-Zlib/config.in <<EOF
245 BUILD_ZLIB = False
246 INCLUDE = ${zlib.dev}/include
247 LIB = ${zlib.out}/lib
248 OLD_ZLIB = False
249 GZIP_OS_CODE = AUTO_DETECT
250 USE_ZLIB_NG = False
251 ''
252 + lib.optionalString (lib.versionAtLeast version "5.40.0") ''
253 ZLIB_INCLUDE = ${zlib.dev}/include
254 ZLIB_LIB = ${zlib.out}/lib
255 ''
256 + ''
257 EOF
258 ''
259 + lib.optionalString stdenv.hostPlatform.isDarwin ''
260 substituteInPlace hints/darwin.sh --replace "env MACOSX_DEPLOYMENT_TARGET=10.3" ""
261 ''
262 + lib.optionalString (!enableThreading) ''
263 # We need to do this because the bootstrap doesn't have a static libpthread
264 sed -i 's,\(libswanted.*\)pthread,\1,g' Configure
265 '';
266
267 # Default perl does not support --host= & co.
268 configurePlatforms = [ ];
269
270 setupHook = ./setup-hook.sh;
271
272 env = {
273 # https://github.com/llvm/llvm-project/issues/152241
274 NIX_CFLAGS_COMPILE = lib.optionalString (
275 stdenv.hasCC && stdenv.cc.isClang && lib.versionAtLeast stdenv.cc.version "21"
276 ) "-fno-strict-aliasing";
277 };
278
279 # copied from python
280 passthru =
281 let
282 # When we override the interpreter we also need to override the spliced versions of the interpreter
283 inputs' = lib.filterAttrs (n: v: !lib.isDerivation v && n != "passthruFun") inputs;
284 override =
285 attr:
286 let
287 perl = attr.override (inputs' // { self = perl; });
288 in
289 perl;
290 in
291 passthruFun rec {
292 inherit self perlAttr;
293 inherit overrides;
294 perlOnBuildForBuild = override pkgsBuildBuild.${perlAttr};
295 perlOnBuildForHost = override pkgsBuildHost.${perlAttr};
296 perlOnBuildForTarget = override pkgsBuildTarget.${perlAttr};
297 perlOnHostForHost = override pkgsHostHost.${perlAttr};
298 perlOnTargetForTarget =
299 if lib.hasAttr perlAttr pkgsTargetTarget then (override pkgsTargetTarget.${perlAttr}) else { };
300
301 tests.withCheck = finalAttrs.finalPackage.overrideAttrs (_: {
302 preCheck = ''
303 # Weird test failure, can't even understand what it's about
304 # Disable the test for now
305 sed -i '/ext\/Pod-Html\/t\/htmldir3.*/d' MANIFEST
306 '';
307 doCheck = true;
308 });
309 };
310
311 # TODO: it seems like absolute paths to some coreutils is required.
312 postInstall = ''
313 # Remove dependency between "out" and "man" outputs.
314 rm "$out"/lib/perl5/*/*/.packlist
315
316 # Remove dependencies on glibc and gcc
317 sed "/ *libpth =>/c libpth => ' '," \
318 -i "$out"/lib/perl5/*/*/Config.pm
319 # TODO: removing those paths would be cleaner than overwriting with nonsense.
320 substituteInPlace "$out"/lib/perl5/*/*/Config_heavy.pl \
321 --replace "${libcInc}" /no-such-path \
322 --replace "${if stdenv.hasCC then stdenv.cc else "/no-such-path"}" /no-such-path \
323 --replace "${
324 if stdenv.hasCC && stdenv.cc.cc != null then stdenv.cc.cc else "/no-such-path"
325 }" /no-such-path \
326 --replace "${
327 if stdenv.hasCC && stdenv.cc.fallback_sdk or null != null then
328 stdenv.cc.fallback_sdk
329 else
330 "/no-such-path"
331 }" /no-such-path \
332 --replace "$man" /no-such-path
333 ''
334 + lib.optionalString crossCompiling ''
335 mkdir -p $mini/lib/perl5/cross_perl/${version}
336 for dir in cnf/{stub,cpan}; do
337 cp -r $dir/* $mini/lib/perl5/cross_perl/${version}
338 done
339
340 mkdir -p $mini/bin
341 install -m755 miniperl $mini/bin/perl
342
343 export runtimeArch="$(ls $out/lib/perl5/site_perl/${version})"
344 # wrapProgram should use a runtime-native SHELL by default, but
345 # it actually uses a buildtime-native one. If we ever fix that,
346 # we'll need to fix this to use a buildtime-native one.
347 #
348 # Adding the arch-specific directory is morally incorrect, as
349 # miniperl can't load the native modules there. However, it can
350 # (and sometimes needs to) load and run some of the pure perl
351 # code there, so we add it anyway. When needed, stubs can be put
352 # into $mini/lib/perl5/cross_perl/${version}.
353 wrapProgram $mini/bin/perl --prefix PERL5LIB : \
354 "$mini/lib/perl5/cross_perl/${version}:$out/lib/perl5/${version}:$out/lib/perl5/${version}/$runtimeArch"
355 ''; # */
356
357 meta = {
358 homepage = "https://www.perl.org/";
359 description = "Standard implementation of the Perl 5 programming language";
360 license = lib.licenses.artistic1;
361 maintainers = [ ];
362 teams = [ lib.teams.perl ];
363 platforms = lib.platforms.all;
364 priority = 6; # in `buildEnv' (including the one inside `perl.withPackages') the library files will have priority over files in `perl`
365 mainProgram = "perl";
366 };
367 }
368 // lib.optionalAttrs crossCompiling rec {
369 crossVersion = "1.6.4";
370
371 perl-cross-src = fetchFromGitHub {
372 name = "perl-cross-${crossVersion}";
373 owner = "arsv";
374 repo = "perl-cross";
375 rev = crossVersion;
376 hash = "sha256-Qcysy7f887XHlq23iE5U92PhxDhpgaluITZBSdcc9Ck=";
377 };
378 patches = commonPatches ++ [
379 # fixes build failure due to missing d_fdopendir/HAS_FDOPENDIR configure option
380 # https://github.com/arsv/perl-cross/pull/159
381 ./cross-fdopendir.patch
382 ];
383
384 depsBuildBuild = [
385 buildPackages.stdenv.cc
386 makeWrapper
387 ];
388
389 postUnpack = ''
390 unpackFile ${perl-cross-src}
391 chmod -R u+w ${perl-cross-src.name}
392 cp -R ${perl-cross-src.name}/* perl-${version}/
393 '';
394
395 configurePlatforms = [
396 "build"
397 "host"
398 "target"
399 ];
400
401 # TODO merge setup hooks
402 setupHook = ./setup-hook-cross.sh;
403 }
404)