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