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