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