Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 376 lines (258 sloc) 13.301 kb
cbbe6b9 @luislavena Minor revisions to cross compilation instructions
luislavena authored
1 = What is rake-compiler?
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
2
cbbe6b9 @luislavena Minor revisions to cross compilation instructions
luislavena authored
3 rake-compiler is first and foremost a productivity tool for Ruby developers.
93a50f4 @jonforums Update README.
jonforums authored
4 It's goal is to make the busy developer's life easier by simplifying the building
5 and packaging of Ruby extensions by simplifying code and reducing duplication.
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
6
93a50f4 @jonforums Update README.
jonforums authored
7 It follows *convention over configuration* by advocating a standardized build and
8 package structure for both C and Java based RubyGems.
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
9
cbbe6b9 @luislavena Minor revisions to cross compilation instructions
luislavena authored
10 rake-compiler is the result of many hard-won experiences dealing with several
93a50f4 @jonforums Update README.
jonforums authored
11 diverse RubyGems that provided native extensions for different platforms and
12 different user configurations in different ways. Details such as differences in
13 code portability, differences in code clarity, and differences in project directory
14 structure often made it very difficult for newcomers to those RubyGems.
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
15
93a50f4 @jonforums Update README.
jonforums authored
16 From these challenges, rake-compiler was born with the single-minded goal of
17 making the busy RubyGem developer's life much less difficult.
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
18
93a50f4 @jonforums Update README.
jonforums authored
19 == Feature Overview
20
21 Some of the benefits rake-compiler provides include:
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
22
23 * No custom rake tasks required. Less code duplication and errors.
24
25 * Painlessly build extensions on different platforms (Linux, OSX and Windows).
26
27 * Painlessly build extensions for different Ruby implementations (JRuby,
28 Rubinius and MRI).
29
93a50f4 @jonforums Update README.
jonforums authored
30 * Allow multiple extensions to be compiled inside the same gem.
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
31
93a50f4 @jonforums Update README.
jonforums authored
32 * Painlessly build "fat" native gems for Windows users (from Linux or OSX).
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
33
93a50f4 @jonforums Update README.
jonforums authored
34 * Mimics RubyGems standard installation process, helping as a test environment.
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
35
93a50f4 @jonforums Update README.
jonforums authored
36 * Simplifies cross platform extension compilation (targeting Windows from Linux).
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
37
93a50f4 @jonforums Update README.
jonforums authored
38 == OK, I'm sold! Show me how to install it!
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
39
93a50f4 @jonforums Update README.
jonforums authored
40 Simple:
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
41
42 $ gem install rake-compiler
43
93a50f4 @jonforums Update README.
jonforums authored
44 == That's easy. How do I use it?
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
45
93a50f4 @jonforums Update README.
jonforums authored
46 Now that you have installed rake-compiler, it's time to give your project a
47 standardized structure.
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
48
93a50f4 @jonforums Update README.
jonforums authored
49 === Using a standardized project structure
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
50
93a50f4 @jonforums Update README.
jonforums authored
51 Let's say you want to compile an extension called 'hello_world'. Organizing
52 your project's code tree in the following way will help rake-compiler do
53 its job:
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
54
55 |-- ext
56 | `-- hello_world
57 | |-- extconf.rb
58 | |-- HelloWorldService.java
59 | `-- hello_world.c
60 |-- lib
61 `-- Rakefile
62
93a50f4 @jonforums Update README.
jonforums authored
63 TIP: Having a consistent project directory structure will help developers and
64 newcomers find and understand your code, making it easier for them to
65 contribute back to your project.
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
66
93a50f4 @jonforums Update README.
jonforums authored
67 === Adding the code to enable rake-compiler
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
68
93a50f4 @jonforums Update README.
jonforums authored
69 Now the fun part. It's time to introduce the code to your projects Rakefile
70 to tell it to use rake-compiler to build your extension:
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
71
72 # File: Rakefile
73
74 require 'rake/extensiontask'
75
76 Rake::ExtensionTask.new('hello_world')
77
93a50f4 @jonforums Update README.
jonforums authored
78 That's it? Yes, that's it! No other lines of code are needed for
79 rake-compiler to work its magic.
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
80
93a50f4 @jonforums Update README.
jonforums authored
81 If you want to do the same for a JRuby extension written in Java, it's just
82 as easy:
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
83
84 # File: Rakefile
85
86 require 'rake/javaextensiontask'
87
88 Rake::JavaExtensionTask.new('hello_world')
89
93a50f4 @jonforums Update README.
jonforums authored
90 === The simple process
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
91
93a50f4 @jonforums Update README.
jonforums authored
92 Those *two* simple lines of code automatically added the Rake tasks needed to
93 build your 'hello_world' extension. For example, checking the Rake tasks on
94 MRI Ruby 1.8.x/1.9 returns something similar to:
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
95
96 $ rake -T
97 (in /home/user/my_extension)
98 rake compile # Compile the extension(s)
99 rake compile:hello_world # Compile just the hello_world extension
100
93a50f4 @jonforums Update README.
jonforums authored
101 Simply calling <tt>compile</tt> like
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
102
103 $ rake compile
104
93a50f4 @jonforums Update README.
jonforums authored
105 performs the entire compile and build process for you and places the resulting
106 extension inside the <tt>lib</tt> directory of your project.
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
107
108 NOTE: Please be aware that building C extensions requires the proper
93a50f4 @jonforums Update README.
jonforums authored
109 development environment for your Platform, including libraries, headers
110 and build tools. Check your distro / vendor documentation on how to install
111 these development resources.
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
112
113 NOTE: Building Java extensions requires the <tt>javac</tt>, part of the Java
114 Development Kit (JDK). This should be included by default on Mac OS X, and
115 downloadable from http://java.sun.com for other operating systems.
116
93a50f4 @jonforums Update README.
jonforums authored
117 === Generating native RubyGems
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
118
93a50f4 @jonforums Update README.
jonforums authored
119 A common usage scenario for rake-compiler is generating native gems that
120 bundle your extensions. As mentioned above, if you have your development
121 environment configured correctly, the following examples work even when
122 building native gems on Windows systems.
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
123
93a50f4 @jonforums Update README.
jonforums authored
124 Creating native gems is really easy with rake-compiler's <tt>Rake::ExtensionTask</tt>:
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
125
126 # somewhere in your Rakefile, define your gem spec
127 spec = Gem::Specification.new do |s|
128 s.name = "my_gem"
129 s.platform = Gem::Platform::RUBY
130 s.extensions = FileList["ext/**/extconf.rb"]
131 end
132
133 # add your default gem packing task
cbbe6b9 @luislavena Minor revisions to cross compilation instructions
luislavena authored
134 Gem::PackageTask.new(spec) do |pkg|
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
135 end
136
93a50f4 @jonforums Update README.
jonforums authored
137 # feed the ExtensionTask with your spec
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
138 Rake::ExtensionTask.new('hello_world', spec)
139
93a50f4 @jonforums Update README.
jonforums authored
140 As expected, you can still build your pure-ruby gem in the usual way
141 (standard output) by running:
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
142
143 $ rake gem
144 (in /projects/oss/my_gem.git)
145 mkdir -p pkg
146 Successfully built RubyGem
147 Name: my_gem
148 Version: 0.1.0
149 File: my_gem-0.1.0.gem
150 mv my_gem-0.1.0.gem pkg/my_gem-0.1.0.gem
151
cbbe6b9 @luislavena Minor revisions to cross compilation instructions
luislavena authored
152 Plus, rake-compiler tasks give you the extra functionality needed to build
93a50f4 @jonforums Update README.
jonforums authored
153 native gems by running:
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
154
155 # rake native gem
156 (... compilation output ...)
157 mkdir -p pkg
158 Successfully built RubyGem
159 Name: my_gem
160 Version: 0.1.0
161 File: my_gem-0.1.0.gem
162 mv my_gem-0.1.0.gem pkg/my_gem-0.1.0.gem
163 Successfully built RubyGem
164 Name: my_gem
165 Version: 0.1.0
166 File: my_gem-0.1.0-x86-mingw32.gem
167 mv my_gem-0.1.0-x86-mingw32.gem pkg/my_gem-0.1.0-x86-mingw32.gem
168
93a50f4 @jonforums Update README.
jonforums authored
169 Did you notice that you get two gems for the price of one? How's that for a
170 time saver?
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
171
93a50f4 @jonforums Update README.
jonforums authored
172 Similarly, it's just as easy to do the same thing for JRuby extensions:
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
173
174 # rake java gem
175 (... compilation output ...)
176 mkdir -p pkg
177 Successfully built RubyGem
178 Name: my_gem
179 Version: 0.1.0
180 File: my_gem-0.1.0.gem
181 mv my_gem-0.1.0.gem pkg/my_gem-0.1.0.gem
182 Successfully built RubyGem
183 Name: my_gem
184 Version: 0.1.0
185 File: my_gem-0.1.0-java.gem
186 mv my_gem-0.1.0-java.gem pkg/my_gem-0.1.0-java.gem
187
188
93a50f4 @jonforums Update README.
jonforums authored
189 === Great, but can I use a non-standard project structure?
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
190
93a50f4 @jonforums Update README.
jonforums authored
191 Yes you can! While the conventional project structure is recommended, you may
192 want, or need, to tweak those conventions. Rake-compiler allows you to customize
193 several settings for <tt>Rake::ExtensionTask</tt>:
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
194
195 Rake::ExtensionTask.new do |ext|
196 ext.name = 'hello_world' # indicate the name of the extension.
197 ext.ext_dir = 'ext/weird_world' # search for 'hello_world' inside it.
198 ext.lib_dir = 'lib/my_lib' # put binaries into this folder.
93a50f4 @jonforums Update README.
jonforums authored
199 ext.config_script = 'custom_extconf.rb' # use instead of the default 'extconf.rb'.
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
200 ext.tmp_dir = 'tmp' # temporary folder used during compilation.
201 ext.source_pattern = "*.{c,cpp}" # monitor file changes to allow simple rebuild.
93a50f4 @jonforums Update README.
jonforums authored
202 ext.config_options << '--with-foo' # supply additional options to configure script.
203 ext.gem_spec = spec # optionally indicate which gem specification
204 # will be used.
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
205 end
206
93a50f4 @jonforums Update README.
jonforums authored
207 == Cross compilation - the future is now.
208
209 Rake-compiler also provides a standardized way to generate, from either Linux
210 or OSX, extensions and gem binaries for your Windows users!
211
212 How can this be you say? Simple, rake-compiler's cross compilation features
213 take advantage of GCC's host/target capabilities to build 'target' binaries on
214 different 'host' OS's.
215
216 === How I do this from Linux or OSX?
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
217
93a50f4 @jonforums Update README.
jonforums authored
218 In addition to having the development tool chain installed (GCC), you also need to
219 install your platform's <tt>mingw32</tt> cross compilation package.
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
220
93a50f4 @jonforums Update README.
jonforums authored
221 Installation depends upon your operating system/distribution. On Ubuntu and Debian
222 host machines, a simple <tt>apt-get install mingw32</tt> will be enough.
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
223
93a50f4 @jonforums Update README.
jonforums authored
224 On Arch, <tt>mingw32</tt> is installed by running <tt>pacman -S mingw32-gcc</tt>
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
225
93a50f4 @jonforums Update README.
jonforums authored
226 On OSX, <tt>mingw32</tt> is available via MacPorts via <tt>port install i386-mingw32-gcc</tt>
227 (ensure your ports tree is updated as <tt>mingw32</tt> has been broken in the past).
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
228
93a50f4 @jonforums Update README.
jonforums authored
229 === I've got my tool-chain installed, now what?
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
230
cbbe6b9 @luislavena Minor revisions to cross compilation instructions
luislavena authored
231 First, you need to build Ruby for Windows on your Linux or OSX system.
93a50f4 @jonforums Update README.
jonforums authored
232
233 Relax, no need to freak out! Let rake-compiler do all the heavy lifting for you:
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
234
235 rake-compiler cross-ruby
236
93a50f4 @jonforums Update README.
jonforums authored
237 And you're done. It will automatically download, configure and compile the latest
238 stable version of Ruby for Windows, and place it into your <tt>~/.rake-compiler</tt>
239 directory.
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
240
cbbe6b9 @luislavena Minor revisions to cross compilation instructions
luislavena authored
241 This will create <tt>~/.rake-compiler/config.yml</tt> file so that rake-compiler
242 knows where to find the <tt>rbconfig.rb</tt> file that matches the Ruby version
243 on the Windows host system you're cross-compiling for. An example:
244
245 # File: ~/.rake-compiler/config.yml
246
247 rbconfig-1.8.6: /path/to/ruby-1.8.6/rbconfig.rb
248 rbconfig-1.8.7: /path/to/ruby-1.8.7/rbconfig.rb
249 rbconfig-1.9.2: /path/to/ruby-1.9.2/rbconfig.rb
250
93a50f4 @jonforums Update README.
jonforums authored
251 If, instead, you want to build a different Ruby version than the default one, please
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
252 supply a <tt>VERSION</tt>:
253
254 rake-compiler cross-ruby VERSION=1.8.6-p114
255
93a50f4 @jonforums Update README.
jonforums authored
256 If you, like me, have multiple versions of MinGW packages installed, you can
257 specify the HOST that will be used to cross compile Ruby:
68be722 @luislavena Added some documentation to HOST option
luislavena authored
258
259 rake-compiler cross-ruby HOST=i386-mingw32 # (OSX mingw32 port)
260
261 The host will vary depending on provider (mingw32 versus mingw-w64 projects).
93a50f4 @jonforums Update README.
jonforums authored
262 Please consult the documentation and website of the MinGW package provider before
263 reporting any issues.
68be722 @luislavena Added some documentation to HOST option
luislavena authored
264
93a50f4 @jonforums Update README.
jonforums authored
265 === OK, let's cross compile some gems!
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
266
93a50f4 @jonforums Update README.
jonforums authored
267 Now, you only need specify a few additional options in your extension definition:
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
268
269 Rake::ExtensionTask.new('my_extension', gem_spec) do |ext|
270 ext.cross_compile = true # enable cross compilation (requires cross compile toolchain)
271 ext.cross_platform = 'i386-mswin32' # forces the Windows platform instead of the default one
272 # configure options only for cross compile
273 ext.cross_config_options << '--with-something'
274
275 # perform alterations on the gemspec when cross compiling
276 ext.cross_compiling do |gem_spec|
277 gem_spec.post_install_message = "You installed the binary version of this gem!"
278 end
279 end
280
93a50f4 @jonforums Update README.
jonforums authored
281 By default, cross compilation targets 'i386-mingw32' which is the default GCC
282 platform for Ruby.
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
283
93a50f4 @jonforums Update README.
jonforums authored
284 To target gems for MRI Ruby's current official distribution, please force the
285 platform to the one (i386-mswin32) previously shown.
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
286
93a50f4 @jonforums Update README.
jonforums authored
287 === Warning, magician about to do some tricks, don't blink!
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
288
93a50f4 @jonforums Update README.
jonforums authored
289 Cross compiling is still very simple:
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
290
291 rake cross compile
292
93a50f4 @jonforums Update README.
jonforums authored
293 And now, building gems for your Windows users is just 5 more letters:
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
294
295 rake cross native gem
296
297 And you're done, yeah.
298
93a50f4 @jonforums Update README.
jonforums authored
299 === But wait, there's more
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
300
cbbe6b9 @luislavena Minor revisions to cross compilation instructions
luislavena authored
301 You can specify which version of Ruby to build the extension against:
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
302
303 rake cross compile RUBY_CC_VERSION=1.8.6
304
93a50f4 @jonforums Update README.
jonforums authored
305 For example, if you installed <tt>1.9.2</tt>, you can do:
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
306
93a50f4 @jonforums Update README.
jonforums authored
307 rake cross compile RUBY_CC_VERSION=1.9.2
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
308
93a50f4 @jonforums Update README.
jonforums authored
309 Even better, you can target multiple versions (ie. 1.8.6 and 1.9.2) in
310 the same gem via:
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
311
93a50f4 @jonforums Update README.
jonforums authored
312 rake cross compile RUBY_CC_VERSION=1.8.6:1.9.2
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
313
93a50f4 @jonforums Update README.
jonforums authored
314 And better yet, you can bundle both binary extensions into one so-called "fat"
315 gem via:
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
316
93a50f4 @jonforums Update README.
jonforums authored
317 rake cross native gem RUBY_CC_VERSION=1.8.6:1.9.2
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
318
93a50f4 @jonforums Update README.
jonforums authored
319 That will place binaries for both the 1.8 and 1.9 versions of your Ruby
320 extensions inside your project's <tt>lib_dir</tt> directory:
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
321
322 lib/1.8/my_extension.so
323 lib/1.9/my_extension.so
324
93a50f4 @jonforums Update README.
jonforums authored
325 NOTE: building "fat" gems is currently only supported by rake-compiler when
326 cross compiling from a Linux or OSX host. Patches are welcome if building
cbbe6b9 @luislavena Minor revisions to cross compilation instructions
luislavena authored
327 "fat" gems from Windows hosts is desired, or natively for your platform :-)
93a50f4 @jonforums Update README.
jonforums authored
328
7d0cb02 @luislavena Better require example for fat-binaries
luislavena authored
329 Now is up to you to make your gem load the proper binary at runtime:
93a50f4 @jonforums Update README.
jonforums authored
330
7d0cb02 @luislavena Better require example for fat-binaries
luislavena authored
331 begin
332 RUBY_VERSION =~ /(\d+.\d+)/
333 require "#{$1}/my_extension"
334 rescue LoadError
335 require "my_extension"
336 end
337
338 The above technique will lookup first for 1.8 or 1.9 version of the extension
339 and when not found, will look for the plain extension.
340
341 This approach catch the cases of provided fat binaries or gems compiled by the
342 end user installing the gem. It has also been implemented successfully in
343 several projects.
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
344
345 === What are you talking about? (Give me examples)
346
93a50f4 @jonforums Update README.
jonforums authored
347 I know all the above sounds like a complete foreign language (it does even for me!).
348 So, what if I show you some examples?
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
349
93a50f4 @jonforums Update README.
jonforums authored
350 Check our wiki with links to the proper rake files used by many developers and
351 projects and how they use rake-compiler.
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
352
353 http://github.com/luislavena/rake-compiler/wiki/projects-using-rake-compiler
354
355 == Future
356
cbbe6b9 @luislavena Minor revisions to cross compilation instructions
luislavena authored
357 rake-compiler is a work in progress and we appreciate any and all feedback
93a50f4 @jonforums Update README.
jonforums authored
358 during the development of it! (and contributions too!)
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
359
360 You can find more information about rake-compiler:
361
bd046ac @luislavena Deprecate RDoc generation and use rubydoc.info instead
luislavena authored
362 * GitHub: https://github.com/luislavena/rake-compiler
363 * Issues: https://github.com/luislavena/rake-compiler/issues
364 * Blog: http://blog.mmediasys.com
365 * Docs: http://rubydoc.info/gems/rake-compiler
366 * Wiki: https://github.com/luislavena/rake-compiler/wiki
83a4096 @luislavena Add wiki example link to README. Close GH-26
luislavena authored
367
368 == Disclaimer
369
370 If you have any trouble, don't hesitate to contact the author. As always,
371 I'm not going to say "Use at your own risk" because I don't want this library
372 to be risky.
373
374 If you trip on something, I'll share the liability by repairing things
375 as quickly as I can. Your responsibility is to report the inadequacies.
Something went wrong with that request. Please try again.