nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{ stdenv, buildPackages, lib
2, fetchurl, fetchpatch, fetchFromSavannah, fetchFromGitHub
3, zlib, openssl, 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} @ args:
8
9let
10 op = lib.optional;
11 ops = lib.optionals;
12 opString = lib.optionalString;
13 patchSet = import ./rvm-patchsets.nix { inherit fetchFromGitHub; };
14 config = import ./config.nix { inherit fetchFromSavannah; };
15 rubygems = import ./rubygems { inherit stdenv lib fetchurl; };
16
17 # Contains the ruby version heuristics
18 rubyVersion = import ./ruby-version.nix { inherit lib; };
19
20 generic = { version, sha256 }: let
21 ver = version;
22 tag = ver.gitTag;
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, 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.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;
61
62 src = fetchurl {
63 url = "https://cache.ruby-lang.org/pub/ruby/${ver.majMin}/ruby-${ver}.tar.gz";
64 inherit sha256;
65 };
66
67 # Have `configure' avoid `/usr/bin/nroff' in non-chroot builds.
68 NROFF = if docSupport then "${groff}/bin/nroff" else null;
69
70 outputs = [ "out" ] ++ lib.optional docSupport "devdoc";
71
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 opensslSupport openssl)
80 ++ (op gdbmSupport gdbm)
81 ++ (op yamlSupport libyaml)
82 ++ (op jemallocSupport jemalloc)
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
90 enableParallelBuilding = true;
91
92 patches =
93 (import ./patchsets.nix {
94 inherit patchSet useRailsExpress ops fetchpatch;
95 patchLevel = ver.patchLevel;
96 }).${ver.majMinTiny}
97 ++ op (lib.versionOlder ver.majMin "3.1") ./do-not-regenerate-revision.h.patch
98 ++ op (atLeast30 && useBaseRuby) ./do-not-update-gems-baseruby.patch
99 ++ ops (!atLeast30 && rubygemsSupport) [
100 # We upgrade rubygems to a version that isn't compatible with the
101 # ruby 2.7 installer. Backport the upstream fix.
102 ./rbinstall-new-rubygems-compat.patch
103
104 # Ruby prior to 3.0 has a bug the installer (tools/rbinstall.rb) but
105 # the resulting error was swallowed. Newer rubygems no longer swallows
106 # this error. We upgrade rubygems when rubygemsSupport is enabled, so
107 # we have to fix this bug to prevent the install step from failing.
108 # See https://github.com/ruby/ruby/pull/2930
109 (fetchpatch {
110 url = "https://github.com/ruby/ruby/commit/261d8dd20afd26feb05f00a560abd99227269c1c.patch";
111 sha256 = "0wrii25cxcz2v8bgkrf7ibcanjlxwclzhayin578bf0qydxdm9qy";
112 })
113 ];
114
115 postUnpack = opString rubygemsSupport ''
116 rm -rf $sourceRoot/{lib,test}/rubygems*
117 cp -r ${rubygems}/lib/rubygems* $sourceRoot/lib
118 cp -r ${rubygems}/test/rubygems $sourceRoot/test
119 '';
120
121 postPatch = ''
122 sed -i configure.ac -e '/config.guess/d'
123 cp --remove-destination ${config}/config.guess tool/
124 cp --remove-destination ${config}/config.sub tool/
125 '' + opString (!atLeast30) ''
126 # Make the build reproducible for ruby <= 2.7
127 # See https://github.com/ruby/io-console/commit/679a941d05d869f5e575730f6581c027203b7b26#diff-d8422f096931c58d4463e2489f62a228b0f24f0492950ba88c8c89a0d741cfe6
128 sed -i ext/io/console/io-console.gemspec -e '/s\.date/d'
129 '';
130
131 configureFlags = [
132 (lib.enableFeature (!stdenv.hostPlatform.isStatic) "shared")
133 (lib.enableFeature true "pthread")
134 (lib.withFeatureAs true "soname" "ruby-${version}")
135 (lib.withFeatureAs useBaseRuby "baseruby" "${baseRuby}/bin/ruby")
136 (lib.enableFeature jitSupport "jit-support")
137 (lib.enableFeature docSupport "install-doc")
138 (lib.withFeature jemallocSupport "jemalloc")
139 (lib.withFeatureAs docSupport "ridir" "${placeholder "devdoc"}/share/ri")
140 ] ++ ops stdenv.isDarwin [
141 # on darwin, we have /usr/include/tk.h -- so the configure script detects
142 # that tk is installed
143 "--with-out-ext=tk"
144 # on yosemite, "generating encdb.h" will hang for a very long time without this flag
145 "--with-setjmp-type=setjmp"
146 ];
147
148 preConfigure = opString docSupport ''
149 # rdoc creates XDG_DATA_DIR (defaulting to $HOME/.local/share) even if
150 # it's not going to be used.
151 export HOME=$TMPDIR
152 '';
153
154 # fails with "16993 tests, 2229489 assertions, 105 failures, 14 errors, 89 skips"
155 # mostly TZ- and patch-related tests
156 # TZ- failures are caused by nix sandboxing, I didn't investigate others
157 doCheck = false;
158
159 preInstall = ''
160 # Ruby installs gems here itself now.
161 mkdir -pv "$out/${passthru.gemPath}"
162 export GEM_HOME="$out/${passthru.gemPath}"
163 '';
164
165 installFlags = lib.optional docSupport "install-doc";
166 # Bundler tries to create this directory
167 postInstall = ''
168 rbConfig=$(find $out/lib/ruby -name rbconfig.rb)
169 # Remove references to the build environment from the closure
170 sed -i '/^ CONFIG\["\(BASERUBY\|SHELL\|GREP\|EGREP\|MKDIR_P\|MAKEDIRS\|INSTALL\)"\]/d' $rbConfig
171 # Remove unnecessary groff reference from runtime closure, since it's big
172 sed -i '/NROFF/d' $rbConfig
173 ${
174 lib.optionalString (!jitSupport) ''
175 # Get rid of the CC runtime dependency
176 ${removeReferencesTo}/bin/remove-references-to \
177 -t ${stdenv.cc} \
178 $out/lib/libruby*
179 ${removeReferencesTo}/bin/remove-references-to \
180 -t ${stdenv.cc} \
181 $rbConfig
182 sed -i '/CC_VERSION_MESSAGE/d' $rbConfig
183 ''
184 }
185 # Remove unnecessary external intermediate files created by gems
186 extMakefiles=$(find $out/lib/ruby/gems -name Makefile)
187 for makefile in $extMakefiles; do
188 make -C "$(dirname "$makefile")" distclean
189 done
190 # Bundler tries to create this directory
191 mkdir -p $out/nix-support
192 cat > $out/nix-support/setup-hook <<EOF
193 addGemPath() {
194 addToSearchPath GEM_PATH \$1/${passthru.gemPath}
195 }
196 addRubyLibPath() {
197 addToSearchPath RUBYLIB \$1/lib/ruby/site_ruby
198 addToSearchPath RUBYLIB \$1/lib/ruby/site_ruby/${ver.libDir}
199 addToSearchPath RUBYLIB \$1/lib/ruby/site_ruby/${ver.libDir}/${stdenv.hostPlatform.system}
200 }
201
202 addEnvHooks "$hostOffset" addGemPath
203 addEnvHooks "$hostOffset" addRubyLibPath
204 EOF
205 '' + opString docSupport ''
206 # Prevent the docs from being included in the closure
207 sed -i "s|\$(DESTDIR)$devdoc|\$(datarootdir)/\$(RI_BASE_NAME)|" $rbConfig
208 sed -i "s|'--with-ridir=$devdoc/share/ri'||" $rbConfig
209
210 # Add rbconfig shim so ri can find docs
211 mkdir -p $devdoc/lib/ruby/site_ruby
212 cp ${./rbconfig.rb} $devdoc/lib/ruby/site_ruby/rbconfig.rb
213 '' + opString useBaseRuby ''
214 # Prevent the baseruby from being included in the closure.
215 ${removeReferencesTo}/bin/remove-references-to \
216 -t ${baseRuby} \
217 $rbConfig $out/lib/libruby*
218 '';
219
220 disallowedRequisites = op (!jitSupport) stdenv.cc.cc
221 ++ op useBaseRuby baseRuby;
222
223 meta = with lib; {
224 description = "The Ruby language";
225 homepage = "http://www.ruby-lang.org/en/";
226 license = licenses.ruby;
227 maintainers = with maintainers; [ vrthra manveru marsam ];
228 platforms = platforms.all;
229 };
230
231 passthru = rec {
232 version = ver;
233 rubyEngine = "ruby";
234 libPath = "lib/${rubyEngine}/${ver.libDir}";
235 gemPath = "lib/${rubyEngine}/gems/${ver.libDir}";
236 devEnv = import ./dev.nix {
237 inherit buildEnv bundler bundix;
238 ruby = self;
239 };
240
241 inherit (import ../../ruby-modules/with-packages {
242 inherit lib stdenv makeWrapper buildRubyGem buildEnv;
243 gemConfig = defaultGemConfig;
244 ruby = self;
245 }) withPackages gems;
246
247 # deprecated 2016-09-21
248 majorVersion = ver.major;
249 minorVersion = ver.minor;
250 teenyVersion = ver.tiny;
251 patchLevel = ver.patchLevel;
252 } // lib.optionalAttrs useBaseRuby {
253 inherit baseRuby;
254 };
255 }
256 ) args; in self;
257
258in {
259 ruby_2_7 = generic {
260 version = rubyVersion "2" "7" "6" "";
261 sha256 = "042xrdk7hsv4072bayz3f8ffqh61i8zlhvck10nfshllq063n877";
262 };
263
264 ruby_3_0 = generic {
265 version = rubyVersion "3" "0" "4" "";
266 sha256 = "0avj4g3s2839b2y4m6pk8kid74r8nj7k0qm2rsdcwjzhg8h7rd3h";
267 };
268
269 ruby_3_1 = generic {
270 version = rubyVersion "3" "1" "2" "";
271 sha256 = "0gm84ipk6mrfw94852w5h7xxk2lqrxjbnlwb88svf0lz70933131";
272 };
273}