1{ stdenv, buildPackages, lib
2, fetchurl, fetchpatch, fetchFromSavannah, fetchFromGitHub
3, zlib, openssl, gdbm, ncurses, readline, groff, libyaml, libffi, autoreconfHook, bison
4, autoconf, libiconv, libobjc, libunwind, Foundation
5, buildEnv, bundler, bundix
6} @ args:
7
8let
9 op = lib.optional;
10 ops = lib.optionals;
11 opString = lib.optionalString;
12 patchSet = import ./rvm-patchsets.nix { inherit fetchFromGitHub; };
13 config = import ./config.nix { inherit fetchFromSavannah; };
14 rubygemsSrc = import ./rubygems-src.nix { inherit fetchurl; };
15 rubygemsPatch = fetchpatch {
16 url = "https://github.com/zimbatm/rubygems/compare/v2.6.6...v2.6.6-nix.patch";
17 sha256 = "0297rdb1m6v75q8665ry9id1s74p9305dv32l95ssf198liaihhd";
18 };
19 unpackdir = obj:
20 lib.removeSuffix ".tgz"
21 (lib.removeSuffix ".tar.gz" obj.name);
22
23 # Contains the ruby version heuristics
24 rubyVersion = import ./ruby-version.nix { inherit lib; };
25
26 # Needed during postInstall
27 buildRuby =
28 if stdenv.hostPlatform == stdenv.buildPlatform
29 then "$out/bin/ruby"
30 else "${buildPackages.ruby}/bin/ruby";
31
32 generic = { version, sha256 }: let
33 ver = version;
34 tag = ver.gitTag;
35 isRuby25 = ver.majMin == "2.5";
36 baseruby = self.override { useRailsExpress = false; };
37 self = lib.makeOverridable (
38 { stdenv, buildPackages, lib
39 , fetchurl, fetchpatch, fetchFromSavannah, fetchFromGitHub
40 , useRailsExpress ? true
41 , zlib, zlibSupport ? true
42 , openssl, opensslSupport ? true
43 , gdbm, gdbmSupport ? true
44 , ncurses, readline, cursesSupport ? true
45 , groff, docSupport ? false
46 , libyaml, yamlSupport ? true
47 , libffi, fiddleSupport ? true
48 , autoreconfHook, bison, autoconf
49 , buildEnv, bundler, bundix
50 , libiconv, libobjc, libunwind, Foundation
51 }:
52 let rubySrc =
53 if useRailsExpress then fetchFromGitHub {
54 owner = "ruby";
55 repo = "ruby";
56 rev = tag;
57 sha256 = sha256.git;
58 } else fetchurl {
59 url = "http://cache.ruby-lang.org/pub/ruby/${ver.majMin}/ruby-${ver}.tar.gz";
60 sha256 = sha256.src;
61 };
62 in
63 stdenv.mkDerivation rec {
64 name = "ruby-${version}";
65
66 srcs = [ rubySrc rubygemsSrc ];
67 sourceRoot =
68 if useRailsExpress then
69 rubySrc.name
70 else
71 unpackdir rubySrc;
72
73 # Have `configure' avoid `/usr/bin/nroff' in non-chroot builds.
74 NROFF = if docSupport then "${groff}/bin/nroff" else null;
75
76 nativeBuildInputs =
77 ops useRailsExpress [ autoreconfHook bison ]
78 ++ ops (stdenv.buildPlatform != stdenv.hostPlatform) [
79 buildPackages.ruby
80 ];
81 buildInputs =
82 (op fiddleSupport libffi)
83 ++ (ops cursesSupport [ ncurses readline ])
84 ++ (op docSupport groff)
85 ++ (op zlibSupport zlib)
86 ++ (op opensslSupport openssl)
87 ++ (op gdbmSupport gdbm)
88 ++ (op yamlSupport libyaml)
89 ++ (op isRuby25 autoconf)
90 # Looks like ruby fails to build on darwin without readline even if curses
91 # support is not enabled, so add readline to the build inputs if curses
92 # support is disabled (if it's enabled, we already have it) and we're
93 # running on darwin
94 ++ op (!cursesSupport && stdenv.isDarwin) readline
95 ++ ops stdenv.isDarwin [ libiconv libobjc libunwind Foundation ];
96
97 enableParallelBuilding = true;
98
99 patches =
100 (import ./patchsets.nix {
101 inherit patchSet useRailsExpress ops;
102 patchLevel = ver.patchLevel;
103 })."${ver.majMinTiny}";
104
105 postUnpack = ''
106 cp -r ${unpackdir rubygemsSrc} ${sourceRoot}/rubygems
107 pushd ${sourceRoot}/rubygems
108 patch -p1 < ${rubygemsPatch}
109 popd
110 '';
111
112 postPatch = if isRuby25 then ''
113 sed -i configure.ac -e '/config.guess/d'
114 cp ${config}/config.guess tool/
115 cp ${config}/config.sub tool/
116 ''
117 else opString useRailsExpress ''
118 sed -i configure.in -e '/config.guess/d'
119 cp ${config}/config.guess tool/
120 cp ${config}/config.sub tool/
121 '';
122
123 configureFlags = ["--enable-shared" "--enable-pthread"]
124 ++ op useRailsExpress "--with-baseruby=${baseruby}/bin/ruby"
125 ++ op (!docSupport) "--disable-install-doc"
126 ++ ops stdenv.isDarwin [
127 # on darwin, we have /usr/include/tk.h -- so the configure script detects
128 # that tk is installed
129 "--with-out-ext=tk"
130 # on yosemite, "generating encdb.h" will hang for a very long time without this flag
131 "--with-setjmp-type=setjmp"
132 ]
133 ++ op (stdenv.hostPlatform != stdenv.buildPlatform)
134 "--with-baseruby=${buildRuby}";
135
136 # fails with "16993 tests, 2229489 assertions, 105 failures, 14 errors, 89 skips"
137 # mostly TZ- and patch-related tests
138 # TZ- failures are caused by nix sandboxing, I didn't investigate others
139 doCheck = false;
140
141 preInstall = ''
142 # Ruby installs gems here itself now.
143 mkdir -pv "$out/${passthru.gemPath}"
144 export GEM_HOME="$out/${passthru.gemPath}"
145 '';
146
147 installFlags = stdenv.lib.optionalString docSupport "install-doc";
148 # Bundler tries to create this directory
149 postInstall = ''
150 # Update rubygems
151 pushd rubygems
152 ${buildRuby} setup.rb
153 popd
154
155 # Remove unnecessary groff reference from runtime closure, since it's big
156 sed -i '/NROFF/d' $out/lib/ruby/*/*/rbconfig.rb
157
158 # Bundler tries to create this directory
159 mkdir -p $out/nix-support
160 cat > $out/nix-support/setup-hook <<EOF
161 addGemPath() {
162 addToSearchPath GEM_PATH \$1/${passthru.gemPath}
163 }
164
165 addEnvHooks "$hostOffset" addGemPath
166 EOF
167 '' + opString useRailsExpress ''
168 rbConfig=$(find $out/lib/ruby -name rbconfig.rb)
169
170 # Prevent the baseruby from being included in the closure.
171 sed -i '/^ CONFIG\["BASERUBY"\]/d' $rbConfig
172 sed -i "s|'--with-baseruby=${baseruby}/bin/ruby'||" $rbConfig
173 '';
174
175 meta = with stdenv.lib; {
176 description = "The Ruby language";
177 homepage = http://www.ruby-lang.org/en/;
178 license = licenses.ruby;
179 maintainers = with maintainers; [ vrthra manveru ];
180 platforms = platforms.all;
181 };
182
183 passthru = rec {
184 version = ver;
185 rubyEngine = "ruby";
186 baseRuby = baseruby;
187 libPath = "lib/${rubyEngine}/${ver.libDir}";
188 gemPath = "lib/${rubyEngine}/gems/${ver.libDir}";
189 devEnv = import ./dev.nix {
190 inherit buildEnv bundler bundix;
191 ruby = self;
192 };
193
194 # deprecated 2016-09-21
195 majorVersion = ver.major;
196 minorVersion = ver.minor;
197 teenyVersion = ver.tiny;
198 patchLevel = ver.patchLevel;
199 };
200 }
201 ) args; in self;
202
203in {
204 ruby_2_3 = generic {
205 version = rubyVersion "2" "3" "7" "";
206 sha256 = {
207 src = "0zvx5kdp1frjs9n95n7ba7dy0alax33wi3nj8034m3ppvnf39k9m";
208 git = "11wbzw2ywwfnvlkg3qjg0as2pzk5zyk63y2iis42d91lg1l2flrk";
209 };
210 };
211
212 ruby_2_4 = generic {
213 version = rubyVersion "2" "4" "4" "";
214 sha256 = {
215 src = "0nmfr2lijik6cykk0zbj11zcapcrvmdvq83k3r6q3k74g4d1qkr5";
216 git = "103cs7hz1v0h84lbrippl87s4lawi20m406rs5dgxl2gr2wyjpy5";
217 };
218 };
219
220 ruby_2_5 = generic {
221 version = rubyVersion "2" "5" "1" "";
222 sha256 = {
223 src = "1c99k0fjaq7k09104h1b1cqx6mrk2b14ic1jjnxc6yav68i1ij6s";
224 git = "1j0fd16aq9x98n0kq9c3kfp2sh6xcsq8q4733p0wfqjh3vz50kyj";
225 };
226 };
227}