rake-compiler 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +32 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +258 -0
- data/Rakefile +23 -0
- data/bin/rake-compiler +24 -0
- data/cucumber.yml +1 -0
- data/features/compile.feature +71 -0
- data/features/cross-compile.feature +13 -0
- data/features/cross-package.feature +14 -0
- data/features/package.feature +40 -0
- data/features/step_definitions/compilation.rb +43 -0
- data/features/step_definitions/cross_compilation.rb +21 -0
- data/features/step_definitions/execution.rb +30 -0
- data/features/step_definitions/folders.rb +32 -0
- data/features/step_definitions/gem.rb +29 -0
- data/features/support/env.rb +7 -0
- data/features/support/file_templates.rb +88 -0
- data/features/support/generators.rb +77 -0
- data/lib/rake/extensiontask.rb +270 -0
- data/spec/lib/rake/extensiontask_spec.rb +352 -0
- data/spec/spec_helper.rb +9 -0
- data/tasks/bin/cross-ruby.rake +159 -0
- data/tasks/common.rake +13 -0
- data/tasks/cucumber.rake +14 -0
- data/tasks/gem.rake +59 -0
- data/tasks/rdoc.rake +9 -0
- data/tasks/release.rake +79 -0
- data/tasks/rspec.rake +33 -0
- metadata +97 -0
data/History.txt
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
=== 0.3.0 / 2008-12-07
|
2
|
+
|
3
|
+
* 1 Major Enhancement:
|
4
|
+
|
5
|
+
* Let you specify the Ruby version used for cross compilation instead
|
6
|
+
of default one.
|
7
|
+
|
8
|
+
rake cross compile RUBY_CC_VERSION=1.8
|
9
|
+
|
10
|
+
* 2 Minor Enhancements:
|
11
|
+
|
12
|
+
* Properly update rake-compiler configuration when new version is installed.
|
13
|
+
* Automated release process to RubyForge, yay!
|
14
|
+
|
15
|
+
* 1 Bug fix:
|
16
|
+
|
17
|
+
* Corrected documentation to reflect the available options
|
18
|
+
|
19
|
+
=== 0.2.1 / 2008-11-30
|
20
|
+
|
21
|
+
* 2 Major Enhancements:
|
22
|
+
|
23
|
+
* Allow cross compilation (cross compile) using mingw32 on Linux or OSX.
|
24
|
+
* Allow packaging of gems for Windows on Linux or OSX.
|
25
|
+
|
26
|
+
* 1 Minor Enhancement:
|
27
|
+
|
28
|
+
* Made generation of extensions safe and target folders per-platform
|
29
|
+
|
30
|
+
* 1 Bug Fix:
|
31
|
+
|
32
|
+
* Ensure binaries for the specific platform are copied before packaging.
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Luis Lavena.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,258 @@
|
|
1
|
+
= rake-compiler
|
2
|
+
|
3
|
+
rake-compiler aims to help Gem developers while dealing with Ruby C
|
4
|
+
extensions, simplifiying the code and reducing the duplication.
|
5
|
+
|
6
|
+
It follows *convention over configuration* and set an standarized
|
7
|
+
structure to build and package C extensions in your gems.
|
8
|
+
|
9
|
+
This is the result of expriences dealing with several Gems that required
|
10
|
+
native extensions across platforms and different user configurations
|
11
|
+
where details like portability and clarity of code were lacking.
|
12
|
+
|
13
|
+
== An Overview
|
14
|
+
|
15
|
+
Let's summarize what rake-compiler provides:
|
16
|
+
|
17
|
+
* No custom rake tasks required. Less code duplication and errors.
|
18
|
+
|
19
|
+
* Painlessly build extensions on different platforms (Linux, OSX and Windows).
|
20
|
+
|
21
|
+
* Allow multiple extensions be compiled inside the same gem.
|
22
|
+
|
23
|
+
* Mimics RubyGems installation process, so helps as test environment.
|
24
|
+
|
25
|
+
* Simplify cross platform compilation of extensions (target Windows from Linux).
|
26
|
+
|
27
|
+
== I'm sold! show me how to use it! (Installation)
|
28
|
+
|
29
|
+
Usage of rake-compiler is pretty much straight forward.
|
30
|
+
|
31
|
+
First, you need to install the gem:
|
32
|
+
|
33
|
+
$ gem install rake-compiler
|
34
|
+
|
35
|
+
Since this package is in constant evolution, you could try installing it
|
36
|
+
from GitHub:
|
37
|
+
|
38
|
+
$ gem install luislavena-rake-compiler --source http://gems.github.com
|
39
|
+
|
40
|
+
The development gem is usually in pretty good shape actually.
|
41
|
+
|
42
|
+
== Now what? (Usage)
|
43
|
+
|
44
|
+
Now that you have the gem installed, let's give your project some structure.
|
45
|
+
|
46
|
+
=== Structure
|
47
|
+
|
48
|
+
Let's say we want to compile an extension called 'hello_world', so we should
|
49
|
+
organize the code and folders that will help rake-compiler do it's job:
|
50
|
+
|
51
|
+
|-- ext
|
52
|
+
| `-- hello_world
|
53
|
+
| |-- extconf.rb
|
54
|
+
| `-- hello_world.c
|
55
|
+
|-- lib
|
56
|
+
`-- Rakefile
|
57
|
+
|
58
|
+
TIP: Having a consistent folder structure will help developers and newcomers
|
59
|
+
to find code and also contribute back to your project more easily.
|
60
|
+
|
61
|
+
=== Adding the code
|
62
|
+
|
63
|
+
So now it's time to introduce the code to compile our extension:
|
64
|
+
|
65
|
+
# File: Rakefile
|
66
|
+
|
67
|
+
require 'rake/extensiontask'
|
68
|
+
|
69
|
+
Rake::ExtensionTask.new('hello_world')
|
70
|
+
|
71
|
+
Ok, that's it. No other line of code.
|
72
|
+
|
73
|
+
=== Compile process
|
74
|
+
|
75
|
+
Those *two* lines of code automatically added the needed rake tasks to build
|
76
|
+
the hello_world extension:
|
77
|
+
|
78
|
+
$ rake -T
|
79
|
+
(in /home/user/my_extesion)
|
80
|
+
rake compile # Compile the extension(s)
|
81
|
+
rake compile:hello_world # Compile just the hello_world extension
|
82
|
+
|
83
|
+
Simply calling <tt>compile</tt>:
|
84
|
+
|
85
|
+
$ rake compile
|
86
|
+
|
87
|
+
Will do all the compile process for us, putting the result extension inside
|
88
|
+
<tt>lib</tt> directory.
|
89
|
+
|
90
|
+
NOTE: Please be aware that building C extensions requires the proper
|
91
|
+
development environment for your Platform, which includes libraries, headers
|
92
|
+
and build tools. Check your distro / vendor documentation on how to install it.
|
93
|
+
|
94
|
+
=== Generate native gems
|
95
|
+
|
96
|
+
A common usage scenario of rake-compiler is generate native gems that bundles
|
97
|
+
your extensions.
|
98
|
+
|
99
|
+
This got over-simplified with <tt>Rake::ExtensionTask</tt>:
|
100
|
+
|
101
|
+
# somewhere in your Rakefile, define your gem spec
|
102
|
+
spec = Gem::Specification.new do |s|
|
103
|
+
s.name = "my_gem"
|
104
|
+
s.platform = Gem::Platform::RUBY
|
105
|
+
s.extensions = FileList["ext/**/extconf.rb"]
|
106
|
+
end
|
107
|
+
|
108
|
+
# add your default gem packing task
|
109
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
110
|
+
end
|
111
|
+
|
112
|
+
# feed your ExtensionTask with your spec
|
113
|
+
Rake::ExtensionTask.new('hello_world', spec)
|
114
|
+
|
115
|
+
Now, as usual, you can build your pure-ruby gem (standard output):
|
116
|
+
|
117
|
+
$ rake gem
|
118
|
+
(in /projects/oss/my_gem.git)
|
119
|
+
mkdir -p pkg
|
120
|
+
Successfully built RubyGem
|
121
|
+
Name: my_gem
|
122
|
+
Version: 0.1.0
|
123
|
+
File: my_gem-0.1.0.gem
|
124
|
+
mv my_gem-0.1.0.gem pkg/my_gem-0.1.0.gem
|
125
|
+
|
126
|
+
Plus, you have the functionality to build native versions of the gem:
|
127
|
+
|
128
|
+
# rake native gem
|
129
|
+
(... compilation output ...)
|
130
|
+
mkdir -p pkg
|
131
|
+
Successfully built RubyGem
|
132
|
+
Name: my_gem
|
133
|
+
Version: 0.1.0
|
134
|
+
File: my_gem-0.1.0.gem
|
135
|
+
mv my_gem-0.1.0.gem pkg/my_gem-0.1.0.gem
|
136
|
+
Successfully built RubyGem
|
137
|
+
Name: my_gem
|
138
|
+
Version: 0.1.0
|
139
|
+
File: my_gem-0.1.0-x86-mingw32.gem
|
140
|
+
mv my_gem-0.1.0-x86-mingw32.gem pkg/my_gem-0.1.0-x86-mingw32.gem
|
141
|
+
|
142
|
+
You get two gems for the price of one.
|
143
|
+
|
144
|
+
=== What about breaking the standards? (Customization)
|
145
|
+
|
146
|
+
In case you want to bend the convention established, rake-compiler let you
|
147
|
+
personalize several settings for <tt>Rake::ExtensionTask</tt>:
|
148
|
+
|
149
|
+
Rake::ExtensionTask.new do |ext|
|
150
|
+
ext.name = 'hello_world' # indicate the name of the extension.
|
151
|
+
ext.ext_dir = 'ext/weird_world' # search for 'hello_world' inside it.
|
152
|
+
ext.lib_dir = 'lib/my_lib' # put binaries into this folder.
|
153
|
+
ext.config_script = 'custom_extconf.rb' # use instead of 'extconf.rb' default
|
154
|
+
ext.tmp_dir = 'tmp' # temporary folder used during compilation.
|
155
|
+
ext.source_pattern = "*.{c,cpp}" # monitor file changes to allow simple rebuild.
|
156
|
+
ext.config_options << '--with-foo' # supply additional configure options to config script.
|
157
|
+
ext.gem_spec = spec # optional indicate which gem specification
|
158
|
+
# will be used to based on.
|
159
|
+
end
|
160
|
+
|
161
|
+
== Future is now: Cross compilation
|
162
|
+
|
163
|
+
rake-compiler provides now an standarized way to generate, from Linux or OSX
|
164
|
+
both extensions and gem binaries for Windows!
|
165
|
+
|
166
|
+
It takes advantages from GCC host/target to build binaries (for target) on
|
167
|
+
different OS (hosts).
|
168
|
+
|
169
|
+
=== How I enjoy this?
|
170
|
+
|
171
|
+
Besides having the development tool chain installed (GCC), you should install
|
172
|
+
also <tt>mingw32</tt> cross compilation package.
|
173
|
+
|
174
|
+
Dependending on your operating system distribution, a simple <tt>apt-get install mingw32</tt>
|
175
|
+
will be enough.
|
176
|
+
|
177
|
+
Please check OSX documentation about installing mingw32 from macports.
|
178
|
+
|
179
|
+
=== I have my toolchain, now what?
|
180
|
+
|
181
|
+
You need to build Ruby for Windows.
|
182
|
+
|
183
|
+
Relax, no need to freak out. rake-compiler do it for you:
|
184
|
+
|
185
|
+
rake-compiler cross-ruby
|
186
|
+
|
187
|
+
And you're done. It will automatically download, configure and compile latest
|
188
|
+
stable version of Ruby for Windows, and place it into <tt>~/.rake-compiler</tt>
|
189
|
+
|
190
|
+
If, instead, you want to build another version than the default one, please
|
191
|
+
supply a <tt>VERSION</tt>:
|
192
|
+
|
193
|
+
rake-compiler cross-ruby VERSION=1.8.6-p114
|
194
|
+
|
195
|
+
=== Let's build some gems!
|
196
|
+
|
197
|
+
Now, you only need to use additional options in your extension defintion:
|
198
|
+
|
199
|
+
Rake::ExtensionTask.new('my_extension', gem_spec) do |ext|
|
200
|
+
ext.cross_compile = true # enable cross compilation (requires cross compile toolchain)
|
201
|
+
ext.cross_platform = 'i386-mswin32' # forces the Windows platform instead of the default one
|
202
|
+
# configure options only for cross compile
|
203
|
+
ext.cross_config_options << '--with-something'
|
204
|
+
end
|
205
|
+
|
206
|
+
By default, cross compilation targets 'i386-mingw32' which is default GCC platform
|
207
|
+
for Ruby.
|
208
|
+
|
209
|
+
To target gems for current Ruby official distribution, please force the platform
|
210
|
+
to the one shown before.
|
211
|
+
|
212
|
+
=== Magician doing some tricks, don't blink!
|
213
|
+
|
214
|
+
Compiles keeps being simple:
|
215
|
+
|
216
|
+
rake cross compile
|
217
|
+
|
218
|
+
And now, build your gems for Windows is just 5 more letters:
|
219
|
+
|
220
|
+
rake cross native gem
|
221
|
+
|
222
|
+
And you're done, yeah.
|
223
|
+
|
224
|
+
=== Take it even further
|
225
|
+
|
226
|
+
You can specify against with version of Ruby you want to build the extension:
|
227
|
+
|
228
|
+
rake cross compile RUBY_CC_VERSION=1.8
|
229
|
+
|
230
|
+
If you installed <tt>1.9.1</tt>, you can do:
|
231
|
+
|
232
|
+
rake cross compile RUBY_CC_VERSION=1.9
|
233
|
+
|
234
|
+
== Future
|
235
|
+
|
236
|
+
rake-compiler is a work in progress and we will appreciate feedback during the
|
237
|
+
development of it! (and contributions too!)
|
238
|
+
|
239
|
+
You can find more information about rake-compiler:
|
240
|
+
|
241
|
+
Blog: http://blog.mmediasys.com
|
242
|
+
RubyForge: http://rubyforge.org/projects/rake-compiler
|
243
|
+
GitHub: http://github.com/luislavena/rake-compiler
|
244
|
+
|
245
|
+
=== Some of the desired features
|
246
|
+
|
247
|
+
* <tt>Rake::JavaJarTask</tt> to generate <tt>jar</tt> packages and gems for JRuby.
|
248
|
+
|
249
|
+
$ rake java gem
|
250
|
+
|
251
|
+
== Disclaimer
|
252
|
+
|
253
|
+
If you have any trouble, don't hesitate to contact the author. As always,
|
254
|
+
I'm not going to say "Use at your own risk" because I don't want this library
|
255
|
+
to be risky.
|
256
|
+
|
257
|
+
If you trip on something, I'll share the liability by repairing things
|
258
|
+
as quickly as I can. Your responsibility is to report the inadequacies.
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2008 Luis Lavena
|
3
|
+
#
|
4
|
+
# This source code is released under the MIT License.
|
5
|
+
# See LICENSE file for details
|
6
|
+
#++
|
7
|
+
|
8
|
+
#
|
9
|
+
# NOTE: Keep this file clean.
|
10
|
+
# Add your customizations inside tasks directory.
|
11
|
+
# Thank You.
|
12
|
+
#
|
13
|
+
|
14
|
+
begin
|
15
|
+
require 'rake'
|
16
|
+
rescue LoadError
|
17
|
+
require 'rubygems'
|
18
|
+
gem 'rake', '~> 0.8.3.1'
|
19
|
+
require 'rake'
|
20
|
+
end
|
21
|
+
|
22
|
+
# load rakefile extensions (tasks)
|
23
|
+
Dir['tasks/*.rake'].each { |f| import f }
|
data/bin/rake-compiler
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright (c) 2008 Luis Lavena
|
5
|
+
#
|
6
|
+
# This source code is released under the MIT License.
|
7
|
+
# See LICENSE file for details
|
8
|
+
#++
|
9
|
+
|
10
|
+
begin
|
11
|
+
require 'rake'
|
12
|
+
rescue LoadError
|
13
|
+
require 'rubygems'
|
14
|
+
require 'rake'
|
15
|
+
end
|
16
|
+
|
17
|
+
# Initialize 'rake-compiler' application
|
18
|
+
Rake.application.init('rake-compiler')
|
19
|
+
|
20
|
+
# Load the already cooked tasks ;-)
|
21
|
+
load File.join(File.dirname(__FILE__), %w{.. tasks bin cross-ruby.rake})
|
22
|
+
|
23
|
+
# delegate control to Rake
|
24
|
+
Rake.application.top_level
|
data/cucumber.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
autotest: --format progress features
|
@@ -0,0 +1,71 @@
|
|
1
|
+
Feature: Compile C code into Ruby extensions.
|
2
|
+
|
3
|
+
In order to automate compilation process.
|
4
|
+
As a Gem developer.
|
5
|
+
I want rake tasks compile source code for me.
|
6
|
+
|
7
|
+
Scenario: compile single extension
|
8
|
+
Given a safe project directory
|
9
|
+
And a extension named 'extension_one'
|
10
|
+
And 'tmp' folder is deleted
|
11
|
+
When rake task 'compile' is invoked
|
12
|
+
Then rake task 'compile' succeeded
|
13
|
+
And binary extension 'extension_one' do exist in 'lib'
|
14
|
+
And 'tmp' folder is created
|
15
|
+
|
16
|
+
Scenario: not recompile unmodified extension
|
17
|
+
Given a safe project directory
|
18
|
+
And a extension named 'extension_one'
|
19
|
+
And I've already successfully executed rake task 'compile'
|
20
|
+
And not changed any file since
|
21
|
+
When rake task 'compile' is invoked
|
22
|
+
Then rake task 'compile' succeeded
|
23
|
+
And output of rake task 'compile' do not contain /gcc|cl/
|
24
|
+
|
25
|
+
Scenario: recompile extension when source is modified
|
26
|
+
Given a safe project directory
|
27
|
+
And a extension named 'extension_one'
|
28
|
+
And I've already successfully executed rake task 'compile'
|
29
|
+
When touching 'source.c' file of extension 'extension_one'
|
30
|
+
And rake task 'compile' is invoked
|
31
|
+
Then rake task 'compile' succeeded
|
32
|
+
And output of rake task 'compile' contains /extension_one/
|
33
|
+
|
34
|
+
Scenario: compile multiple extensions
|
35
|
+
Given a safe project directory
|
36
|
+
And a extension named 'extension_one'
|
37
|
+
And a extension named 'extension_two'
|
38
|
+
And 'tmp' folder is deleted
|
39
|
+
When rake task 'compile' is invoked
|
40
|
+
Then rake task 'compile' succeeded
|
41
|
+
And binary extension 'extension_one' do exist in 'lib'
|
42
|
+
And binary extension 'extension_two' do exist in 'lib'
|
43
|
+
And 'tmp' folder is created
|
44
|
+
|
45
|
+
Scenario: compile one extension instead of all present
|
46
|
+
Given a safe project directory
|
47
|
+
And a extension named 'extension_one'
|
48
|
+
And a extension named 'extension_two'
|
49
|
+
When rake task 'compile:extension_one' is invoked
|
50
|
+
Then rake task 'compile:extension_one' succeeded
|
51
|
+
And output of rake task 'compile:extension_one' do not contain /extension_two/
|
52
|
+
And binary extension 'extension_one' do exist in 'lib'
|
53
|
+
And binary extension 'extension_two' do not exist in 'lib'
|
54
|
+
|
55
|
+
Scenario: removing temporary files
|
56
|
+
Given a safe project directory
|
57
|
+
And a extension named 'extension_one'
|
58
|
+
And I've already successfully executed rake task 'compile'
|
59
|
+
When rake task 'clean' is invoked
|
60
|
+
Then rake task 'clean' succeeded
|
61
|
+
And binary extension 'extension_one' do exist in 'lib'
|
62
|
+
And no left over from 'extension_one' remains in 'tmp'
|
63
|
+
|
64
|
+
Scenario: clobbering binary and temporary files
|
65
|
+
Given a safe project directory
|
66
|
+
And a extension named 'extension_one'
|
67
|
+
And I've already successfully executed rake task 'compile'
|
68
|
+
When rake task 'clobber' is invoked
|
69
|
+
Then rake task 'clobber' succeeded
|
70
|
+
And binary extension 'extension_one' do not exist in 'lib'
|
71
|
+
And 'tmp' folder do not exist
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Feature: Cross-compile C extensions
|
2
|
+
|
3
|
+
In order to avoid bitching from Windows users
|
4
|
+
As a Ruby developer on Linux
|
5
|
+
I want some rake tasks that take away the pain of compilation
|
6
|
+
|
7
|
+
Scenario: compile single extension
|
8
|
+
Given that all my source files are in place
|
9
|
+
And I'm running a POSIX operating system
|
10
|
+
And I've installed cross compile toolchain
|
11
|
+
When rake task 'cross compile' is invoked
|
12
|
+
Then rake task 'cross compile' succeeded
|
13
|
+
And binaries for platform 'i386-mingw32' get generated
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Feature: Generate Windows gems from Linux
|
2
|
+
|
3
|
+
In order to keep sanity in the Ruby world
|
4
|
+
As a Gem developer on Linux
|
5
|
+
I want more rake magic that turns monotony into joy.
|
6
|
+
|
7
|
+
Scenario: package a gem for Windows
|
8
|
+
Given that my gem source is all in place
|
9
|
+
And I'm running a POSIX operating system
|
10
|
+
And I've installed cross compile toolchain
|
11
|
+
And I've already successfully executed rake task 'cross compile'
|
12
|
+
When rake task 'cross native gem' is invoked
|
13
|
+
Then rake task 'cross native gem' succeeded
|
14
|
+
And gem for platform 'x86-mingw32' get generated
|
@@ -0,0 +1,40 @@
|
|
1
|
+
Feature: Distribute native extension with gems
|
2
|
+
|
3
|
+
In order to avoid compiler toolchain requirement during installation
|
4
|
+
As a Gem developer.
|
5
|
+
I want rake tasks generate platform specific gems for me
|
6
|
+
|
7
|
+
Scenario: generate pure ruby gem
|
8
|
+
Given a safe project directory
|
9
|
+
And a gem named 'my_project'
|
10
|
+
And a extension named 'extension_one'
|
11
|
+
And I've already successfully executed rake task 'compile'
|
12
|
+
And 'pkg' folder is deleted
|
13
|
+
When rake task 'gem' is invoked
|
14
|
+
Then rake task 'gem' succeeded
|
15
|
+
And 'pkg' folder is created
|
16
|
+
And ruby gem for 'my_project' version '0.1.0' do exist in 'pkg'
|
17
|
+
|
18
|
+
Scenario: generate native gem
|
19
|
+
Given a safe project directory
|
20
|
+
And a gem named 'my_project'
|
21
|
+
And a extension named 'extension_one'
|
22
|
+
And I've already successfully executed rake task 'compile'
|
23
|
+
And 'pkg' folder is deleted
|
24
|
+
When rake task 'native gem' is invoked
|
25
|
+
Then rake task 'native gem' succeeded
|
26
|
+
And 'pkg' folder is created
|
27
|
+
And ruby gem for 'my_project' version '0.1.0' do exist in 'pkg'
|
28
|
+
And binary gem for 'my_project' version '0.1.0' do exist in 'pkg'
|
29
|
+
|
30
|
+
Scenario: generate forced native gem
|
31
|
+
Given a safe project directory
|
32
|
+
And a gem named 'my_project'
|
33
|
+
And a extension 'extension_one' with forced platform 'universal-unknown'
|
34
|
+
And I've already successfully executed rake task 'compile'
|
35
|
+
And 'pkg' folder is deleted
|
36
|
+
When rake task 'native:universal-unknown gem' is invoked
|
37
|
+
Then rake task 'native:universal-unknown gem' succeeded
|
38
|
+
And 'pkg' folder is created
|
39
|
+
And ruby gem for 'my_project' version '0.1.0' do exist in 'pkg'
|
40
|
+
And a gem for 'my_project' version '0.1.0' platform 'universal-unknown' do exist in 'pkg'
|
@@ -0,0 +1,43 @@
|
|
1
|
+
Given /^a extension named '(.*)'$/ do |extension_name|
|
2
|
+
generate_extension_task_for extension_name
|
3
|
+
generate_source_code_for extension_name
|
4
|
+
end
|
5
|
+
|
6
|
+
Given /^a extension cross-compilable '(.*)'$/ do |extension_name|
|
7
|
+
generate_cross_compile_extension_task_for extension_name
|
8
|
+
generate_source_code_for extension_name
|
9
|
+
end
|
10
|
+
|
11
|
+
Given /^a extension '(.*)' with forced platform '(.*)'$/ do |extension_name, forced_platform|
|
12
|
+
generate_extension_task_for extension_name, forced_platform
|
13
|
+
generate_source_code_for extension_name
|
14
|
+
end
|
15
|
+
|
16
|
+
Given /^that all my source files are in place$/ do
|
17
|
+
Given "a safe project directory"
|
18
|
+
Given "a extension cross-compilable 'extension_one'"
|
19
|
+
end
|
20
|
+
|
21
|
+
Given /^that my gem source is all in place$/ do
|
22
|
+
Given "a safe project directory"
|
23
|
+
Given "a gem named 'gem_abc'"
|
24
|
+
Given "a extension cross-compilable 'extension_one'"
|
25
|
+
end
|
26
|
+
|
27
|
+
Given /^not changed any file since$/ do
|
28
|
+
# don't do anything, that's the purpose of this step!
|
29
|
+
end
|
30
|
+
|
31
|
+
When /^touching '(.*)' file of extension '(.*)'$/ do |file, extension_name|
|
32
|
+
Kernel.sleep 1
|
33
|
+
FileUtils.touch "ext/#{extension_name}/#{file}"
|
34
|
+
end
|
35
|
+
|
36
|
+
Then /^binary extension '(.*)' (do|do not) exist in '(.*)'$/ do |extension_name, condition, folder|
|
37
|
+
ext_for_platform = File.join(folder, "#{extension_name}.#{RbConfig::CONFIG['DLEXT']}")
|
38
|
+
if condition == 'do'
|
39
|
+
File.exist?(ext_for_platform).should be_true
|
40
|
+
else
|
41
|
+
File.exist?(ext_for_platform).should be_false
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Naive way of looking into platforms, please include others like FreeBSD?
|
2
|
+
Given %r{^I'm running a POSIX operating system$} do
|
3
|
+
unless RUBY_PLATFORM =~ /linux|darwin/ then
|
4
|
+
raise Cucumber::Pending.new("You need a POSIX operating system, no cheating ;-)")
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
Given %r{^I've installed cross compile toolchain$} do
|
9
|
+
compiler = 'i586-mingw32msvc-gcc'
|
10
|
+
found = false
|
11
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
12
|
+
next unless File.exist?(File.join(path, compiler))
|
13
|
+
found = true
|
14
|
+
end
|
15
|
+
raise "Cannot locate '#{compiler}' in the PATH." unless found
|
16
|
+
end
|
17
|
+
|
18
|
+
Then /^binaries for platform '(.*)' get generated$/ do |platform|
|
19
|
+
ext_for_platform = Dir.glob("tmp/#{platform}/**/*.#{RbConfig::CONFIG['DLEXT']}")
|
20
|
+
ext_for_platform.should_not be_empty
|
21
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
Given %r{^I've already successfully executed rake task '(.*)'$} do |task_name|
|
2
|
+
emptyness = `rake #{task_name} 2>&1`
|
3
|
+
unless $?.success?
|
4
|
+
warn emptyness
|
5
|
+
raise "rake failed with #{$?.exitstatus}"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
When /^rake task '(.*)' is invoked$/ do |task_name|
|
10
|
+
@output ||= {}
|
11
|
+
@result ||= {}
|
12
|
+
@output[task_name] = `rake #{task_name} 2>&1`
|
13
|
+
@result[task_name] = $?.success?
|
14
|
+
end
|
15
|
+
|
16
|
+
Then /^rake task '(.*)' succeeded$/ do |task_name|
|
17
|
+
if @result.nil? || !@result.include?(task_name) then
|
18
|
+
raise "The task #{task_name} should be invoked first."
|
19
|
+
else
|
20
|
+
@result[task_name].should be_true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
Then /^output of rake task '(.*)' (contains|do not contain) \/(.*)\/$/ do |task_name, condition, regex|
|
25
|
+
if condition == 'contains' then
|
26
|
+
@output[task_name].should match(%r(#{regex}))
|
27
|
+
else
|
28
|
+
@output[task_name].should_not match(%r(#{regex}))
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
Given /^a safe project directory$/ do
|
2
|
+
# step back to ROOT
|
3
|
+
Dir.chdir ROOT_PATH
|
4
|
+
tmp_name = "project.#{Process.pid}"
|
5
|
+
@safe_dir = File.join(ROOT_PATH, 'tmp', tmp_name)
|
6
|
+
FileUtils.rm_rf @safe_dir
|
7
|
+
FileUtils.mkdir_p @safe_dir
|
8
|
+
Dir.chdir @safe_dir
|
9
|
+
|
10
|
+
generate_scaffold_structure
|
11
|
+
end
|
12
|
+
|
13
|
+
Given /^'(.*)' folder (exist|is deleted)$/ do |folder, condition|
|
14
|
+
case condition
|
15
|
+
when 'exist'
|
16
|
+
raise "Folder #{folder} do not exist" unless File.exist?(folder) && File.directory?(folder)
|
17
|
+
when 'is deleted'
|
18
|
+
FileUtils.rm_rf folder
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Then /^'(.*)' folder is created$/ do |folder|
|
23
|
+
File.directory?(folder).should be_true
|
24
|
+
end
|
25
|
+
|
26
|
+
Then /^'(.*)' folder do not exist$/ do |folder|
|
27
|
+
File.directory?(folder).should_not be_true
|
28
|
+
end
|
29
|
+
|
30
|
+
Then /^no left over from '(.*)' remains in '(.*)'$/ do |name, folder|
|
31
|
+
Dir.glob("#{folder}/**/#{name}").should be_empty
|
32
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Given /^a gem named '(.*)'$/ do |gem_name|
|
2
|
+
generate_gem_task gem_name
|
3
|
+
end
|
4
|
+
|
5
|
+
Then /^ruby gem for '(.*)' version '(.*)' do exist in '(.*)'$/ do |name, version, folder|
|
6
|
+
File.exist?(gem_file(folder, name, version)).should be_true
|
7
|
+
end
|
8
|
+
|
9
|
+
Then /^binary gem for '(.*)' version '(.*)' do exist in '(.*)'$/ do |name, version, folder|
|
10
|
+
File.exist?(gem_file_platform(folder, name, version)).should be_true
|
11
|
+
end
|
12
|
+
|
13
|
+
Then /^a gem for '(.*)' version '(.*)' platform '(.*)' do exist in '(.*)'$/ do |name, version, platform, folder|
|
14
|
+
File.exist?(gem_file_platform(folder, name, version, platform)).should be_true
|
15
|
+
end
|
16
|
+
|
17
|
+
Then /^gem for platform '(.*)' get generated$/ do |platform|
|
18
|
+
Then "a gem for 'gem_abc' version '0.1.0' platform '#{platform}' do exist in 'pkg'"
|
19
|
+
end
|
20
|
+
|
21
|
+
def gem_file(folder, name, version)
|
22
|
+
"#{folder}/#{name}-#{version}.gem"
|
23
|
+
end
|
24
|
+
|
25
|
+
def gem_file_platform(folder, name, version, platform = nil)
|
26
|
+
file = "#{folder}/#{name}-#{version}"
|
27
|
+
file << "-" << (platform || Gem::Platform.local.to_s)
|
28
|
+
file << ".gem"
|
29
|
+
end
|