rake-compiler 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|