python3Packages.orjson: Disable failing tests on 32 bit
[NixPkgs.git] / pkgs / development / interpreters / ruby / default.nix
blobdc7594da17d92965409a16affba48ebbb9ca0d83
1 { stdenv, buildPackages, lib
2 , fetchurl, fetchpatch, fetchFromSavannah, fetchFromGitHub
3 , zlib, gdbm, ncurses, readline, groff, libyaml, libffi, jemalloc, autoreconfHook, bison
4 , autoconf, libiconv, libobjc, libunwind, Foundation
5 , buildEnv, bundler, bundix
6 , makeWrapper, buildRubyGem, defaultGemConfig, removeReferencesTo
7 , openssl, openssl_1_1
8 } @ args:
10 let
11   op = lib.optional;
12   ops = lib.optionals;
13   opString = lib.optionalString;
14   patchSet = import ./rvm-patchsets.nix { inherit fetchFromGitHub; };
15   config = import ./config.nix { inherit fetchFromSavannah; };
16   rubygems = import ./rubygems { inherit stdenv lib fetchurl; };
18   # Contains the ruby version heuristics
19   rubyVersion = import ./ruby-version.nix { inherit lib; };
21   generic = { version, sha256 }: let
22     ver = version;
23     atLeast30 = lib.versionAtLeast ver.majMin "3.0";
24     self = lib.makeOverridable (
25       { stdenv, buildPackages, lib
26       , fetchurl, fetchpatch, fetchFromSavannah, fetchFromGitHub
27       , useRailsExpress ? true
28       , rubygemsSupport ? true
29       , zlib, zlibSupport ? true
30       , openssl, openssl_1_1, opensslSupport ? true
31       , gdbm, gdbmSupport ? true
32       , ncurses, readline, cursesSupport ? true
33       , groff, docSupport ? true
34       , libyaml, yamlSupport ? true
35       , libffi, fiddleSupport ? true
36       , jemalloc, jemallocSupport ? false
37       # By default, ruby has 3 observed references to stdenv.cc:
38       #
39       # - If you run:
40       #     ruby -e "puts RbConfig::CONFIG['configure_args']"
41       # - In:
42       #     $out/${passthru.libPath}/${stdenv.hostPlatform.system}/rbconfig.rb
43       #   Or (usually):
44       #     $(nix-build -A ruby)/lib/ruby/2.6.0/x86_64-linux/rbconfig.rb
45       # - In $out/lib/libruby.so and/or $out/lib/libruby.dylib
46       , removeReferencesTo, jitSupport ? false
47       , autoreconfHook, bison, autoconf
48       , buildEnv, bundler, bundix
49       , libiconv, libobjc, libunwind, Foundation
50       , makeWrapper, buildRubyGem, defaultGemConfig
51       , baseRuby ? buildPackages.ruby_3_1.override {
52           useRailsExpress = false;
53           docSupport = false;
54           rubygemsSupport = false;
55         }
56       , useBaseRuby ? stdenv.hostPlatform != stdenv.buildPlatform || useRailsExpress
57       }:
58       stdenv.mkDerivation rec {
59         pname = "ruby";
60         inherit version;
62         src = fetchurl {
63           url = "https://cache.ruby-lang.org/pub/ruby/${ver.majMin}/ruby-${ver}.tar.gz";
64           inherit sha256;
65         };
67         # Have `configure' avoid `/usr/bin/nroff' in non-chroot builds.
68         NROFF = if docSupport then "${groff}/bin/nroff" else null;
70         outputs = [ "out" ] ++ lib.optional docSupport "devdoc";
72         nativeBuildInputs = [ autoreconfHook bison ]
73           ++ (op docSupport groff)
74           ++ op useBaseRuby baseRuby;
75         buildInputs = [ autoconf ]
76           ++ (op fiddleSupport libffi)
77           ++ (ops cursesSupport [ ncurses readline ])
78           ++ (op zlibSupport zlib)
79           ++ (op (lib.versionOlder ver.majMin "3.0" && opensslSupport) openssl_1_1)
80           ++ (op (atLeast30 && opensslSupport) openssl_1_1)
81           ++ (op gdbmSupport gdbm)
82           ++ (op yamlSupport libyaml)
83           # Looks like ruby fails to build on darwin without readline even if curses
84           # support is not enabled, so add readline to the build inputs if curses
85           # support is disabled (if it's enabled, we already have it) and we're
86           # running on darwin
87           ++ op (!cursesSupport && stdenv.isDarwin) readline
88           ++ ops stdenv.isDarwin [ libiconv libobjc libunwind Foundation ];
89         propagatedBuildInputs = op jemallocSupport jemalloc;
91         enableParallelBuilding = true;
93         patches =
94           (import ./patchsets.nix {
95             inherit patchSet useRailsExpress ops fetchpatch;
96             patchLevel = ver.patchLevel;
97           }).${ver.majMinTiny}
98           ++ op (lib.versionOlder ver.majMin "3.1") ./do-not-regenerate-revision.h.patch
99           ++ op (atLeast30 && useBaseRuby) ./do-not-update-gems-baseruby.patch
100           ++ ops (!atLeast30 && rubygemsSupport) [
101             # We upgrade rubygems to a version that isn't compatible with the
102             # ruby 2.7 installer. Backport the upstream fix.
103             ./rbinstall-new-rubygems-compat.patch
105             # Ruby prior to 3.0 has a bug the installer (tools/rbinstall.rb) but
106             # the resulting error was swallowed. Newer rubygems no longer swallows
107             # this error. We upgrade rubygems when rubygemsSupport is enabled, so
108             # we have to fix this bug to prevent the install step from failing.
109             # See https://github.com/ruby/ruby/pull/2930
110             (fetchpatch {
111               url = "https://github.com/ruby/ruby/commit/261d8dd20afd26feb05f00a560abd99227269c1c.patch";
112               sha256 = "0wrii25cxcz2v8bgkrf7ibcanjlxwclzhayin578bf0qydxdm9qy";
113             })
114           ];
116         postUnpack = opString rubygemsSupport ''
117           rm -rf $sourceRoot/{lib,test}/rubygems*
118           cp -r ${rubygems}/lib/rubygems* $sourceRoot/lib
119           cp -r ${rubygems}/test/rubygems $sourceRoot/test
120         '';
122         postPatch = ''
123           sed -i configure.ac -e '/config.guess/d'
124           cp --remove-destination ${config}/config.guess tool/
125           cp --remove-destination ${config}/config.sub tool/
126         '' + opString (!atLeast30) ''
127           # Make the build reproducible for ruby <= 2.7
128           # See https://github.com/ruby/io-console/commit/679a941d05d869f5e575730f6581c027203b7b26#diff-d8422f096931c58d4463e2489f62a228b0f24f0492950ba88c8c89a0d741cfe6
129           sed -i ext/io/console/io-console.gemspec -e '/s\.date/d'
130         '';
132         configureFlags = [
133           (lib.enableFeature (!stdenv.hostPlatform.isStatic) "shared")
134           (lib.enableFeature true "pthread")
135           (lib.withFeatureAs true "soname" "ruby-${version}")
136           (lib.withFeatureAs useBaseRuby "baseruby" "${baseRuby}/bin/ruby")
137           (lib.enableFeature jitSupport "jit-support")
138           (lib.enableFeature docSupport "install-doc")
139           (lib.withFeature jemallocSupport "jemalloc")
140           (lib.withFeatureAs docSupport "ridir" "${placeholder "devdoc"}/share/ri")
141           # ruby enables -O3 for gcc, however our compiler hardening wrapper
142           # overrides that by enabling `-O2` which is the minimum optimization
143           # needed for `_FORTIFY_SOURCE`.
144         ] ++ lib.optional stdenv.cc.isGNU "CFLAGS=-O3" ++ [
145         ] ++ ops stdenv.isDarwin [
146           # on darwin, we have /usr/include/tk.h -- so the configure script detects
147           # that tk is installed
148           "--with-out-ext=tk"
149           # on yosemite, "generating encdb.h" will hang for a very long time without this flag
150           "--with-setjmp-type=setjmp"
151         ];
153         preConfigure = opString docSupport ''
154           # rdoc creates XDG_DATA_DIR (defaulting to $HOME/.local/share) even if
155           # it's not going to be used.
156           export HOME=$TMPDIR
157         '';
159         # fails with "16993 tests, 2229489 assertions, 105 failures, 14 errors, 89 skips"
160         # mostly TZ- and patch-related tests
161         # TZ- failures are caused by nix sandboxing, I didn't investigate others
162         doCheck = false;
164         preInstall = ''
165           # Ruby installs gems here itself now.
166           mkdir -pv "$out/${passthru.gemPath}"
167           export GEM_HOME="$out/${passthru.gemPath}"
168         '';
170         installFlags = lib.optional docSupport "install-doc";
171         # Bundler tries to create this directory
172         postInstall = ''
173           rbConfig=$(find $out/lib/ruby -name rbconfig.rb)
174           # Remove references to the build environment from the closure
175           sed -i '/^  CONFIG\["\(BASERUBY\|SHELL\|GREP\|EGREP\|MKDIR_P\|MAKEDIRS\|INSTALL\)"\]/d' $rbConfig
176           # Remove unnecessary groff reference from runtime closure, since it's big
177           sed -i '/NROFF/d' $rbConfig
178           ${
179             lib.optionalString (!jitSupport) ''
180               # Get rid of the CC runtime dependency
181               ${removeReferencesTo}/bin/remove-references-to \
182                 -t ${stdenv.cc} \
183                 $out/lib/libruby*
184               ${removeReferencesTo}/bin/remove-references-to \
185                 -t ${stdenv.cc} \
186                 $rbConfig
187               sed -i '/CC_VERSION_MESSAGE/d' $rbConfig
188             ''
189           }
190           # Remove unnecessary external intermediate files created by gems
191           extMakefiles=$(find $out/lib/ruby/gems -name Makefile)
192           for makefile in $extMakefiles; do
193             make -C "$(dirname "$makefile")" distclean
194           done
195           # Bundler tries to create this directory
196           mkdir -p $out/nix-support
197           cat > $out/nix-support/setup-hook <<EOF
198           addGemPath() {
199             addToSearchPath GEM_PATH \$1/${passthru.gemPath}
200           }
201           addRubyLibPath() {
202             addToSearchPath RUBYLIB \$1/lib/ruby/site_ruby
203             addToSearchPath RUBYLIB \$1/lib/ruby/site_ruby/${ver.libDir}
204             addToSearchPath RUBYLIB \$1/lib/ruby/site_ruby/${ver.libDir}/${stdenv.hostPlatform.system}
205           }
207           addEnvHooks "$hostOffset" addGemPath
208           addEnvHooks "$hostOffset" addRubyLibPath
209           EOF
210         '' + opString docSupport ''
211           # Prevent the docs from being included in the closure
212           sed -i "s|\$(DESTDIR)$devdoc|\$(datarootdir)/\$(RI_BASE_NAME)|" $rbConfig
213           sed -i "s|'--with-ridir=$devdoc/share/ri'||" $rbConfig
215           # Add rbconfig shim so ri can find docs
216           mkdir -p $devdoc/lib/ruby/site_ruby
217           cp ${./rbconfig.rb} $devdoc/lib/ruby/site_ruby/rbconfig.rb
218         '' + opString useBaseRuby ''
219           # Prevent the baseruby from being included in the closure.
220           ${removeReferencesTo}/bin/remove-references-to \
221             -t ${baseRuby} \
222             $rbConfig $out/lib/libruby*
223         '';
225         disallowedRequisites = op (!jitSupport) stdenv.cc.cc
226           ++ op useBaseRuby baseRuby;
228         meta = with lib; {
229           description = "An object-oriented language for quick and easy programming";
230           homepage    = "https://www.ruby-lang.org/";
231           license     = licenses.ruby;
232           maintainers = with maintainers; [ vrthra manveru marsam ];
233           platforms   = platforms.all;
234         };
236         passthru = rec {
237           version = ver;
238           rubyEngine = "ruby";
239           libPath = "lib/${rubyEngine}/${ver.libDir}";
240           gemPath = "lib/${rubyEngine}/gems/${ver.libDir}";
241           devEnv = import ./dev.nix {
242             inherit buildEnv bundler bundix;
243             ruby = self;
244           };
246           inherit (import ../../ruby-modules/with-packages {
247             inherit lib stdenv makeWrapper buildRubyGem buildEnv;
248             gemConfig = defaultGemConfig;
249             ruby = self;
250           }) withPackages gems;
252         } // lib.optionalAttrs useBaseRuby {
253           inherit baseRuby;
254         };
255       }
256     ) args; in self;
258 in {
259   mkRubyVersion = rubyVersion;
260   mkRuby = generic;
262   ruby_2_7 = generic {
263     version = rubyVersion "2" "7" "6" "";
264     sha256 = "042xrdk7hsv4072bayz3f8ffqh61i8zlhvck10nfshllq063n877";
265   };
267   ruby_3_0 = generic {
268     version = rubyVersion "3" "0" "4" "";
269     sha256 = "0avj4g3s2839b2y4m6pk8kid74r8nj7k0qm2rsdcwjzhg8h7rd3h";
270   };
272   ruby_3_1 = generic {
273     version = rubyVersion "3" "1" "2" "";
274     sha256 = "0gm84ipk6mrfw94852w5h7xxk2lqrxjbnlwb88svf0lz70933131";
275   };