pax_global_header00006660000000000000000000000064133421544760014523gustar00rootroot0000000000000052 comment=87b89f825780b1e4fd289c4871e1b9dfd413f9fa rake-compiler-1.0.5/000077500000000000000000000000001334215447600142605ustar00rootroot00000000000000rake-compiler-1.0.5/.gitignore000066400000000000000000000001061334215447600162450ustar00rootroot00000000000000/.ruby-version /.rvmrc /Gemfile.lock /coverage/ /doc/api/ /pkg/ /tmp/ rake-compiler-1.0.5/.travis.yml000066400000000000000000000003311334215447600163660ustar00rootroot00000000000000language: ruby notifications: recipients: - rake-compiler@ml.commit-email.info before_script: - gem update bundler rvm: - 2.1.2 - 2.2 - 2.3.0 - ruby-head matrix: allow_failures: - rvm: ruby-head rake-compiler-1.0.5/Gemfile000066400000000000000000000001731334215447600155540ustar00rootroot00000000000000source "https://rubygems.org" gem "rake" group :development do gem "rspec", "~> 3.0" gem "cucumber", "~> 2.0" end rake-compiler-1.0.5/History.txt000066400000000000000000000315571334215447600164750ustar00rootroot00000000000000=== 1.0.5 / 2018-08-31 * Enhancements: * Improve JRuby class pass detection. #147 [Patch by Prashant Vithani] * Update the default source and target versions to Java 6. #148 [Patch by Prashant Vithani] === 1.0.4 / 2017-05-27 * Enhancements: * Migrate to RSpec 3 from RSpec 2. * Add more tests. #140 [Patch by Lars Kanis] * Support C++ source files by default. #141 [Patch by Takashi Kokubun] * Suppress warnings. #142 [Patch by Akira Matsuda] === 1.0.3 / 2016-12-02 * Enhancements: * Support specifying required Ruby versions. #137 [Patch by Lars Kanis] === 1.0.2 / 2016-11-13 * Bugfixes: * Fix Ruby version detection example code in README. #135 [Patch by Nicolas Noble] * Fix version detection. #136 [Patch by Lars Kanis] === 1.0.1 / 2016-06-21 * Bugfixes: * Add missing dependency. === 1.0.0 / 2016-06-21 * Enhancements: * Really support extension in sub directory. === 0.9.9 / 2016-05-10 * Bugfixes: * Support Symbol as extension name again. #134 [Patch by Takashi Kokubun] === 0.9.8 / 2016-04-29 * Enhancements: * Support extension in sub directory. #128, #129 [Patch by Kenta Murata] === 0.9.7 / 2016-03-16 * Bugfixes: * May fix "make" detection on Windows. #123 [Reported by Aaron Stone] === 0.9.6 / 2016-03-04 * Enhancements: * Add more descriptions into README. Closes #105 [Patch by Aaron Stone] * Remove needless executable bits. Closes #107 [Patch by Thibault Jouan] * Update .gitignore. Closes #108 [Patch by Thibault Jouan] * Improve "make" detection on some platforms such as FreeBSD. Closes #109 [Patch by Thibault Jouan] * Enable cucumber steps for POSIX on *BSD. Closes #110 [Patch by Thibault Jouan] * Stop to build bundled extensions. * Add description about CLI option into README. Closes #115 [Patch by Richard Michael] * Update description about using rake-compiler on virtual machine in README. Closes #116, #117 [Patch by Lars Kanis] * Update fake mechanism to be compatible with Bundler. Closes #121 [Patch by Lars Kanis] * Bugfixes: * Fix typos in README. Closes #102, #103 [Patch by Robert Fletcher] === 0.9.5 / 2015-01-03 * Enhancements: * Support adding bundled files in cross_compiling block. Closes #100 [Patch by Aaron Stone] === 0.9.4 / 2014-12-28 * Notes: * Change maintainer to Kouhei Sutou from Luis Lavena. Thanks Luis Lavena for your great works! * Change repository to https://github.com/rake-compiler/rake-compiler from https://github.com/luislavena/rake-compiler . * Bugfixes: * Loose RubyGems dependency a little bit to ease old Debian/Ubuntu. Closes #93 === 0.9.3 / 2014-08-03 * Bugfixes: * Fix specs to run (and pass) on Ruby 2.1 and beyond. Pull #94 [hggh] === 0.9.2 / 2013-11-14 * Bugfixes: * Pre-load resolver to avoid Bundler blow up during cross-compilation Pull #83 [larskanis] === 0.9.1 / 2013-08-03 * Bugfixes: * Restore compatibility with RubyGems platforms for cross-compilation (i386-mingw32 and x86-mingw32 are the same and supported) === 0.9.0 / 2013-08-03 * Enhancements: * Add support for cross-builds and multiple platforms (x86/x64). Pull #74 [larskanis] $ rake-compiler cross-ruby VERSION=1.8.7-p371 $ rake-compiler cross-ruby VERSION=1.9.3-p392 $ rake-compiler cross-ruby VERSION=2.0.0-p0 $ rake-compiler cross-ruby VERSION=2.0.0-p0 HOST=x86_64-w64-mingw32 $ rake cross compile RUBY_CC_VERSION=1.8.7:1.9.3:2.0.0 # Rakefile ext.cross_platform = %w[i386-mingw32 x64-mingw32] * Support for cross-platform specific options. Pull #74 [larskanis] # Rakefile ext.cross_config_options << "--with-common-option" ext.cross_config_options << {"x64-mingw32" => "--enable-64bits"} * Bugfixes: * Correct fat-gems support caused by RubyGems issues. Pull #76 [knu] * Deprecations: * Requires minimum Ruby 1.8.7 and RubyGems 1.8.25 * Usage of 'i386-mswin32' needs to be changed to 'i386-mswin32-60' === 0.9.0.pre.1 / 2013-05-05 See 0.9.0 changes. === 0.8.3 / 2013-02-16 * Bugfixes: * Support FreeBSD 'mingw32-gcc' cross compiler. Closes #72 [knu] === 0.8.2 / 2013-01-11 * Bugfixes: * Unset CC, LDFLAGS and CPPFLAGS prior cross-compiling. Closes #55 === 0.8.1 / 2012-04-15 * Bugfixes: * Raise error when either make or gmake could be found. Closes #53, #54 === 0.8.0 / 2012-01-08 * Enhancements: * Invocation from command line now support extra options similar to RubyGems. Closes #4 from Pull #47 [jonforums] $ rake compile -- --with-opt-dir=/opt/local * Bugfixes: * Only emit cross-compilation warnings for C when `cross` is invoked. Closes #16 from Pull #48 [mvz] * Only emit warnings when invoking cross-compilation tasks for JRuby. Pull #45 [jfirebaugh] * Use x86 MinGW cross-compiler. Pull #49 [larskanis] === 0.7.9 / 2011-06-08 * Enhancements: * Consistently use RubyGems features available since version 1.3.2 and avoid deprecation warnings with Rake > 0.8.7. * Bugfixes: * Use correct platform in fake.rb. Pull #39 [kou] * Workaround Gem::Specification and Gem::PackageTask limitations. Closes #43 === 0.7.8 / 2011-04-26 * Enhancements: * Bump default cross-ruby version to 1.8.7-p334. * ExtensionTask now support config_includes to load additional directories. [jfinkhaeuser] Rake::ExtensionTask.new("myext", GEM_SPEC) do |ext| ext.config_includes << File.expand_path("my", "custom", "dir") end * Bugfixes: * Warn if compiled files exists in extension's source directory. Closes GH-35 * Workaround issue with WINE using proper build option. Closes GH-37 * Use FileUtils#install instead of cp. Closes GH-33 [Eric Wong] * Update README instructions for OSX. Closes GH-29 [tmm1] === 0.7.7 / 2011-04-04 * Bugfixes: * Use Winsock2 as default to match Ruby 1.9.2 library linking. === 0.7.6 / 2011-02-04 * Bugfixes: * Prefer Psych over Syck for YAML parsing on Ruby 1.9.2. [tenderlove] === 0.7.5 / 2010-11-25 * Enhancements: * Promoted stable version for cross-compilation to 1.8.6-p398. Closes GH-19 * Bugfixes: * Generate a fake.rb compatible with Ruby 1.9.2. Closes GH-25 * fake.rb will not try to mimic Ruby's own fake to the letter. Closes GH-28 * Expand symlinks for tmp_dir. Closes GH-24 * Silence make output during rake-compiler invocation. * Usage of Gem.ruby instead of RbConfig ruby_install_name This solve issues with ruby vs. ruby.exe and jruby.exe * Experimental: * Allow setting of HOST during cross-compilation. This enable usage of mingw-w64 compiler and not the first one found in the PATH. rake-compiler cross-ruby VERSION=1.9.2-p0 HOST=i686-w64-mingw32 rake-compiler cross-ruby HOST=i386-mingw32 (OSX mingw32 port) rake-compiler cross-ruby HOST=i586-pc-mingw32 (Debian/Ubuntu mingw32) === 0.7.1 / 2010-08-07 * Bugfixes: * Update gem files to make "gem install -t" works. Closes GH-14 * Update mocks to work under 1.8.7. Closes GH-15 [luisparravicini] * Do not allow cross-ruby be executed under Windows. Closes GH-22 * Experimental: * Allow JRuby to compile C extensions [timfel]. It is now possible compile C extensions using latest JRuby. Offered in experimental mode since JRuby cext hasn't been officially released. === 0.7.0 / 2009-12-08 * Enhancements * Allow generation of JRuby extensions. Thanks to Alex Coles (myabc) for the contribution. This will allow, with proper JDK tools, cross compilation of JRuby gems from MRI. Rake::JavaExtensionTask.new('my_java_extension', GEM_SPEC) do |ext| # most of ExtensionTask options can be used # plus, java_compiling: ext.java_compiling do |gem_spec| gem_spec.post_install_message = "This is a native JRuby gem!" end end Please note that cross-compiling JRuby gems requires either JRUBY_HOME or JRUBY_PARENT_CLASSPATH environment variables being properly set. * Allow alteration of the Gem Specification when cross compiling. Closes GH-3 This is useful to indicate a custom requirement message, like DLLs installation or similar. Rake::ExtensionTask.new('my_extension', GEM_SPEC) do |ext| ext.cross_compile = true # ... ext.cross_compiling do |gem_spec| gem_spec.post_install_message = "You've installed a binary version of this gem" end end * Bugfixes * Detect GNU make independently of distribution based naming. Thanks to flori for patches. * Usage of #dup to duplicate gemspec instead of YAML dumping. * No longer support Ruby older than 1.8.6 * No longer support RubyGems older than 1.3.5 * Force definition of binary directory and executables. Closes GH-11 * Workaround path with spaces issues using relative paths. Closes GH-6 * Removed gemspec, GitHub gems no more * Known issues * Usage of rake-compiler under projects with Jeweler requires some tweaks Please read issue GH-73 for Jeweler: http://github.com/technicalpickles/jeweler/issues#issue/73 For a workaround, look here: http://gist.github.com/251663 === 0.6.0 / 2009-07-25 * Enhancements * Implemented 'fat-binaries' generation for cross compiling (for now). Thanks to Aaron Patterson for the suggestion and original idea. rake cross native gem RUBY_CC_VERSION=1.8.6:1.9.1 Will package extensions for 1.8 and 1.9 versions of Ruby. * Can now cross compile extensions for 1.9 using 1.8.x as base. Be warned: works from 1.8 to 1.9, but not if your default ruby is 1.9 rake cross compile RUBY_CC_VERSION=1.9.1 * Allow simultaneous versions of Ruby to compile extensions. This change allow 1.8.x compiles co-exist with 1.9.x ones and don't override each other. Please perform rake clobber prior compiling again. * Allow optional source file URL for cross-compile tasks. (Thanks to deepj for the patches) rake-compiler cross-ruby VERSION=1.9.1-p0 SOURCE=http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.1-p0.tar.bz2 * Bugfixes * Removed strict versioning for gems since it clash with fat binaries. From now on, if your gem only targets a specific version of Ruby, please indicate it in the Gem::Specification (required_ruby_version) === 0.5.0 / 2009-04-25 * Enhancements * Allow generation of multiple gems for Windows (EXPERIMENTAL) This allows build gems for both VC6 and MinGW builts of Ruby (Thanks to Jonathan Stott for the suggestion) Rake::ExtensionTask.new('my_extension', GEM_SPEC) do |ext| ext.cross_compile = true ext.cross_platform = ['i386-mswin32', 'i386-mingw32'] end === 0.4.1 / 2009-04-09 * Enhancements * Target specific versions of Ruby when generating binaries. This avoids installing a 1.8.x binary gem in 1.9.x and viceversa. (Thanks to Aaron Patterson for the patches) * Bugfixes * No longer raises error if rake-compiler configuration is missing. Not all users of a project would have it installed. (Thanks to Aaron Patterson for the patch) === 0.4.0 / 2009-04-03 * Enhancements * Bended the convention for extension folder. Defining ext_dir for custom extension location. Rake::ExtensionTask.new('my_extension') do |ext| ext.ext_dir = 'custom/location' # look into custom/location end # instead of ext/my_extension * Better detection of mingw target across Linux/OSX. Exposed it as Rake::ExtensionCompiler * Display list of available tasks when calling rake-compiler script * Track Ruby full versioning (x.y.z). This will help the compilation of extensions targetting 1.8.6/7 and 1.9.1 * Bugfixes * Better output of Rake development tasks (Thanks to Luis Parravicini). * Proper usage of Gem::Platform for native gems (Thanks to Dirkjan Bussink). * Don't use autoload for YAML (present problems with Ruby 1.9.1). === 0.3.1 / 2009-01-09 * Enhancements * Download cross-ruby source code using HTTP instead of FTP. * Disabled Tcl/Tk extension building on cross-ruby (helps with 1.9). * Bugfixes * Workaround bug introduced by lack of Gem::Specification cloning. Fixes DM LH #757. * Use proper binary extension on OSX (reported by Dirkjan Bussink). * Ensure lib/binary task is defined prior clear of requisites. === 0.3.0 / 2008-12-07 * New features * Let you specify the Ruby version used for cross compilation instead of default one. rake cross compile RUBY_CC_VERSION=1.8 * Enhancements * Properly update rake-compiler configuration when new version is installed. * Automated release process to RubyForge, yay! * Bugfixes * Corrected documentation to reflect the available options === 0.2.1 / 2008-11-30 * New features * Allow cross compilation (cross compile) using mingw32 on Linux or OSX. * Allow packaging of gems for Windows on Linux or OSX. * Enhancements * Made generation of extensions safe and target folders per-platform * Bugfixes * Ensure binaries for the specific platform are copied before packaging. rake-compiler-1.0.5/LICENSE.txt000066400000000000000000000020451334215447600161040ustar00rootroot00000000000000Copyright (c) 2008-2011 Luis Lavena. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. rake-compiler-1.0.5/README.rdoc000066400000000000000000000365021334215447600160740ustar00rootroot00000000000000= What is rake-compiler? rake-compiler is first and foremost a productivity tool for Ruby developers. Its goal is to make the busy developer's life easier by simplifying the building and packaging of Ruby extensions by simplifying code and reducing duplication. It follows *convention over configuration* by advocating a standardized build and package structure for both C and Java based RubyGems. rake-compiler is the result of many hard-won experiences dealing with several diverse RubyGems that provided native extensions for different platforms and different user configurations in different ways. Details such as differences in code portability, differences in code clarity, and differences in project directory structure often made it very difficult for newcomers to those RubyGems. From these challenges, rake-compiler was born with the single-minded goal of making the busy RubyGem developer's life much less difficult. == Feature Overview Some of the benefits rake-compiler provides include: * No custom rake tasks required. Less code duplication and errors. * Painlessly build extensions on different platforms (Linux, OSX and Windows). * Painlessly build extensions for different Ruby implementations (JRuby, Rubinius and MRI). * Allow multiple extensions to be compiled inside the same gem. * Painlessly build "fat" native gems for Windows users (from Linux or OSX). * Mimics RubyGems standard installation process, helping as a test environment. * Simplifies cross platform extension compilation (targeting Windows from Linux). == OK, I'm sold! Show me how to install it! Simple: $ gem install rake-compiler == That's easy. How do I use it? Now that you have installed rake-compiler, it's time to give your project a standardized structure. === Using a standardized project structure Let's say you want to compile an extension called 'hello_world'. Organizing your project's code tree in the following way will help rake-compiler do its job: |-- ext | `-- hello_world | |-- extconf.rb | |-- HelloWorldService.java | `-- hello_world.c |-- lib `-- Rakefile TIP: Having a consistent project directory structure will help developers and newcomers find and understand your code, making it easier for them to contribute back to your project. === Adding the code to enable rake-compiler Now the fun part. It's time to introduce the code to your projects Rakefile to tell it to use rake-compiler to build your extension: # File: extconf.rb # these lines must exist already require 'mkmf' create_makefile('hello_world') # File: Rakefile require 'rake/extensiontask' Rake::ExtensionTask.new('hello_world') That's it? Yes, that's it! No other lines of code are needed for rake-compiler to work its magic. Though, you need to make sure the parameter to create_makefile and ExtensionTask.new are the same or rake-compiler will not mimic the RubyGems standard install process. You can override this standard behaviour if needed, see the instructions for "non-standard project structure" below for details. If you want to do the same for a JRuby extension written in Java, it's just as easy: # File: Rakefile require 'rake/javaextensiontask' Rake::JavaExtensionTask.new('hello_world') === The simple process Those *two* simple lines of code automatically added the Rake tasks needed to build your 'hello_world' extension. For example, checking the Rake tasks on MRI Ruby 1.8.x/1.9 returns something similar to: $ rake -T (in /home/user/my_extension) rake compile # Compile the extension(s) rake compile:hello_world # Compile just the hello_world extension Simply calling compile like $ rake compile performs the entire compile and build process for you and places the resulting extension inside the lib directory of your project. To pass dir_config options to the compilation, add to the command line: $ rake compile -- --with-foo-[dir|lib|bin|...]=/path/to/foo NOTE: Please be aware that building C extensions requires the proper development environment for your Platform, including libraries, headers and build tools. Check your distro / vendor documentation on how to install these development resources. NOTE: Building Java extensions requires the javac, part of the Java Development Kit (JDK). This should be included by default on Mac OS X, and downloadable from http://java.sun.com for other operating systems. === Generating native RubyGems A common usage scenario for rake-compiler is generating native gems that bundle your extensions. As mentioned above, if you have your development environment configured correctly, the following examples work even when building native gems on Windows systems. Creating native gems is really easy with rake-compiler's Rake::ExtensionTask: # somewhere in your Rakefile, define your gem spec spec = Gem::Specification.new do |s| s.name = "my_gem" s.platform = Gem::Platform::RUBY s.extensions = FileList["ext/**/extconf.rb"] end # add your default gem packing task Gem::PackageTask.new(spec) do |pkg| end # feed the ExtensionTask with your spec Rake::ExtensionTask.new('hello_world', spec) As expected, you can still build your pure-ruby gem in the usual way (standard output) by running: $ rake gem (in /projects/oss/my_gem.git) mkdir -p pkg Successfully built RubyGem Name: my_gem Version: 0.1.0 File: my_gem-0.1.0.gem mv my_gem-0.1.0.gem pkg/my_gem-0.1.0.gem Plus, rake-compiler tasks give you the extra functionality needed to build native gems by running: # rake native gem (... compilation output ...) mkdir -p pkg Successfully built RubyGem Name: my_gem Version: 0.1.0 File: my_gem-0.1.0.gem mv my_gem-0.1.0.gem pkg/my_gem-0.1.0.gem Successfully built RubyGem Name: my_gem Version: 0.1.0 File: my_gem-0.1.0-x86-mingw32.gem mv my_gem-0.1.0-x86-mingw32.gem pkg/my_gem-0.1.0-x86-mingw32.gem Did you notice that you get two gems for the price of one? How's that for a time saver? Similarly, it's just as easy to do the same thing for JRuby extensions: # rake java gem (... compilation output ...) mkdir -p pkg Successfully built RubyGem Name: my_gem Version: 0.1.0 File: my_gem-0.1.0.gem mv my_gem-0.1.0.gem pkg/my_gem-0.1.0.gem Successfully built RubyGem Name: my_gem Version: 0.1.0 File: my_gem-0.1.0-java.gem mv my_gem-0.1.0-java.gem pkg/my_gem-0.1.0-java.gem === Great, but can I use a non-standard project structure? Yes you can! While the conventional project structure is recommended, you may want, or need, to tweak those conventions. Rake-compiler allows you to customize several settings for Rake::ExtensionTask: Rake::ExtensionTask.new do |ext| ext.name = 'hello_world' # indicate the name of the extension. ext.ext_dir = 'ext/weird_world' # search for 'hello_world' inside it. ext.lib_dir = 'lib/my_lib' # put binaries into this folder. ext.config_script = 'custom_extconf.rb' # use instead of the default 'extconf.rb'. ext.tmp_dir = 'tmp' # temporary folder used during compilation. ext.source_pattern = "*.{c,cpp}" # monitor file changes to allow simple rebuild. ext.config_options << '--with-foo' # supply additional options to configure script. ext.gem_spec = spec # optionally indicate which gem specification # will be used. end == Cross compilation - the future is now. Rake-compiler also provides a standardized way to generate, from either Linux or OSX, extensions and gem binaries for your Windows users! How can this be you say? Simple, rake-compiler's cross compilation features take advantage of GCC's host/target capabilities to build 'target' binaries on different 'host' OS's. === How do I do this from Linux or OSX? ==== The Easy Way Use rake-compiler-dock, a gem that makes use of a virtual machine provisioned with all the necessary build tools. You can add a task to your Rakefile, that cross-compiles and packages your gem into Windows fat binaries (with 1.8 to 2.2 and x86/x64 support). See https://github.com/rake-compiler/rake-compiler-dock for more information. ==== The Manual Way In addition to having the development tool chain installed (GCC), you also need to install your platform's mingw32 cross compilation package. Installation depends upon your operating system/distribution. On Ubuntu and Debian host machines, a simple apt-get install mingw32 will be enough. On Arch, mingw32 is installed by running pacman -S mingw32-gcc On OSX, we no longer recommend the usage of MacPorts mingw32 package because it stagnated in GCC version 3.4.5. Instead we recommend you download mingw-w64 automated build packages available at SourceForge: http://sourceforge.net/downloads/mingw-w64/ Browse into Toolchains targetting Win32 and then Automated Builds. Files will be ordered by recency, find the latest one with version 1.0 in it, like this one: mingw-w32-1.0-bin_i686-darwin_20110422.tar.bz2 Download and extract. After that, make sure the bin directory is added to the PATH, eg: export PATH=~/mingw-w64/w32/bin:$PATH You can add this to your .profile to avoid the repitition. ==== I've got my tool-chain installed, now what? First, you need to build Ruby for Windows on your Linux or OSX system. Relax, no need to freak out! Let rake-compiler do all the heavy lifting for you: rake-compiler cross-ruby And you're done. It will automatically download, configure and compile the latest stable version of Ruby for Windows, and place it into your ~/.rake-compiler directory. This will create ~/.rake-compiler/config.yml file so that rake-compiler knows where to find the rbconfig.rb file that matches the Ruby version on the Windows host system you're cross-compiling for. An example: # File: ~/.rake-compiler/config.yml rbconfig-x86-mingw32-1.8.6: /path/to/ruby-1.8.6/rbconfig.rb rbconfig-x86-mingw32-1.8.7: /path/to/ruby-1.8.7/rbconfig.rb rbconfig-x86-mingw32-1.9.2: /path/to/ruby-1.9.2/rbconfig.rb If, instead, you want to build a different Ruby version than the default one, please supply a VERSION: rake-compiler cross-ruby VERSION=1.8.6-p114 If you, like me, have multiple versions of MinGW packages installed, you can specify the HOST that will be used to cross compile Ruby: rake-compiler cross-ruby HOST=x86-mingw32 # (OSX mingw32 port) The host will vary depending on provider (mingw32 versus mingw-w64 projects). Please consult the documentation and website of the MinGW package provider before reporting any issues. ==== OK, let's cross compile some gems! Now, you only need specify a few additional options in your extension definition: Rake::ExtensionTask.new('my_extension', gem_spec) do |ext| # enable cross compilation (requires cross compile toolchain) ext.cross_compile = true # set a single platform or an array of platforms to target ext.cross_platform = ['x86-mingw32', 'x64-mingw32'] # cross-compile options will be passed to extconf.rb for each # platform build, with platform-specific options in a hash. ext.cross_config_options << '--with-common-option' ext.cross_config_options << { 'x86-mswin32-60 => '--with-some-option', 'x64-mingw32' => '--enable-64bits', } ext.cross_config_options << '--with-final-option' # perform alterations on the gemspec when cross compiling ext.cross_compiling do |gem_spec| # such as packaging a file that isn't specified in the gemspec gem_spec.files << 'lib/generated_file.rb' # or adding a new installation message gem_spec.post_install_message = "You installed the binary version of this gem!" end end By default, cross compilation targets 'i386-mingw32' which is the default GCC platform for Ruby. MRI Ruby's current official distribution uses i386-mswin32-60. The RubyInstaller distribution uses x86-mingw32 and x64-mingw32 for 32-bit and 64-bit Windows targets, respectively. Note that i386 and x86 are synonymous here; x86 is preferred going forward. The format for cross_config_options is an array of strings and hashes. Hashes will be fetched for each value of cross_platform as the build iterates, or ignored if there is no value for that platform. You can mix-and-match strings and hashes to get desired option ordering. ==== Warning, magician about to do some tricks, don't blink! Cross compiling is still very simple: rake cross compile And now, building gems for your Windows users is just 6 more letters: rake cross native gem And you're done, yeah. ==== But wait, there's more You can specify which version of Ruby to build the extension against: rake cross compile RUBY_CC_VERSION=1.8.6 For example, if you installed 1.9.2, you can do: rake cross compile RUBY_CC_VERSION=1.9.2 Even better, you can target multiple versions (ie. 1.8.6 and 1.9.2) in the same gem via: rake cross compile RUBY_CC_VERSION=1.8.6:1.9.2 And better yet, you can bundle both binary extensions into one so-called "fat" gem via: rake cross native gem RUBY_CC_VERSION=1.8.6:1.9.2 That will place binaries for both the 1.8 and 1.9 versions of your Ruby extensions inside your project's lib_dir directory: lib/1.8/my_extension.so lib/1.9/my_extension.so NOTE: building "fat" gems is currently only supported by rake-compiler when cross compiling from a Linux or OSX host. Patches are welcome if building "fat" gems from Windows hosts is desired, or natively for your platform :-) Now it's up to you to make your gem load the proper binary at runtime: begin RUBY_VERSION =~ /(\d+\.\d+)/ require "#{$1}/my_extension" rescue LoadError require "my_extension" end The above technique will lookup first for 1.8 or 1.9 version of the extension and when not found, will look for the plain extension. This approach catch the cases of provided fat binaries or gems compiled by the end user installing the gem. It has also been implemented successfully in several projects. == What are you talking about? (Give me examples) I know all the above sounds like a complete foreign language (it does even for me!). So, what if I show you some examples? Check our wiki with links to the proper rake files used by many developers and projects and how they use rake-compiler. http://github.com/rake-compiler/rake-compiler/wiki/projects-using-rake-compiler == Future rake-compiler is a work in progress and we appreciate any and all feedback during the development of it! (and contributions too!) You can find more information about rake-compiler: * GitHub: https://github.com/rake-compiler/rake-compiler * Issues: https://github.com/rake-compiler/rake-compiler/issues * Docs: http://rubydoc.info/gems/rake-compiler * Wiki: https://github.com/rake-compiler/rake-compiler/wiki == Disclaimer If you have any trouble, don't hesitate to contact the author. As always, I'm not going to say "Use at your own risk" because I don't want this library to be risky. If you trip on something, I'll share the liability by repairing things as quickly as I can. Your responsibility is to report the inadequacies. rake-compiler-1.0.5/Rakefile000066400000000000000000000004631334215447600157300ustar00rootroot00000000000000#-- # Copyright (c) 2008 Luis Lavena # # This source code is released under the MIT License. # See LICENSE file for details #++ # # NOTE: Keep this file clean. # Add your customizations inside tasks directory. # Thank You. # # load rakefile extensions (tasks) Dir['tasks/*.rake'].sort.each { |f| load f } rake-compiler-1.0.5/appveyor.yml000066400000000000000000000006311334215447600166500ustar00rootroot00000000000000--- version: "{build}" branches: only: - master clone_depth: 10 install: - SET PATH=C:\Ruby%ruby_version%\bin;%PATH% - ruby --version - gem --version - gem install bundler --quiet --no-ri --no-rdoc - bundler --version - bundle install build: off test_script: - bundle exec rake spec environment: matrix: - ruby_version: "193" - ruby_version: "200" - ruby_version: "200-x64" rake-compiler-1.0.5/bin/000077500000000000000000000000001334215447600150305ustar00rootroot00000000000000rake-compiler-1.0.5/bin/rake-compiler000077500000000000000000000007361334215447600175160ustar00rootroot00000000000000#!/usr/bin/env ruby #-- # Copyright (c) 2008 Luis Lavena # # This source code is released under the MIT License. # See LICENSE file for details #++ begin require 'rake' rescue LoadError require 'rubygems' require 'rake' end # Initialize 'rake-compiler' application Rake.application.init('rake-compiler') # Load the already cooked tasks ;-) load File.join(File.dirname(__FILE__), %w{.. tasks bin cross-ruby.rake}) # delegate control to Rake Rake.application.top_level rake-compiler-1.0.5/cucumber.yml000066400000000000000000000002601334215447600166060ustar00rootroot00000000000000default: --tags ~@java --format progress features java: --tags @java --format progress features all: --format progress features autotest: --format progress features rake-compiler-1.0.5/features/000077500000000000000000000000001334215447600160765ustar00rootroot00000000000000rake-compiler-1.0.5/features/compile.feature000066400000000000000000000063211334215447600211050ustar00rootroot00000000000000Feature: Compile C code into Ruby extensions. In order to automate compilation process. As a Gem developer. I want rake tasks compile source code for me. Scenario: compile single extension Given a safe project directory And a extension named 'extension_one' And 'tmp' folder is deleted When rake task 'compile' is invoked Then rake task 'compile' succeeded And binary extension 'extension_one' do exist in 'lib' And 'tmp' folder is created Scenario: compile an extension with extra options Given a safe project directory And a extension named 'extension_one' And 'tmp' folder is deleted When rake task 'compile -- --with-opt-dir=/opt/local' is invoked Then rake task 'compile -- --with-opt-dir=/opt/local' succeeded And output of rake task 'compile -- --with-opt-dir=/opt/local' contains /with-opt-dir/ Scenario: not recompile unmodified extension Given a safe project directory And a extension named 'extension_one' And I've already successfully executed rake task 'compile' And not changed any file since When rake task 'compile' is invoked Then rake task 'compile' succeeded And output of rake task 'compile' do not contain /gcc|cl/ Scenario: recompile extension when source is modified Given a safe project directory And a extension named 'extension_one' And I've already successfully executed rake task 'compile' When touching 'source.c' file of extension 'extension_one' And rake task 'compile' is invoked Then rake task 'compile' succeeded And output of rake task 'compile' contains /extension_one/ Scenario: compile multiple extensions Given a safe project directory And a extension named 'extension_one' And a extension named 'extension_two' And 'tmp' folder is deleted When rake task 'compile' is invoked Then rake task 'compile' succeeded And binary extension 'extension_one' do exist in 'lib' And binary extension 'extension_two' do exist in 'lib' And 'tmp' folder is created Scenario: compile one extension instead of all present Given a safe project directory And a extension named 'extension_one' And a extension named 'extension_two' When rake task 'compile:extension_one' is invoked Then rake task 'compile:extension_one' succeeded And output of rake task 'compile:extension_one' do not contain /extension_two/ And binary extension 'extension_one' do exist in 'lib' And binary extension 'extension_two' do not exist in 'lib' Scenario: removing temporary files Given a safe project directory And a extension named 'extension_one' And I've already successfully executed rake task 'compile' When rake task 'clean' is invoked Then rake task 'clean' succeeded And binary extension 'extension_one' do exist in 'lib' And no left over from 'extension_one' remains in 'tmp' Scenario: clobbering binary and temporary files Given a safe project directory And a extension named 'extension_one' And I've already successfully executed rake task 'compile' When rake task 'clobber' is invoked Then rake task 'clobber' succeeded And binary extension 'extension_one' do not exist in 'lib' And 'tmp' folder do not exist rake-compiler-1.0.5/features/cross-compile.feature000066400000000000000000000020641334215447600222340ustar00rootroot00000000000000Feature: Cross-compile C extensions In order to avoid bitching from Windows users As a Ruby developer on Linux I want some rake tasks that take away the pain of compilation Scenario: compile single extension Given that all my source files are in place And I'm running a POSIX operating system And I've installed cross compile toolchain When rake task 'cross compile' is invoked Then rake task 'cross compile' succeeded And binaries for platform 'i386-mingw32' get generated Scenario: compile single extension to multiple versions Given that all my source files are in place And I'm running a POSIX operating system And I've installed cross compile toolchain When rake task 'cross compile RUBY_CC_VERSION=1.8.7:1.9.3:2.0.0' is invoked Then rake task 'cross compile RUBY_CC_VERSION=1.8.7:1.9.3:2.0.0' succeeded And binaries for platform 'i386-mingw32' version '1.8' get copied And binaries for platform 'i386-mingw32' version '1.9' get copied And binaries for platform 'i386-mingw32' version '2.0' get copied rake-compiler-1.0.5/features/cross-package-multi.feature000066400000000000000000000013041334215447600233230ustar00rootroot00000000000000Feature: Generate multiple Windows gems from Linux In order to keep compatibility with versions of Ruby on Windows As a Gem developer on Linux I want to build binary gems for One-Click Installer (old and new versions) Scenario: package multiple gems for Windows Given that my gem source is all in place to target two platforms And I'm running a POSIX operating system And I've installed cross compile toolchain And I've already successfully executed rake task 'cross compile' When rake task 'cross native gem' is invoked Then rake task 'cross native gem' succeeded And gem for platform 'x86-mswin32-60' get generated And gem for platform 'x86-mingw32' get generated rake-compiler-1.0.5/features/cross-package.feature000066400000000000000000000010671334215447600222010ustar00rootroot00000000000000Feature: Generate Windows gems from Linux In order to keep sanity in the Ruby world As a Gem developer on Linux I want more rake magic that turns monotony into joy. Scenario: package a gem for Windows Given that my gem source is all in place And I'm running a POSIX operating system And I've installed cross compile toolchain And I've already successfully executed rake task 'cross compile' When rake task 'cross native gem' is invoked Then rake task 'cross native gem' succeeded And gem for platform 'x86-mingw32' get generated rake-compiler-1.0.5/features/java-compile.feature000066400000000000000000000015041334215447600220220ustar00rootroot00000000000000Feature: JCompile Java extensions In order to avoid bitching from Enterprise users As a Ruby developer I want some rake tasks that take away the pain of compilation @java Scenario: Compile single Java extension (with default Rake) Given that all my Java source files are in place And I've installed the Java Development Kit When rake task 'java compile' is invoked Then rake task 'java compile' succeeded And binaries for platform 'java' get generated @java Scenario: Compile single Java extension (with Rake on JRuby) Given that all my Java source files are in place And I've installed the Java Development Kit When I've installed JRuby When rake task 'java compile' is invoked on JRuby Then rake task 'java compile' succeeded And binaries for platform 'java' get generated rake-compiler-1.0.5/features/java-no-native-compile.feature000066400000000000000000000030251334215447600237200ustar00rootroot00000000000000Feature: No native or cross compilation on JRuby In order to present a good user experience to users of rake-compiler As a user of JRuby I want to be warned that my platform does not provide any support for C Extensions I want to be be informed of this without rake-compiler blowing up in my face @java Scenario: Attempting to do a cross compilation while on JRuby (without prerequisites) Given that all my source files are in place And I'm running a POSIX operating system When rake task 'cross compile' is invoked on JRuby Then rake task 'cross compile' should fail And output of rake task 'cross compile' warns """ WARNING: You're attempting to (cross-)compile C extensions from a platform (jruby) that does not support native extensions or mkmf.rb. """ And output of rake task 'cross compile' contains /Don't know how to build task 'cross'/ @java Scenario: Attempting to do a cross compilation while on JRuby (even with prerequisites) Given that all my source files are in place And I'm running a POSIX operating system And I've installed cross compile toolchain When rake task 'cross compile' is invoked on JRuby Then rake task 'cross compile' should fail And output of rake task 'cross compile' warns """ WARNING: You're attempting to (cross-)compile C extensions from a platform (jruby) that does not support native extensions or mkmf.rb. """ And output of rake task 'cross compile' contains /Don't know how to build task 'cross'/ rake-compiler-1.0.5/features/java-package.feature000066400000000000000000000016731334215447600217740ustar00rootroot00000000000000Feature: Generate JRuby gems from JRuby or MRI In order to keep sanity in the Ruby world As a Gem developer who used to do J2EE development I want more rake magic that turns monotony into joy. @java Scenario: package a gem for Java (with default Rake) Given that my JRuby gem source is all in place And I've installed the Java Development Kit And I've already successfully executed rake task 'java compile' When rake task 'java gem' is invoked Then rake task 'java gem' succeeded And gem for platform 'java' get generated @java Scenario: package a gem for Java (with Rake on JRuby) Given that my JRuby gem source is all in place And I've installed the Java Development Kit And I've installed JRuby And I've already successfully executed rake task 'java compile' on JRuby When rake task 'java gem' is invoked Then rake task 'java gem' succeeded And gem for platform 'java' get generated rake-compiler-1.0.5/features/package.feature000066400000000000000000000032441334215447600210510ustar00rootroot00000000000000Feature: Distribute native extension with gems In order to avoid compiler toolchain requirement during installation As a Gem developer. I want rake tasks generate platform specific gems for me Scenario: generate pure ruby gem Given a safe project directory And a gem named 'my_project' And a extension named 'extension_one' And I've already successfully executed rake task 'compile' And 'pkg' folder is deleted When rake task 'gem' is invoked Then rake task 'gem' succeeded And 'pkg' folder is created And ruby gem for 'my_project' version '0.1.0' do exist in 'pkg' Scenario: generate native gem Given a safe project directory And a gem named 'my_project' And a extension named 'extension_one' And I've already successfully executed rake task 'compile' And 'pkg' folder is deleted When rake task 'native gem' is invoked Then rake task 'native gem' succeeded And 'pkg' folder is created And ruby gem for 'my_project' version '0.1.0' do exist in 'pkg' And binary gem for 'my_project' version '0.1.0' do exist in 'pkg' Scenario: generate forced native gem Given a safe project directory And a gem named 'my_project' And a extension 'extension_one' with forced platform 'universal-unknown' And I've already successfully executed rake task 'compile' And 'pkg' folder is deleted When rake task 'native:universal-unknown gem' is invoked Then rake task 'native:universal-unknown gem' succeeded And 'pkg' folder is created And ruby gem for 'my_project' version '0.1.0' do exist in 'pkg' And a gem for 'my_project' version '0.1.0' platform 'universal-unknown' do exist in 'pkg' rake-compiler-1.0.5/features/step_definitions/000077500000000000000000000000001334215447600214445ustar00rootroot00000000000000rake-compiler-1.0.5/features/step_definitions/compilation.rb000066400000000000000000000043761334215447600243210ustar00rootroot00000000000000Given /^a extension named '(.*)'$/ do |extension_name| generate_extension_task_for extension_name generate_source_code_for extension_name end Given /^a extension cross-compilable '(.*)'$/ do |extension_name| generate_cross_compile_extension_task_for extension_name generate_source_code_for extension_name end Given /^a extension Java-compilable '(.*)'$/ do |extension_name| generate_java_compile_extension_task_for extension_name generate_java_source_code_for extension_name end Given /^a extension '(.*)' multi cross\-compilable$/ do |extension_name| generate_multi_cross_compile_extension_task_for extension_name generate_source_code_for extension_name end Given /^a extension '(.*)' with forced platform '(.*)'$/ do |extension_name, forced_platform| generate_extension_task_for extension_name, forced_platform generate_source_code_for extension_name end Given /^that all my source files are in place$/ do step "a safe project directory" step "a extension cross-compilable 'extension_one'" end Given /^that all my Java source files are in place$/ do step "a safe project directory" step "a extension Java-compilable 'extension_one'" end Given /^that my gem source is all in place$/ do step "a safe project directory" step "a gem named 'gem_abc'" step "a extension cross-compilable 'extension_one'" end Given /^that my JRuby gem source is all in place$/ do step "a safe project directory" step "a gem named 'gem_abc'" step "a extension Java-compilable 'extension_one'" end Given /^that my gem source is all in place to target two platforms$/ do step "a safe project directory" step "a gem named 'gem_abc'" step "a extension 'extension_one' multi cross-compilable" end Given /^not changed any file since$/ do # don't do anything, that's the purpose of this step! end When /^touching '(.*)' file of extension '(.*)'$/ do |file, extension_name| Kernel.sleep 1 FileUtils.touch "ext/#{extension_name}/#{file}" end Then /^binary extension '(.*)' (do|do not) exist in '(.*)'$/ do |extension_name, condition, folder| ext_for_platform = File.join(folder, "#{extension_name}.#{RbConfig::CONFIG['DLEXT']}") if condition == 'do' File.exist?(ext_for_platform).should be_true else File.exist?(ext_for_platform).should be_false end end rake-compiler-1.0.5/features/step_definitions/cross_compilation.rb000066400000000000000000000016371334215447600255270ustar00rootroot00000000000000# Naive way of looking into platforms Given %r{^I'm running a POSIX operating system$} do unless RbConfig::CONFIG['host_os'] =~ /linux|darwin|bsd|dragonfly/ then raise Cucumber::Pending.new("You need a POSIX operating system, no cheating ;-)") end end Given %r{^I've installed cross compile toolchain$} do unless search_path(%w(i586-mingw32msvc-gcc i386-mingw32-gcc i686-w64-mingw32-gcc)) pending 'Cannot locate suitable compiler in the PATH.' end end Then /^binaries for platform '(.*)' get generated$/ do |platform| ext = binary_extension(platform) ext_for_platform = Dir.glob("tmp/#{platform}/**/*.#{ext}") ext_for_platform.should_not be_empty end Then /^binaries for platform '(.*)' version '(.*)' get copied$/ do |platform, version| lib_path = "lib/#{version}" ext = binary_extension(platform) ext_for_platform = Dir.glob("#{lib_path}/*.#{ext}") ext_for_platform.should_not be_empty end rake-compiler-1.0.5/features/step_definitions/execution.rb000066400000000000000000000030241334215447600237730ustar00rootroot00000000000000# FIXME: Make the Transform work # # Transform /^| on JRuby$/ do |step_arg| # / on JRuby/.match(step_arg) != nil # end Given %r{^I've already successfully executed rake task '(.*)'(| on JRuby)$} do |task_name, on_jruby| rake_cmd = "rake #{task_name}" rake_cmd = 'jruby -S ' << rake_cmd if on_jruby == ' on JRuby' emptyness = `#{rake_cmd} 2>&1` unless $?.success? warn emptyness raise "rake failed with #{$?.exitstatus}" end end When /^rake task '(.*)' is invoked(| on JRuby)$/ do |task_name, on_jruby| @output ||= {} @result ||= {} rake_cmd = "rake #{task_name}" rake_cmd = 'jruby -S ' << rake_cmd if on_jruby == ' on JRuby' @output[task_name] = `#{rake_cmd} 2>&1` @result[task_name] = $?.success? end Then /^rake task '(.*)' succeeded$/ do |task_name| if @result.nil? || !@result.include?(task_name) then raise "The task #{task_name} should be invoked first." else @result[task_name].should be_true end end Then /^rake task '(.*)' should fail$/ do |task_name| if @result.nil? || !@result.include?(task_name) then raise "The task #{task_name} should be invoked first." else @result[task_name].should be_false end end Then /^output of rake task '(.*)' (contains|do not contain) \/(.*)\/$/ do |task_name, condition, regex| if condition == 'contains' then @output[task_name].should match(%r(#{regex})) else @output[task_name].should_not match(%r(#{regex})) end end Then /^output of rake task '(.*)' warns$/ do |task_name, warning| @output[task_name].should include(warning) end rake-compiler-1.0.5/features/step_definitions/folders.rb000066400000000000000000000015571334215447600234370ustar00rootroot00000000000000Given /^a safe project directory$/ do # step back to ROOT Dir.chdir ROOT_PATH tmp_name = "project.#{Process.pid}" @safe_dir = File.join(ROOT_PATH, 'tmp', tmp_name) FileUtils.rm_rf @safe_dir FileUtils.mkdir_p @safe_dir Dir.chdir @safe_dir generate_scaffold_structure end Given /^'(.*)' folder (exist|is deleted)$/ do |folder, condition| case condition when 'exist' raise "Folder #{folder} do not exist" unless File.exist?(folder) && File.directory?(folder) when 'is deleted' FileUtils.rm_rf folder end end Then /^'(.*)' folder is created$/ do |folder| File.directory?(folder).should be_true end Then /^'(.*)' folder do not exist$/ do |folder| File.directory?(folder).should_not be_true end Then /^no left over from '(.*)' remains in '(.*)'$/ do |name, folder| Dir.glob("#{folder}/**/#{name}/#{RUBY_VERSION}").should be_empty end rake-compiler-1.0.5/features/step_definitions/gem.rb000066400000000000000000000032121334215447600225370ustar00rootroot00000000000000Given /^a gem named '(.*)'$/ do |gem_name| generate_gem_task gem_name end Then /^ruby gem for '(.*)' version '(.*)' do exist in '(.*)'$/ do |name, version, folder| File.exist?(gem_file(folder, name, version)).should be_true end Then /^binary gem for '(.*)' version '(.*)' do exist in '(.*)'$/ do |name, version, folder| File.exist?(gem_file_platform(folder, name, version)).should be_true end Then /^a gem for '(.*)' version '(.*)' platform '(.*)' do exist in '(.*)'$/ do |name, version, platform, folder| File.exist?(gem_file_platform(folder, name, version, platform)).should be_true # unpack the Gem and check what's inside! `gem unpack #{gem_file_platform(folder, name, version, platform)} --target tmp` unpacked_gem_dir = unpacked_gem_dir_platform('tmp', name, version, platform) File.exist?(unpacked_gem_dir).should be_true files = Dir.glob("#{unpacked_gem_dir}/lib/*.#{binary_extension(platform)}") files << Dir.glob("#{unpacked_gem_dir}/lib/*/*.#{binary_extension(platform)}") files.flatten.uniq.should_not be_empty end Then /^gem for platform '(.*)' get generated$/ do |platform| step "a gem for 'gem_abc' version '0.1.0' platform '#{platform}' do exist in 'pkg'" end def gem_file(folder, name, version) "#{folder}/#{name}-#{version}.gem" end def gem_file_platform(folder, name, version, platform = nil) file = "#{folder}/#{name}-#{version}" file << "-" << (platform || Gem::Platform.new(RUBY_PLATFORM).to_s) file << ".gem" file end def unpacked_gem_dir_platform(folder, name, version, platform = nil) file = "#{folder}/#{name}-#{version}" file << "-" << (platform || Gem::Platform.new(RUBY_PLATFORM).to_s) file end rake-compiler-1.0.5/features/step_definitions/java_compilation.rb000066400000000000000000000005251334215447600253120ustar00rootroot00000000000000Given %r{^I've installed the Java Development Kit$} do pending('Cannot locate suitable Java compiler (the Java Development Kit) in the PATH.') unless search_path(%w(javac javac.exe)) end Given %r{^I've installed JRuby$} do pending('Cannot locate a JRuby installation in the PATH.') unless search_path(%w(jruby jruby.exe jruby.bat)) end rake-compiler-1.0.5/features/support/000077500000000000000000000000001334215447600176125ustar00rootroot00000000000000rake-compiler-1.0.5/features/support/env.rb000066400000000000000000000003551334215447600207320ustar00rootroot00000000000000require 'cucumber' require 'rspec' require 'fileutils' require 'rbconfig' ROOT_PATH = File.expand_path(File.join(File.dirname(__FILE__), '../..')) # get rid of Bundler environment polution defined?(Bundler) and ENV.delete("RUBYOPT") rake-compiler-1.0.5/features/support/file_template_helpers.rb000066400000000000000000000061761334215447600245050ustar00rootroot00000000000000module FileTemplateHelpers def template_rakefile <<-EOF # add rake-compiler lib dir to the LOAD_PATH $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '../..', 'lib')) require 'rubygems' require 'rake' # load rakefile extensions (tasks) Dir['tasks/*.rake'].each { |f| import f } EOF end def template_rake_gemspec(gem_name) <<-EOF require 'rubygems/package_task' SPEC = Gem::Specification.new do |s| s.name = "#{gem_name}" s.version = "0.1.0" s.summary = "#{gem_name} test gem for rake-compiler" s.description = "#{gem_name} is a fake gem for testing under rake-compiler" s.files = FileList["ext/**/*.{rb,c,h}", "Rakefile", "tasks/*.rake", "lib/**/*.rb"] s.extensions = FileList["ext/**/extconf.rb"] s.homepage = 'http://github.com/luislavena/rake-compiler' s.rubyforge_project = 'TODO' s.authors = ["Luis Lavena"] s.email = ["luislavena@gmail.com"] end Gem::PackageTask.new(SPEC) do |pkg| pkg.need_zip = false pkg.need_tar = false end EOF end def template_rake_extension(extension_name, gem_spec = nil) <<-EOF require 'rake/extensiontask' Rake::ExtensionTask.new("#{extension_name}"#{', SPEC' if gem_spec}) EOF end def template_rake_extension_with_platform(extension_name, platform) <<-EOF require 'rake/extensiontask' Rake::ExtensionTask.new("#{extension_name}", SPEC) do |ext| ext.platform = "#{platform}" end EOF end def template_rake_extension_cross_compile(extension_name, gem_spec = nil) <<-EOF require 'rake/extensiontask' Rake::ExtensionTask.new("#{extension_name}"#{', SPEC' if gem_spec}) do |ext| ext.cross_compile = true end EOF end def template_rake_extension_multi_cross_compile(extension_name) <<-EOF require 'rake/extensiontask' Rake::ExtensionTask.new("#{extension_name}", SPEC) do |ext| ext.cross_compile = true ext.cross_platform = ['i386-mswin32-60', 'i386-mingw32'] end EOF end def template_rake_extension_java_compile(extension_name, gem_spec = nil) <<-EOF require 'rake/javaextensiontask' Rake::JavaExtensionTask.new("#{extension_name}"#{', SPEC' if gem_spec}) do |ext| # nothing end EOF end def template_extconf(extension_name) <<-EOF require 'mkmf' create_makefile("#{extension_name}") EOF end def template_source_c(extension_name) <<-EOF #include "source.h" void Init_#{extension_name}() { printf("source.c of extension #{extension_name}\\n"); } EOF end def template_source_h <<-EOF #include "ruby.h" EOF end def template_source_java(extension_name) <<-EOF import org.jruby.Ruby; import org.jruby.runtime.load.BasicLibraryService; public class #{camelize(extension_name)}Service implements BasicLibraryService { public boolean basicLoad(final Ruby runtime) throws java.io.IOException { HelloWorldPrinter hwp = new HelloWorldPrinter(); hwp.tellTheWorld(); return true; } private class HelloWorldPrinter { void tellTheWorld() throws java.io.IOException { System.out.println("#{camelize(extension_name)}Service.java of extension #{extension_name}\\n"); } } } EOF end def camelize(str) str.gsub(/(^|_)(.)/) { $2.upcase } end end World(FileTemplateHelpers) rake-compiler-1.0.5/features/support/generator_helpers.rb000066400000000000000000000071451334215447600236560ustar00rootroot00000000000000module GeneratorHelpers def generate_scaffold_structure # create folder structure FileUtils.mkdir_p "lib" FileUtils.mkdir_p "tasks" FileUtils.mkdir_p "tmp" # create Rakefile loader File.open("Rakefile", 'w') do |rakefile| rakefile.puts template_rakefile.strip end end def generate_gem_task(gem_name) # create generic gem task File.open("tasks/gem.rake", 'w') do |gem_rake| gem_rake.puts template_rake_gemspec(gem_name) end end def generate_extension_task_for(extension_name, platform = nil) # create folder structure FileUtils.mkdir_p "ext/#{extension_name}" return if File.exist?("tasks/#{extension_name}.rake") # Building a gem? if File.exist?("tasks/gem.rake") then File.open("tasks/gem.rake", 'a+') do |ext_in_gem| if platform ext_in_gem.puts template_rake_extension_with_platform(extension_name, platform) else ext_in_gem.puts template_rake_extension(extension_name, true) end end else # create specific extension rakefile File.open("tasks/#{extension_name}.rake", 'w') do |ext_rake| ext_rake.puts template_rake_extension(extension_name) end end end def generate_cross_compile_extension_task_for(extension_name) # create folder structure FileUtils.mkdir_p "ext/#{extension_name}" return if File.exist?("tasks/#{extension_name}.rake") # create specific extension rakefile # Building a gem? if File.exist?("tasks/gem.rake") then File.open("tasks/gem.rake", 'a+') do |ext_in_gem| ext_in_gem.puts template_rake_extension_cross_compile(extension_name, true) end else File.open("tasks/#{extension_name}.rake", 'w') do |ext_rake| ext_rake.puts template_rake_extension_cross_compile(extension_name) end end end def generate_java_compile_extension_task_for(extension_name) # create folder structure FileUtils.mkdir_p "ext/#{extension_name}" return if File.exist?("tasks/#{extension_name}.rake") # create specific extension rakefile # Building a gem? if File.exist?("tasks/gem.rake") then File.open("tasks/gem.rake", 'a+') do |ext_in_gem| ext_in_gem.puts template_rake_extension_java_compile(extension_name, true) end else File.open("tasks/#{extension_name}.rake", 'w') do |ext_rake| ext_rake.puts template_rake_extension_java_compile(extension_name) end end end def generate_multi_cross_compile_extension_task_for(extension_name) # create folder structure FileUtils.mkdir_p "ext/#{extension_name}" return if File.exist?("tasks/#{extension_name}.rake") # create specific extension rakefile # Building a gem? if File.exist?("tasks/gem.rake") then File.open("tasks/gem.rake", 'a+') do |ext_in_gem| ext_in_gem.puts template_rake_extension_multi_cross_compile(extension_name) end end end def generate_source_code_for(extension_name) # source C file File.open("ext/#{extension_name}/source.c", 'w') do |c| c.puts template_source_c(extension_name) end # header H file File.open("ext/#{extension_name}/source.h", 'w') do |h| h.puts template_source_h end # extconf.rb file File.open("ext/#{extension_name}/extconf.rb", 'w') do |ext| ext.puts template_extconf(extension_name) end end def generate_java_source_code_for(extension_name) # source .java file File.open("ext/#{extension_name}/#{camelize(extension_name)}Service.java", 'w') do |c| c.puts template_source_java(extension_name) end end end World(GeneratorHelpers) rake-compiler-1.0.5/features/support/platform_extension_helpers.rb000066400000000000000000000011061334215447600255770ustar00rootroot00000000000000module PlatformExtensionHelpers def binary_extension(platform = RUBY_PLATFORM) case platform when /darwin/ 'bundle' when /mingw|mswin|linux/ 'so' when /java/ 'jar' else RbConfig::CONFIG['DLEXT'] end end def search_path(binaries) paths = ENV['PATH'].split(File::PATH_SEPARATOR) binary = binaries.find do |bin_file| paths.find do |path| bin = File.join(path, bin_file) File.exist?(bin) && File.executable?(bin) end end binary end end World(PlatformExtensionHelpers) rake-compiler-1.0.5/lib/000077500000000000000000000000001334215447600150265ustar00rootroot00000000000000rake-compiler-1.0.5/lib/rake/000077500000000000000000000000001334215447600157505ustar00rootroot00000000000000rake-compiler-1.0.5/lib/rake/baseextensiontask.rb000066400000000000000000000032531334215447600220320ustar00rootroot00000000000000require 'rake' require 'rake/clean' require 'rake/tasklib' require 'rbconfig' begin require 'psych' rescue LoadError end require 'yaml' require 'pathname' module Rake class BaseExtensionTask < TaskLib attr_accessor :name attr_accessor :gem_spec attr_accessor :tmp_dir attr_accessor :ext_dir attr_accessor :lib_dir attr_accessor :config_options attr_accessor :source_pattern attr_accessor :extra_options attr_writer :platform def platform @platform ||= RUBY_PLATFORM end def initialize(name = nil, gem_spec = nil) init(name, gem_spec) yield self if block_given? define end def init(name = nil, gem_spec = nil) @name = name @gem_spec = gem_spec @tmp_dir = 'tmp' @ext_dir = "ext/#{@name}" @lib_dir = 'lib' @config_options = [] @extra_options = ARGV.select { |i| i =~ /\A--?/ } end def define fail "Extension name must be provided." if @name.nil? @name = @name.to_s define_compile_tasks end private def define_compile_tasks raise NotImplementedError end def binary(platform = nil) ext = case platform when /darwin/ 'bundle' when /mingw|mswin|linux/ 'so' when /java/ 'jar' else RbConfig::CONFIG['DLEXT'] end "#{@name}.#{ext}" end def source_files FileList["#{@ext_dir}/#{@source_pattern}"] end def warn_once(message) @@already_warned ||= false return if @@already_warned @@already_warned = true warn message end def windows? Rake.application.windows? end end end rake-compiler-1.0.5/lib/rake/extensioncompiler.rb000066400000000000000000000027241334215447600220510ustar00rootroot00000000000000module Rake # # HACK: Lousy API design, sue me. At least works ;-) # # Define a series of helpers to aid in search and usage of MinGW (GCC) Compiler # by gem developer/creators. # module ExtensionCompiler # return the host portion from the installed MinGW def self.mingw_host return @mingw_host if @mingw_host # the mingw_gcc_executable is helpful here if target = mingw_gcc_executable then # we only care for the filename target = File.basename(target) # now strip the extension (if present) target.sub!(File.extname(target), '') # get rid of '-gcc' portion too ;-) target.sub!('-gcc', '') end raise "No MinGW tools or unknown setup platform?" unless target @mingw_host = target end # return the first compiler found that includes both mingw and gcc conditions # (this assumes you have one installed) def self.mingw_gcc_executable return @mingw_gcc_executable if @mingw_gcc_executable # grab the paths defined in the environment paths = ENV['PATH'].split(File::PATH_SEPARATOR) # the pattern to look into (captures *nix and windows executables) pattern = "{mingw32-,i?86*mingw*}gcc{,.*}" @mingw_gcc_executable = paths.find do |path| # cleanup paths before globbing gcc = Dir.glob("#{File.expand_path(path)}/#{pattern}").first break gcc if gcc end @mingw_gcc_executable end end end rake-compiler-1.0.5/lib/rake/extensiontask.rb000066400000000000000000000440341334215447600212010ustar00rootroot00000000000000require "rbconfig" require 'rake/baseextensiontask' require "rubygems/package_task" # Define a series of tasks to aid in the compilation of C extensions for # gem developer/creators. module Rake class ExtensionTask < BaseExtensionTask attr_accessor :config_script attr_accessor :cross_compile attr_writer :cross_platform attr_writer :cross_config_options attr_accessor :no_native attr_accessor :config_includes def init(name = nil, gem_spec = nil) super @config_script = 'extconf.rb' @source_pattern = "*.{c,cc,cpp}" @compiled_pattern = "*.{o,obj,so,bundle,dSYM}" @cross_compile = false @cross_config_options = [] @cross_compiling = nil @no_native = false @config_includes = [] @ruby_versions_per_platform = {} end def cross_platform @cross_platform ||= 'i386-mingw32' end def cross_compiling(&block) @cross_compiling = block if block_given? end def binary(platform = nil) if platform == "java" "#{name}.#{RbConfig::MAKEFILE_CONFIG['DLEXT']}" else super end end def define if (defined?(RUBY_ENGINE) && RUBY_ENGINE == 'ironruby') warn_once <<-EOF WARNING: You're attempting to (cross-)compile C extensions from a platform (#{RUBY_ENGINE}) that does not support native extensions or mkmf.rb. Rerun `rake` under MRI Ruby 1.8.x/1.9.x to cross/native compile. EOF return end super unless compiled_files.empty? warn "WARNING: rake-compiler found compiled files in '#{@ext_dir}' directory. Please remove them." end # only gems with 'ruby' platforms are allowed to define native tasks define_native_tasks if !@no_native && (@gem_spec && @gem_spec.platform == 'ruby') # only define cross platform functionality when enabled return unless @cross_compile if cross_platform.is_a?(Array) then cross_platform.each { |platf| define_cross_platform_tasks(platf) } else define_cross_platform_tasks(cross_platform) end end def cross_config_options(for_platform=nil) return @cross_config_options unless for_platform # apply options for this platform, only @cross_config_options.map do |option| if option.kind_of?(Hash) option[for_platform] || [] else option end end.flatten end private # copy other gem files to staging directory def define_staging_file_tasks(files, lib_path, stage_path, platf, ruby_ver) files.each do |gem_file| # ignore directories and the binary extension next if File.directory?(gem_file) || gem_file == "#{lib_path}/#{binary(platf)}" stage_file = "#{stage_path}/#{gem_file}" # copy each file from base to stage directory unless Rake::Task.task_defined?(stage_file) then directory File.dirname(stage_file) file stage_file => [File.dirname(stage_file), gem_file] do cp gem_file, stage_file end end # append each file to the copy task task "copy:#{@name}:#{platf}:#{ruby_ver}" => [stage_file] end end def define_compile_tasks(for_platform = nil, ruby_ver = RUBY_VERSION) # platform usage platf = for_platform || platform binary_path = binary(platf) # lib_path lib_path = lib_dir lib_binary_path = "#{lib_path}/#{binary_path}" lib_binary_dir_path = File.dirname(lib_binary_path) # tmp_path tmp_path = "#{@tmp_dir}/#{platf}/#{@name}/#{ruby_ver}" stage_path = "#{@tmp_dir}/#{platf}/stage" tmp_binary_path = "#{tmp_path}/#{binary_path}" tmp_binary_dir_path = File.dirname(tmp_binary_path) stage_binary_path = "#{stage_path}/#{lib_path}/#{binary_path}" stage_binary_dir_path = File.dirname(stage_binary_path) # cleanup and clobbering CLEAN.include(tmp_path) CLEAN.include(stage_path) CLOBBER.include("#{lib_path}/#{binary(platf)}") CLOBBER.include("#{@tmp_dir}") # directories we need directory tmp_path directory tmp_binary_dir_path directory lib_binary_dir_path directory stage_binary_dir_path # copy binary from temporary location to final lib # tmp/extension_name/extension_name.{so,bundle} => lib/ task "copy:#{@name}:#{platf}:#{ruby_ver}" => [lib_binary_dir_path, tmp_binary_path] do install tmp_binary_path, "#{lib_path}/#{binary_path}" end # copy binary from temporary location to staging directory task "copy:#{@name}:#{platf}:#{ruby_ver}" => [stage_binary_dir_path, tmp_binary_path] do cp tmp_binary_path, stage_binary_path end # copy other gem files to staging directory define_staging_file_tasks(@gem_spec.files, lib_path, stage_path, platf, ruby_ver) if @gem_spec # binary in temporary folder depends on makefile and source files # tmp/extension_name/extension_name.{so,bundle} file tmp_binary_path => [tmp_binary_dir_path, "#{tmp_path}/Makefile"] + source_files do jruby_compile_msg = <<-EOF Compiling a native C extension on JRuby. This is discouraged and a Java extension should be preferred. EOF warn_once(jruby_compile_msg) if defined?(JRUBY_VERSION) chdir tmp_path do sh make if binary_path != File.basename(binary_path) cp File.basename(binary_path), binary_path end end end # makefile depends of tmp_dir and config_script # tmp/extension_name/Makefile file "#{tmp_path}/Makefile" => [tmp_path, extconf] do |t| options = @config_options.dup # include current directory include_dirs = ['.'].concat(@config_includes).uniq.join(File::PATH_SEPARATOR) cmd = [Gem.ruby, "-I#{include_dirs}"] # build a relative path to extconf script abs_tmp_path = (Pathname.new(Dir.pwd) + tmp_path).realpath abs_extconf = (Pathname.new(Dir.pwd) + extconf).realpath # now add the extconf script cmd << abs_extconf.relative_path_from(abs_tmp_path) # fake.rb will be present if we are cross compiling if t.prerequisites.include?("#{tmp_path}/fake.rb") then options.push(*cross_config_options(platf)) end # add options to command cmd.push(*options) # add any extra command line options unless extra_options.empty? cmd.push(*extra_options) end chdir tmp_path do # FIXME: Rake is broken for multiple arguments system() calls. # Add current directory to the search path of Ruby sh cmd.join(' ') end end # compile tasks unless Rake::Task.task_defined?('compile') then desc "Compile all the extensions" task "compile" end # compile:name unless Rake::Task.task_defined?("compile:#{@name}") then desc "Compile #{@name}" task "compile:#{@name}" end # Allow segmented compilation by platform (open door for 'cross compile') task "compile:#{@name}:#{platf}" => ["copy:#{@name}:#{platf}:#{ruby_ver}"] task "compile:#{platf}" => ["compile:#{@name}:#{platf}"] # Only add this extension to the compile chain if current # platform matches the indicated one. if platf == RUBY_PLATFORM then # ensure file is always copied file "#{lib_path}/#{binary_path}" => ["copy:#{name}:#{platf}:#{ruby_ver}"] task "compile:#{@name}" => ["compile:#{@name}:#{platf}"] task "compile" => ["compile:#{platf}"] end end def define_native_tasks(for_platform = nil, ruby_ver = RUBY_VERSION, callback = nil) platf = for_platform || platform # tmp_path stage_path = "#{@tmp_dir}/#{platf}/stage" # lib_path lib_path = lib_dir # create 'native:gem_name' and chain it to 'native' task unless Rake::Task.task_defined?("native:#{@gem_spec.name}:#{platf}") task "native:#{@gem_spec.name}:#{platf}" do |t| # FIXME: workaround Gem::Specification limitation around cache_file: # http://github.com/rubygems/rubygems/issues/78 spec = gem_spec.dup spec.instance_variable_set(:"@cache_file", nil) if spec.respond_to?(:cache_file) # adjust to specified platform spec.platform = Gem::Platform.new(platf) # set ruby version constraints ruby_versions = @ruby_versions_per_platform[platf] || [] sorted_ruby_versions = ruby_versions.sort_by do |ruby_version| ruby_version.split(".").collect(&:to_i) end spec.required_ruby_version = [ ">= #{ruby_api_version(sorted_ruby_versions.first)}", "< #{ruby_api_version(sorted_ruby_versions.last).succ}" ] # clear the extensions defined in the specs spec.extensions.clear # add the binaries that this task depends on ext_files = [] # go through native prerequisites and grab the real extension files from there t.prerequisites.each do |ext| # strip stage path and keep lib/... only ext_files << ext.sub(stage_path+"/", '') end # include the files in the gem specification spec.files += ext_files # expose gem specification for customization callback.call(spec) if callback # Generate a package for this gem pkg = Gem::PackageTask.new(spec) do |p| p.need_zip = false p.need_tar = false # Do not copy any files per PackageTask, because # we need the files from the staging directory p.package_files.clear end # copy other gem files to staging directory if added by the callback define_staging_file_tasks(spec.files, lib_path, stage_path, platf, ruby_ver) # Copy from staging directory to gem package directory. # This is derived from the code of Gem::PackageTask # but uses stage_path as source directory. stage_files = spec.files.map do |gem_file| File.join(stage_path, gem_file) end file pkg.package_dir_path => stage_files do mkdir_p pkg.package_dir rescue nil spec.files.each do |ft| fn = File.join(stage_path, ft) f = File.join(pkg.package_dir_path, ft) fdir = File.dirname(f) mkdir_p(fdir) if !File.exist?(fdir) if File.directory?(fn) mkdir_p(f) else rm_f f safe_ln(fn, f) end end end end end # add binaries to the dependency chain task "native:#{@gem_spec.name}:#{platf}" => ["#{stage_path}/#{lib_path}/#{binary(platf)}"] # ensure the extension get copied unless Rake::Task.task_defined?("#{lib_path}/#{binary(platf)}") then file "#{lib_path}/#{binary(platf)}" => ["copy:#{@name}:#{platf}:#{ruby_ver}"] end file "#{stage_path}/#{lib_dir}/#{binary(platf)}" => ["copy:#{@name}:#{platf}:#{ruby_ver}"] # Allow segmented packaging by platform (open door for 'cross compile') task "native:#{platf}" => ["native:#{@gem_spec.name}:#{platf}"] # Only add this extension to the compile chain if current # platform matches the indicated one. if platf == RUBY_PLATFORM then task "native:#{@gem_spec.name}" => ["native:#{@gem_spec.name}:#{platf}"] task "native" => ["native:#{platf}"] end end def define_cross_platform_tasks(for_platform) if ruby_vers = ENV['RUBY_CC_VERSION'] ruby_vers = ENV['RUBY_CC_VERSION'].split(':') else ruby_vers = [RUBY_VERSION] end multi = (ruby_vers.size > 1) ? true : false ruby_vers.each do |version| # save original lib_dir orig_lib_dir = @lib_dir # tweak lib directory only when targeting multiple versions if multi then version =~ /(\d+\.\d+)/ @lib_dir = "#{@lib_dir}/#{$1}" end # Update cross compiled platform/version combinations ruby_versions = (@ruby_versions_per_platform[for_platform] ||= []) ruby_versions << version define_cross_platform_tasks_with_version(for_platform, version) # restore lib_dir @lib_dir = orig_lib_dir end end def define_cross_platform_tasks_with_version(for_platform, ruby_ver) config_path = File.expand_path("~/.rake-compiler/config.yml") # warn the user about the need of configuration to use cross compilation. unless File.exist?(config_path) define_dummy_cross_platform_tasks return end config_file = YAML.load_file(config_path) # tmp_path tmp_path = "#{@tmp_dir}/#{for_platform}/#{@name}/#{ruby_ver}" # lib_path lib_path = lib_dir unless rbconfig_file = config_file["rbconfig-#{for_platform}-#{ruby_ver}"] then warn "no configuration section for specified version of Ruby (rbconfig-#{for_platform}-#{ruby_ver})" return end # mkmf mkmf_file = File.expand_path(File.join(File.dirname(rbconfig_file), '..', 'mkmf.rb')) # define compilation tasks for cross platform! define_compile_tasks(for_platform, ruby_ver) # chain fake.rb and mkmf.rb to Makefile generation file "#{tmp_path}/Makefile" => ["#{tmp_path}/fake.rb", "#{tmp_path}/mkmf.rb"] # copy the rbconfig from the cross-ruby location and # genearte fake.rb for different ruby versions file "#{tmp_path}/fake.rb" => [rbconfig_file] do |t| File.open(t.name, 'w') do |f| f.write fake_rb(for_platform, ruby_ver) f.write File.read(t.prerequisites.first) end end # copy mkmf from cross-ruby location file "#{tmp_path}/mkmf.rb" => [mkmf_file] do |t| File.open(t.name, 'w') do |f| content = File.read(t.prerequisites.first) content.sub!(/^(require ')rbconfig(')$/, '\\1fake\\2') if ruby_ver < "1.9" && "1.9" <= RUBY_VERSION content.sub!(/^( break )\*(defaults)$/, '\\1\\2.first') content.sub!(/^( return )\*(defaults)$/, '\\1\\2.first') content.sub!(/^( mfile\.)print( configuration\(srcprefix\))$/, '\\1puts\\2') end f.write content end end # now define native tasks for cross compiled files if @gem_spec && @gem_spec.platform == 'ruby' then define_native_tasks(for_platform, ruby_ver, @cross_compiling) end # create cross task task 'cross' do # clear compile dependencies Rake::Task['compile'].prerequisites.reject! { |t| !compiles_cross_platform.include?(t) } # chain the cross platform ones task 'compile' => ["compile:#{for_platform}"] # clear lib/binary dependencies and trigger cross platform ones # check if lib/binary is defined (damn bundle versus so versus dll) if Rake::Task.task_defined?("#{lib_path}/#{binary(for_platform)}") then Rake::Task["#{lib_path}/#{binary(for_platform)}"].prerequisites.clear end # FIXME: targeting multiple platforms copies the file twice file "#{lib_path}/#{binary(for_platform)}" => ["copy:#{@name}:#{for_platform}:#{ruby_ver}"] # if everything for native task is in place if @gem_spec && @gem_spec.platform == 'ruby' then # double check: only cross platform native tasks should be here # FIXME: Sooo brittle Rake::Task['native'].prerequisites.reject! { |t| !natives_cross_platform.include?(t) } task 'native' => ["native:#{for_platform}"] end end end def define_dummy_cross_platform_tasks task 'cross' do Rake::Task['compile'].clear task 'compile' do raise "rake-compiler must be configured first to enable cross-compilation" end end end def extconf "#{@ext_dir}/#{@config_script}" end def make unless @make @make = if RUBY_PLATFORM =~ /mswin/ then 'nmake' else ENV['MAKE'] || find_make end end unless @make raise "Couldn't find a suitable `make` tool. Use `MAKE` env to set an alternative." end @make end def find_make candidates = ["gmake", "make"] paths = (ENV["PATH"] || "").split(File::PATH_SEPARATOR) exeext = RbConfig::CONFIG["EXEEXT"] candidates.each do |candidate| paths.each do |path| make = File.join(path, "#{candidate}#{exeext}") return make if File.executable?(make) end end nil end def compiled_files FileList["#{@ext_dir}/#{@compiled_pattern}"] end def compiles_cross_platform [*@cross_platform].map { |p| "compile:#{p}" } end def natives_cross_platform [*@cross_platform].map { |p| "native:#{p}" } end def ruby_api_version(ruby_version) ruby_version.split(".")[0, 2].join(".") end def fake_rb(platform, version) <<-FAKE_RB # Pre-load resolver library before faking, in order to avoid error # "cannot load such file -- win32/resolv" when it is required later on. # See also: https://github.com/tjschuck/rake-compiler-dev-box/issues/5 require 'resolv' require 'rbconfig' class Object remove_const :RbConfig remove_const :RUBY_PLATFORM remove_const :RUBY_VERSION remove_const :RUBY_DESCRIPTION if defined?(RUBY_DESCRIPTION) RUBY_PLATFORM = "#{platform}" RUBY_VERSION = "#{version}" RUBY_DESCRIPTION = "ruby \#{RUBY_VERSION} (\#{RUBY_RELEASE_DATE}) [\#{RUBY_PLATFORM}]" end if RUBY_PLATFORM =~ /mswin|bccwin|mingw/ class File remove_const :ALT_SEPARATOR ALT_SEPARATOR = "\\\\" end end posthook = proc do $ruby = "#{Gem.ruby}" untrace_var(:$ruby, posthook) end trace_var(:$ruby, posthook) FAKE_RB end end end rake-compiler-1.0.5/lib/rake/javaextensiontask.rb000066400000000000000000000157561334215447600220540ustar00rootroot00000000000000require "rbconfig" require 'rake/baseextensiontask' # Define a series of tasks to aid in the compilation of Java extensions for # gem developer/creators. module Rake class JavaExtensionTask < BaseExtensionTask attr_accessor :classpath attr_accessor :debug # Provide source compatibility with specified release attr_accessor :source_version # Generate class files for specific VM version attr_accessor :target_version def platform @platform ||= 'java' end def java_compiling(&block) @java_compiling = block if block_given? end def init(name = nil, gem_spec = nil) super @source_pattern = '**/*.java' @classpath = nil @java_compiling = nil @debug = false @source_version = '1.6' @target_version = '1.6' end def define super define_java_platform_tasks end private def define_compile_tasks(for_platform = nil, ruby_ver = RUBY_VERSION) # platform usage platf = for_platform || platform # lib_path lib_path = lib_dir # tmp_path tmp_path = "#{@tmp_dir}/#{platf}/#{@name}" # cleanup and clobbering CLEAN.include(tmp_path) CLOBBER.include("#{lib_path}/#{binary(platf)}") CLOBBER.include("#{@tmp_dir}") # directories we need directory tmp_path directory lib_dir # copy binary from temporary location to final lib # tmp/extension_name/extension_name.{so,bundle} => lib/ task "copy:#{@name}:#{platf}" => [lib_path, "#{tmp_path}/#{binary(platf)}"] do install "#{tmp_path}/#{binary(platf)}", "#{lib_path}/#{binary(platf)}" end file "#{tmp_path}/#{binary(platf)}" => "#{tmp_path}/.build" do class_files = FileList["#{tmp_path}/**/*.class"]. gsub("#{tmp_path}/", '') # avoid environment variable expansion using backslash class_files.gsub!('$', '\$') unless windows? args = class_files.map { |path| ["-C #{tmp_path}", path] }.flatten sh "jar cf #{tmp_path}/#{binary(platf)} #{args.join(' ')}" end file "#{tmp_path}/.build" => [tmp_path] + source_files do not_jruby_compile_msg = <<-EOF WARNING: You're cross-compiling a binary extension for JRuby, but are using another interpreter. If your Java classpath or extension dir settings are not correctly detected, then either check the appropriate environment variables or execute the Rake compilation task using the JRuby interpreter. (e.g. `jruby -S rake compile:java`) EOF warn_once(not_jruby_compile_msg) unless defined?(JRUBY_VERSION) classpath_arg = java_classpath_arg(@classpath) debug_arg = @debug ? '-g' : '' sh "javac #{java_extdirs_arg} -target #{@target_version} -source #{@source_version} -Xlint:unchecked #{debug_arg} #{classpath_arg} -d #{tmp_path} #{source_files.join(' ')}" # Checkpoint file touch "#{tmp_path}/.build" end # compile tasks unless Rake::Task.task_defined?('compile') then desc "Compile all the extensions" task "compile" end # compile:name unless Rake::Task.task_defined?("compile:#{@name}") then desc "Compile #{@name}" task "compile:#{@name}" end # Allow segmented compilation by platform (open door for 'cross compile') task "compile:#{@name}:#{platf}" => ["copy:#{@name}:#{platf}"] task "compile:#{platf}" => ["compile:#{@name}:#{platf}"] # Only add this extension to the compile chain if current # platform matches the indicated one. if platf == RUBY_PLATFORM then # ensure file is always copied file "#{lib_path}/#{binary(platf)}" => ["copy:#{name}:#{platf}"] task "compile:#{@name}" => ["compile:#{@name}:#{platf}"] task "compile" => ["compile:#{platf}"] end end def define_java_platform_tasks # lib_path lib_path = lib_dir if @gem_spec && !Rake::Task.task_defined?("java:#{@gem_spec.name}") task "java:#{@gem_spec.name}" do |t| # FIXME: workaround Gem::Specification limitation around cache_file: # http://github.com/rubygems/rubygems/issues/78 spec = gem_spec.dup spec.instance_variable_set(:"@cache_file", nil) if spec.respond_to?(:cache_file) # adjust to specified platform spec.platform = Gem::Platform.new('java') # clear the extensions defined in the specs spec.extensions.clear # add the binaries that this task depends on ext_files = [] # go through native prerequisites and grab the real extension files from there t.prerequisites.each do |ext| ext_files << ext end # include the files in the gem specification spec.files += ext_files # expose gem specification for customization if @java_compiling @java_compiling.call(spec) end # Generate a package for this gem Gem::PackageTask.new(spec) do |pkg| pkg.need_zip = false pkg.need_tar = false end end # add binaries to the dependency chain task "java:#{@gem_spec.name}" => ["#{lib_path}/#{binary(platform)}"] # ensure the extension get copied unless Rake::Task.task_defined?("#{lib_path}/#{binary(platform)}") then file "#{lib_path}/#{binary(platform)}" => ["copy:#{name}:#{platform}"] end task 'java' => ["java:#{@gem_spec.name}"] end task 'java' do task 'compile' => 'compile:java' end end # # Discover Java Extension Directories and build an extdirs argument # def java_extdirs_arg extdirs = Java::java.lang.System.getProperty('java.ext.dirs') rescue nil extdirs = ENV['JAVA_EXT_DIR'] unless extdirs java_extdir = extdirs.nil? ? "" : "-extdirs \"#{extdirs}\"" end # # Discover the Java/JRuby classpath and build a classpath argument # # @params # *args:: Additional classpath arguments to append # # Copied verbatim from the ActiveRecord-JDBC project. There are a small myriad # of ways to discover the Java classpath correctly. # def java_classpath_arg(*args) jruby_cpath = nil if RUBY_PLATFORM =~ /java/ begin cpath = Java::java.lang.System.getProperty('java.class.path').split(File::PATH_SEPARATOR) cpath += Java::java.lang.System.getProperty('sun.boot.class.path').split(File::PATH_SEPARATOR) jruby_cpath = cpath.compact.join(File::PATH_SEPARATOR) rescue => e end end unless jruby_cpath libdir = RbConfig::CONFIG['libdir'] if libdir.start_with? "classpath:" raise 'Cannot build with jruby-complete' end jruby_cpath = File.join(libdir, "jruby.jar") end jruby_cpath += File::PATH_SEPARATOR + args.join(File::PATH_SEPARATOR) unless args.empty? jruby_cpath ? "-cp \"#{jruby_cpath}\"" : "" end end end rake-compiler-1.0.5/rake-compiler.gemspec000066400000000000000000000031021334215447600203530ustar00rootroot00000000000000# -*- ruby -*- Gem::Specification.new do |s| # basic information s.name = "rake-compiler" s.version = "1.0.5" s.platform = Gem::Platform::RUBY # description and details s.summary = 'Rake-based Ruby Extension (C, Java) task generator.' s.description = "Provide a standard and simplified way to build and package\nRuby extensions (C, Java) using Rake as glue." # requirements s.required_ruby_version = ">= 1.8.7" s.required_rubygems_version = ">= 1.8.23" # dependencies s.add_dependency 'rake' # development dependencies s.add_development_dependency 'rspec', '~> 2.8.0' s.add_development_dependency 'cucumber', '~> 1.1.4' # components, files and paths s.files = Dir.glob("features/**/*.{feature,rb}") s.files += ["bin/rake-compiler"] s.files += Dir.glob("lib/**/*.rb") s.files += ["spec/spec.opts"] s.files += Dir.glob("spec/**/*.rb") s.files += Dir.glob("tasks/**/*.rake") s.files += ["Rakefile", "Gemfile"] s.files += Dir.glob("*.{rdoc,txt,yml}") s.bindir = 'bin' s.executables = ['rake-compiler'] s.require_path = 'lib' # documentation s.rdoc_options << '--main' << 'README.rdoc' << '--title' << 'rake-compiler -- Documentation' s.extra_rdoc_files = %w(README.rdoc LICENSE.txt History.txt) # project information s.homepage = 'https://github.com/rake-compiler/rake-compiler' s.rubyforge_project = 'rake-compiler' s.licenses = ['MIT'] # author and contributors s.authors = ['Kouhei Sutou', 'Luis Lavena'] s.email = ['kou@cozmixng.org', 'luislavena@gmail.com'] end rake-compiler-1.0.5/spec/000077500000000000000000000000001334215447600152125ustar00rootroot00000000000000rake-compiler-1.0.5/spec/lib/000077500000000000000000000000001334215447600157605ustar00rootroot00000000000000rake-compiler-1.0.5/spec/lib/rake/000077500000000000000000000000001334215447600167025ustar00rootroot00000000000000rake-compiler-1.0.5/spec/lib/rake/extensiontask_spec.rb000066400000000000000000000577441334215447600231610ustar00rootroot00000000000000require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'rake/extensiontask' require 'rbconfig' describe Rake::ExtensionTask do context '#new' do context '(basic)' do it 'should raise an error if no name is provided' do lambda { Rake::ExtensionTask.new }.should raise_error(RuntimeError, /Extension name must be provided/) end it 'should allow string as extension name assignation' do ext = Rake::ExtensionTask.new('extension_one') ext.name.should == 'extension_one' end it 'should allow symbol as extension name assignation' do ext = Rake::ExtensionTask.new(:extension_one) ext.name.should == 'extension_one' end it 'should allow string as extension name using block assignation' do ext = Rake::ExtensionTask.new do |ext| ext.name = 'extension_two' end ext.name.should == 'extension_two' end it 'should return itself for the block' do from_block = nil from_lasgn = Rake::ExtensionTask.new('extension_three') do |ext| from_block = ext end from_block.should == from_lasgn end it 'should accept a gem specification as parameter' do spec = mock_gem_spec ext = Rake::ExtensionTask.new('extension_three', spec) ext.gem_spec.should == spec end it 'should allow gem specification be defined using block assignation' do spec = mock_gem_spec ext = Rake::ExtensionTask.new('extension_four') do |ext| ext.gem_spec = spec end ext.gem_spec.should == spec end it 'should allow forcing of platform' do ext = Rake::ExtensionTask.new('weird_extension') do |ext| ext.platform = 'universal-foo-bar-10.5' end ext.platform.should == 'universal-foo-bar-10.5' end end end context '(defaults)' do before :each do @ext = Rake::ExtensionTask.new('extension_one') end it 'should look for extconf script' do @ext.config_script.should == 'extconf.rb' end it 'should dump intermediate files to tmp/' do @ext.tmp_dir.should == 'tmp' end it 'should copy build extension into lib/' do @ext.lib_dir.should == 'lib' end it 'should look for C/C++ files pattern (.c,.cc,.cpp)' do @ext.source_pattern.should == "*.{c,cc,cpp}" end it 'should have no configuration options preset to delegate' do @ext.config_options.should be_empty end it "should have no includes preset to delegate" do @ext.config_includes.should be_empty end it 'should default to current platform' do @ext.platform.should == RUBY_PLATFORM end it 'should default to no cross compilation' do @ext.cross_compile.should == false end it 'should have no configuration options for cross compilation' do @ext.cross_config_options.should be_empty end it "should have cross platform defined to 'i386-mingw32'" do @ext.cross_platform.should == 'i386-mingw32' end end context '(tasks)' do before :each do Rake.application.clear CLEAN.clear CLOBBER.clear end context '(one extension)' do before :each do allow(Rake::FileList).to receive(:[]).and_return(["ext/extension_one/source.c"], []) @ext = Rake::ExtensionTask.new('extension_one') @ext_bin = ext_bin('extension_one') @platform = RUBY_PLATFORM @ruby_ver = RUBY_VERSION end context 'compile' do it 'should define as task' do Rake::Task.task_defined?('compile').should == true end it "should depend on 'compile:{platform}'" do Rake::Task['compile'].prerequisites.should include("compile:#{@platform}") end end context 'compile:extension_one' do it 'should define as task' do Rake::Task.task_defined?('compile:extension_one').should == true end it "should depend on 'compile:extension_one:{platform}'" do Rake::Task['compile:extension_one'].prerequisites.should include("compile:extension_one:#{@platform}") end end context 'lib/extension_one.{so,bundle}' do it 'should define as task' do Rake::Task.task_defined?("lib/#{@ext_bin}").should == true end it "should depend on 'copy:extension_one:{platform}:{ruby_ver}'" do Rake::Task["lib/#{@ext_bin}"].prerequisites.should include("copy:extension_one:#{@platform}:#{@ruby_ver}") end end context 'tmp/{platform}/extension_one/{ruby_ver}/extension_one.{so,bundle}' do it 'should define as task' do Rake::Task.task_defined?("tmp/#{@platform}/extension_one/#{@ruby_ver}/#{@ext_bin}").should == true end it "should depend on 'tmp/{platform}/extension_one/{ruby_ver}/Makefile'" do Rake::Task["tmp/#{@platform}/extension_one/#{@ruby_ver}/#{@ext_bin}"].prerequisites.should include("tmp/#{@platform}/extension_one/#{@ruby_ver}/Makefile") end it "should depend on 'ext/extension_one/source.c'" do Rake::Task["tmp/#{@platform}/extension_one/#{@ruby_ver}/#{@ext_bin}"].prerequisites.should include("ext/extension_one/source.c") end it "should not depend on 'ext/extension_one/source.h'" do Rake::Task["tmp/#{@platform}/extension_one/#{@ruby_ver}/#{@ext_bin}"].prerequisites.should_not include("ext/extension_one/source.h") end end context 'tmp/{platform}/extension_one/{ruby_ver}/Makefile' do it 'should define as task' do Rake::Task.task_defined?("tmp/#{@platform}/extension_one/#{@ruby_ver}/Makefile").should == true end it "should depend on 'tmp/{platform}/extension_one/{ruby_ver}'" do Rake::Task["tmp/#{@platform}/extension_one/#{@ruby_ver}/Makefile"].prerequisites.should include("tmp/#{@platform}/extension_one/#{@ruby_ver}") end it "should depend on 'ext/extension_one/extconf.rb'" do Rake::Task["tmp/#{@platform}/extension_one/#{@ruby_ver}/Makefile"].prerequisites.should include("ext/extension_one/extconf.rb") end end context 'clean' do it "should include 'tmp/{platform}/extension_one/{ruby_ver}' in the pattern" do CLEAN.should include("tmp/#{@platform}/extension_one/#{@ruby_ver}") end end context 'clobber' do it "should include 'lib/extension_one.{so,bundle}'" do CLOBBER.should include("lib/#{@ext_bin}") end it "should include 'tmp'" do CLOBBER.should include('tmp') end end it "should warn when pre-compiled files exist in extension directory" do allow(Rake::FileList).to receive(:[]). and_return(["ext/extension_one/source.c"], ["ext/extension_one/source.o"]) _, err = capture_output do Rake::ExtensionTask.new('extension_one') end err.should match(/rake-compiler found compiled files in 'ext\/extension_one' directory. Please remove them./) end end context '(extension in custom location)' do before :each do allow(Rake::FileList).to receive(:[]).and_return(["ext/extension_one/source.c"], []) @ext = Rake::ExtensionTask.new('extension_one') do |ext| ext.ext_dir = 'custom/ext/foo' end @ext_bin = ext_bin('extension_one') @platform = RUBY_PLATFORM @ruby_ver = RUBY_VERSION end context 'tmp/{platform}/extension_one/{ruby_ver}/Makefile' do it "should depend on 'custom/ext/foo/extconf.rb'" do Rake::Task["tmp/#{@platform}/extension_one/#{@ruby_ver}/Makefile"].prerequisites.should include("custom/ext/foo/extconf.rb") end end end context '(native tasks)' do before :each do allow(Rake::FileList).to receive(:[]).and_return(["ext/extension_one/source.c"], []) @spec = mock_gem_spec @ext_bin = ext_bin('extension_one') @platform = RUBY_PLATFORM @ruby_ver = RUBY_VERSION end context 'native' do before :each do allow(@spec).to receive(:platform=).and_return('ruby') end it 'should define a task for building the supplied gem' do Rake::ExtensionTask.new('extension_one', @spec) Rake::Task.task_defined?('native:my_gem').should == true end it 'should define as task for pure ruby gems' do Rake::Task.task_defined?('native').should == false Rake::ExtensionTask.new('extension_one', @spec) Rake::Task.task_defined?('native').should == true end it 'should not define a task for already native gems' do allow(@spec).to receive(:platform).and_return('current') Rake::ExtensionTask.new('extension_one', @spec) Rake::Task.task_defined?('native').should == false end it 'should depend on platform specific native tasks' do Rake::ExtensionTask.new('extension_one', @spec) Rake::Task["native"].prerequisites.should include("native:#{@platform}") end context 'native:my_gem:{platform}' do it 'should depend on binary extension' do Rake::ExtensionTask.new('extension_one', @spec) Rake::Task["native:my_gem:#{@platform}"].prerequisites.should include("tmp/#{@platform}/stage/lib/#{@ext_bin}") end end end end context '(one extension whose name with directory prefixes)' do before :each do allow(Rake::FileList).to receive(:[]).and_return(["ext/prefix1/prefix2/extension_one/source.c"], []) @ext = Rake::ExtensionTask.new('prefix1/prefix2/extension_one') @ext_bin = ext_bin('extension_one') @platform = RUBY_PLATFORM @ruby_ver = RUBY_VERSION end context 'compile' do it 'should define as task' do Rake::Task.task_defined?('compile').should == true end it "should depend on 'compile:{platform}'" do Rake::Task['compile'].prerequisites.should include("compile:#{@platform}") end end context 'compile:prefix1/prefix2/extension_one' do it 'should define as task' do Rake::Task.task_defined?('compile:prefix1/prefix2/extension_one').should == true end it "should depend on 'compile:prefix1/prefix2/extension_one:{platform}'" do Rake::Task['compile:prefix1/prefix2/extension_one'].prerequisites.should include("compile:prefix1/prefix2/extension_one:#{@platform}") end end context 'lib/prefix1/prefix2/extension_one.{so,bundle}' do it 'should define as task' do Rake::Task.task_defined?("lib/prefix1/prefix2/#{@ext_bin}").should == true end it "should depend on 'copy:prefix1/prefix2/extension_one:{platform}:{ruby_ver}'" do Rake::Task["lib/prefix1/prefix2/#{@ext_bin}"].prerequisites.should include("copy:prefix1/prefix2/extension_one:#{@platform}:#{@ruby_ver}") end end context 'tmp/{platform}/prefix1/prefix2/extension_one/{ruby_ver}/prefix1/prefix2/extension_one.{so,bundle}' do it 'should define as task' do Rake::Task.task_defined?("tmp/#{@platform}/prefix1/prefix2/extension_one/#{@ruby_ver}/prefix1/prefix2/#{@ext_bin}").should == true end it "should depend on 'tmp/{platform}/prefix1/prefix2/extension_one/{ruby_ver}/Makefile'" do Rake::Task["tmp/#{@platform}/prefix1/prefix2/extension_one/#{@ruby_ver}/prefix1/prefix2/#{@ext_bin}"].prerequisites.should include("tmp/#{@platform}/prefix1/prefix2/extension_one/#{@ruby_ver}/Makefile") end it "should depend on 'ext/extension_one/source.c'" do Rake::Task["tmp/#{@platform}/prefix1/prefix2/extension_one/#{@ruby_ver}/prefix1/prefix2/#{@ext_bin}"].prerequisites.should include("ext/prefix1/prefix2/extension_one/source.c") end it "should not depend on 'ext/extension_one/source.h'" do Rake::Task["tmp/#{@platform}/prefix1/prefix2/extension_one/#{@ruby_ver}/prefix1/prefix2/#{@ext_bin}"].prerequisites.should_not include("ext/prefix1/prefix2/extension_one/source.h") end end end context '(cross platform tasks)' do before :each do allow(File).to receive(:exist?).and_return(true) allow(YAML).to receive(:load_file).and_return(mock_config_yml) allow(Rake::FileList).to receive(:[]).and_return(["ext/extension_one/source.c"], []) @spec = mock_gem_spec @config_file = File.expand_path("~/.rake-compiler/config.yml") @ruby_ver = RUBY_VERSION @platform = 'i386-mingw32' @config_path = mock_config_yml["rbconfig-#{@platform}-#{@ruby_ver}"] allow(File).to receive(:open).and_yield(mock_fake_rb) end context 'if no rake-compiler configuration exists' do before :each do expect(File).to receive(:exist?).with(@config_file).and_return(false) _, @err = capture_output do Rake::ExtensionTask.new('extension_one') do |ext| ext.cross_compile = true end end end it 'should not generate a warning' do @err.should eq("") end it 'should create a dummy nested cross-compile target that raises an error' do Rake::Task.should have_defined("cross") Rake::Task["cross"].invoke lambda { Rake::Task["compile"].invoke }.should raise_error(RuntimeError, /rake-compiler must be configured first to enable cross-compilation/) end end it 'should parse the config file using YAML' do expect(YAML).to receive(:load_file).with(@config_file).and_return(mock_config_yml) Rake::ExtensionTask.new('extension_one') do |ext| ext.cross_compile = true end end it 'should warn if no section of config file defines running version of ruby' do config = Hash.new expect(config).to receive(:[]).with("rbconfig-#{@platform}-#{@ruby_ver}").and_return(nil) allow(YAML).to receive(:load_file).and_return(config) out, err = capture_output do Rake::ExtensionTask.new('extension_one') do |ext| ext.cross_compile = true end end err.should match(/no configuration section for specified version of Ruby/) end it 'should capture an action block to be executed when cross compiling' do lambda { Rake::ExtensionTask.new('extension_one') do |ext| ext.cross_compiling do |gem_spec| gem_spec.post_install_message = "Cross compiled gem" end end }.should_not raise_error end it 'should generate additional rake tasks if files are added when cross compiling' do config = Hash.new allow(config).to receive(:[]).and_return('/rubies/1.9.1/rbconfig.rb') allow(YAML).to receive(:load_file).and_return(config) # Use a real spec instead of a mock because define_native_tasks dups and # calls methods on Gem::Specification, which is more than mock can do. spec = Gem::Specification.new do |s| s.name = 'my_gem' s.platform = Gem::Platform::RUBY end # Gem::PackageTask calls Rake::PackageTask which sets Gem.configuration.verbose, # which initializes Gem::ConfigFile, # which gets mad if it cannot find `sysconfdir`/gemrc allow(Gem).to receive_message_chain(:configuration, :verbose=).and_return(true) ENV['RUBY_CC_VERSION'] = '1.9.1' Rake::ExtensionTask.new('extension_one', spec) do |ext| ext.cross_compile = true ext.cross_platform = 'universal-unknown' ext.cross_compiling do |gem_spec| gem_spec.files << 'somedir/somefile' end end Rake::Task['native:my_gem:universal-unknown'].execute Rake::Task.should have_defined("tmp/universal-unknown/stage/somedir") Rake::Task.should have_defined("tmp/universal-unknown/stage/somedir/somefile") end it 'should allow usage of RUBY_CC_VERSION to indicate a different version of ruby' do config = Hash.new expect(config).to receive(:[]).with("rbconfig-i386-mingw32-1.9.1").and_return('/rubies/1.9.1/rbconfig.rb') allow(YAML).to receive(:load_file).and_return(config) ENV['RUBY_CC_VERSION'] = '1.9.1' Rake::ExtensionTask.new('extension_one') do |ext| ext.cross_compile = true end end it 'should allow multiple versions be supplied to RUBY_CC_VERSION' do config = Hash.new expect(config).to receive(:[]).once.with("rbconfig-i386-mingw32-1.8.6").and_return('/rubies/1.8.6/rbconfig.rb') expect(config).to receive(:[]).once.with("rbconfig-i386-mingw32-1.9.1").and_return('/rubies/1.9.1/rbconfig.rb') allow(YAML).to receive(:load_file).and_return(config) ENV['RUBY_CC_VERSION'] = '1.8.6:1.9.1' Rake::ExtensionTask.new('extension_one') do |ext| ext.cross_compile = true end end it "should set required_ruby_version from RUBY_CC_VERSION, set platform, clear extensions but keep metadata" do platforms = ["x86-mingw32", "x64-mingw32"] ruby_cc_versions = ["1.8.6", "2.1.10", "2.2.6", "2.3.3", "2.10.1"] ENV["RUBY_CC_VERSION"] = ruby_cc_versions.join(":") config = Hash.new ruby_cc_versions.each do |ruby_cc_version| platforms.each do |platform| allow(config).to receive(:[]). with("rbconfig-#{platform}-#{ruby_cc_version}"). and_return("/rubies/#{ruby_cc_version}/rbconfig.rb") end end allow(YAML).to receive(:load_file).and_return(config) allow(Gem).to receive_message_chain(:configuration, :verbose=).and_return(true) spec = Gem::Specification.new do |s| s.name = 'my_gem' s.platform = Gem::Platform::RUBY s.extensions = ['ext/somegem/extconf.rb'] s.metadata['allowed_push_host'] = 'http://test' end cross_specs = [] Rake::ExtensionTask.new("extension_one", spec) do |ext| ext.cross_platform = platforms ext.cross_compile = true ext.cross_compiling do |cross_spec| cross_specs << cross_spec end end platforms.each do |platform| Rake::Task["native:my_gem:#{platform}"].execute end expected_required_ruby_versions = [ Gem::Requirement.new([">= 1.8", "< 2.11"]), Gem::Requirement.new([">= 1.8", "< 2.11"]), ] cross_specs.collect(&:required_ruby_version).should == expected_required_ruby_versions cross_specs.collect(&:extensions).should == [[], []] cross_specs.collect(&:platform).collect(&:to_s).should == platforms cross_specs.collect{|s| s.metadata['allowed_push_host']}.should == ['http://test', 'http://test'] # original gemspec should keep unchanged spec.required_ruby_version.should == Gem::Requirement.new([">= 0"]) spec.platform.should == Gem::Platform::RUBY spec.extensions.should == ['ext/somegem/extconf.rb'] spec.metadata['allowed_push_host'].should == 'http://test' end after :each do ENV.delete('RUBY_CC_VERSION') end context "(cross compile for multiple versions)" do before :each do config = Hash.new allow(config).to receive(:[]).and_return('/rubies/1.8.6/rbconfig.rb', '/rubies/1.9.1/rbconfig.rb') allow(YAML).to receive(:load_file).and_return(config) ENV['RUBY_CC_VERSION'] = '1.8.6:1.9.1' @ext = Rake::ExtensionTask.new('extension_one') do |ext| ext.cross_compile = true ext.cross_platform = 'universal-unknown' end end it 'should create specific copy of binaries for each version' do Rake::Task.should have_defined("copy:extension_one:universal-unknown:1.8.6") Rake::Task.should have_defined("copy:extension_one:universal-unknown:1.9.1") end end context "(cross for 'universal-unknown' platform)" do before :each do @ext = Rake::ExtensionTask.new('extension_one', @spec) do |ext| ext.cross_compile = true ext.cross_platform = 'universal-unknown' end end context 'fake' do it 'should chain fake task to Makefile generation' do Rake::Task["tmp/universal-unknown/extension_one/#{@ruby_ver}/Makefile"].prerequisites.should include("tmp/universal-unknown/extension_one/#{@ruby_ver}/fake.rb") end it 'should chain rbconfig tasks to fake.rb generation' do Rake::Task["tmp/universal-unknown/extension_one/#{@ruby_ver}/fake.rb"].prerequisites.should include(@config_path) end end context 'mkmf' do it 'should chain mkmf tasks to Makefile generation' do Rake::Task["tmp/universal-unknown/extension_one/#{@ruby_ver}/Makefile"].prerequisites.should include("tmp/universal-unknown/extension_one/#{@ruby_ver}/mkmf.rb") end it 'should take mkmf from rake-compiler configuration' do mkmf_path = File.expand_path(File.join(File.dirname(@config_path), '..', 'mkmf.rb')) Rake::Task["tmp/universal-unknown/extension_one/#{@ruby_ver}/mkmf.rb"].prerequisites.should include(mkmf_path) end end context 'compile:universal-unknown' do it "should be defined" do Rake::Task.task_defined?('compile:universal-unknown').should == true end it "should depend on 'compile:extension_one:universal-unknown'" do Rake::Task['compile:universal-unknown'].prerequisites.should include('compile:extension_one:universal-unknown') end end context 'native:universal-unknown' do it "should be defined" do Rake::Task.task_defined?('native:universal-unknown').should == true end it "should depend on 'native:my_gem:universal-unknown'" do Rake::Task['native:universal-unknown'].prerequisites.should include('native:my_gem:universal-unknown') end end end context '(cross for multiple platforms)' do before :each do @ext = Rake::ExtensionTask.new('extension_one', @spec) do |ext| ext.cross_compile = true ext.cross_platform = ['universal-known', 'universal-unknown'] ext.cross_config_options << '--with-something' ext.cross_config_options << {'universal-known' => '--with-known'} end end it 'should define task for each supplied platform' do Rake::Task.should have_defined('compile:universal-known') Rake::Task.should have_defined('compile:universal-unknown') end it 'should filter options for each supplied platform' do @ext.cross_config_options('universal-unknown').should eq(%w[--with-something]) @ext.cross_config_options('universal-known').should eq(%w[--with-something --with-known]) end end end end private def ext_bin(extension_name) "#{extension_name}.#{RbConfig::CONFIG['DLEXT']}" end def mock_gem_spec(stubs = {}) double(Gem::Specification, { :name => 'my_gem', :platform => 'ruby', :files => [] }.merge(stubs) ) end def mock_config_yml return @mock_config_yml if @mock_config_yml versions = { "1.8.6" => "1.8", "1.8.7" => "1.8", "1.9.3" => "1.9.1", "2.0.0" => "2.0.0", "2.1.2" => "2.1.0", RUBY_VERSION => RbConfig::CONFIG["ruby_version"] } platforms = [ "i386-mingw32", "universal-known", "universal-unknown", "x64-mingw32", RUBY_PLATFORM ] @mock_config_yml = {} platforms.collect do |platform| versions.each do |version, api_version| @mock_config_yml["rbconfig-#{platform}-#{version}"] = "/rubies/#{api_version}/rbconfig.rb" end end @mock_config_yml end def mock_fake_rb double(File, :write => 45) end end rake-compiler-1.0.5/spec/lib/rake/javaextensiontask_spec.rb000066400000000000000000000125031334215447600240030ustar00rootroot00000000000000require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'rake/javaextensiontask' require 'rbconfig' describe Rake::JavaExtensionTask do context '#new' do context '(basic)' do it 'should raise an error if no name is provided' do lambda { Rake::JavaExtensionTask.new }.should raise_error(RuntimeError, /Extension name must be provided/) end it 'should allow string as extension name assignation' do ext = Rake::JavaExtensionTask.new('extension_one') ext.name.should == 'extension_one' end it 'should allow string as extension name using block assignation' do ext = Rake::JavaExtensionTask.new do |ext| ext.name = 'extension_two' end ext.name.should == 'extension_two' end it 'should return itself for the block' do from_block = nil from_lasgn = Rake::JavaExtensionTask.new('extension_three') do |ext| from_block = ext end from_block.should == from_lasgn end it 'should accept a gem specification as parameter' do spec = mock_gem_spec ext = Rake::JavaExtensionTask.new('extension_three', spec) ext.gem_spec.should == spec end it 'should allow gem specification be defined using block assignation' do spec = mock_gem_spec ext = Rake::JavaExtensionTask.new('extension_four') do |ext| ext.gem_spec = spec end ext.gem_spec.should == spec end it 'should allow forcing of platform' do ext = Rake::JavaExtensionTask.new('weird_extension') do |ext| ext.platform = 'java-128bit' end ext.platform.should == 'java-128bit' end end end context '(defaults)' do before :each do @ext = Rake::JavaExtensionTask.new('extension_one') end it 'should dump intermediate files to tmp/' do @ext.tmp_dir.should == 'tmp' end it 'should copy build extension into lib/' do @ext.lib_dir.should == 'lib' end it 'should look for Java files pattern (.java)' do @ext.source_pattern.should == "**/*.java" end it 'should have no configuration options preset to delegate' do @ext.config_options.should be_empty end it 'should default to Java platform' do @ext.platform.should == 'java' end context '(tasks)' do before :each do Rake.application.clear CLEAN.clear CLOBBER.clear end context '(one extension)' do before :each do allow(Rake::FileList).to receive(:[]).and_return(["ext/extension_one/source.java"]) @ext = Rake::JavaExtensionTask.new('extension_one') @ext_bin = ext_bin('extension_one') @platform = 'java' end context 'compile' do it 'should define as task' do Rake::Task.task_defined?('compile').should == true end it "should depend on 'compile:{platform}'" do pending 'needs fixing' Rake::Task['compile'].prerequisites.should include("compile:#{@platform}") end end context 'compile:extension_one' do it 'should define as task' do Rake::Task.task_defined?('compile:extension_one').should == true end it "should depend on 'compile:extension_one:{platform}'" do pending 'needs fixing' Rake::Task['compile:extension_one'].prerequisites.should include("compile:extension_one:#{@platform}") end end context 'lib/extension_one.jar' do it 'should define as task' do pending 'needs fixing' Rake::Task.task_defined?("lib/#{@ext_bin}").should be_true end it "should depend on 'copy:extension_one:{platform}'" do pending 'needs fixing' Rake::Task["lib/#{@ext_bin}"].prerequisites.should include("copy:extension_one:#{@platform}") end end context 'tmp/{platform}/extension_one/extension_one.jar' do it 'should define as task' do Rake::Task.task_defined?("tmp/#{@platform}/extension_one/#{@ext_bin}").should == true end it "should depend on checkpoint file" do Rake::Task["tmp/#{@platform}/extension_one/#{@ext_bin}"].prerequisites.should include("tmp/#{@platform}/extension_one/.build") end end context 'tmp/{platform}/extension_one/.build' do it 'should define as task' do Rake::Task.task_defined?("tmp/#{@platform}/extension_one/.build").should == true end it 'should depend on source files' do Rake::Task["tmp/#{@platform}/extension_one/.build"].prerequisites.should include("ext/extension_one/source.java") end end context 'clean' do it "should include 'tmp/{platform}/extension_one' in the pattern" do CLEAN.should include("tmp/#{@platform}/extension_one") end end context 'clobber' do it "should include 'lib/extension_one.jar'" do CLOBBER.should include("lib/#{@ext_bin}") end it "should include 'tmp'" do CLOBBER.should include('tmp') end end end end end private def ext_bin(extension_name) "#{extension_name}.jar" end def mock_gem_spec(stubs = {}) double(Gem::Specification, { :name => 'my_gem', :platform => 'ruby' }.merge(stubs) ) end end rake-compiler-1.0.5/spec/spec.opts000066400000000000000000000000501334215447600170460ustar00rootroot00000000000000--colour --format nested --loadby mtime rake-compiler-1.0.5/spec/spec_helper.rb000066400000000000000000000005021334215447600200250ustar00rootroot00000000000000require 'rspec' # Console redirection helper require File.expand_path('../support/capture_output_helper', __FILE__) RSpec.configure do |config| config.include CaptureOutputHelper end # Rake::Task matcher helper RSpec::Matchers.define :have_defined do |task| match do |tasks| tasks.task_defined?(task) end end rake-compiler-1.0.5/spec/support/000077500000000000000000000000001334215447600167265ustar00rootroot00000000000000rake-compiler-1.0.5/spec/support/capture_output_helper.rb000066400000000000000000000006331334215447600236770ustar00rootroot00000000000000module CaptureOutputHelper def capture_output(&block) old_stdout = $stdout old_stderr = $stderr stream_out = StringIO.new stream_err = StringIO.new begin $stdout = stream_out $stderr = stream_err yield ensure $stdout = old_stdout $stderr = old_stderr end stream_out.rewind stream_err.rewind [stream_out.read, stream_err.read] end end rake-compiler-1.0.5/tasks/000077500000000000000000000000001334215447600154055ustar00rootroot00000000000000rake-compiler-1.0.5/tasks/bin/000077500000000000000000000000001334215447600161555ustar00rootroot00000000000000rake-compiler-1.0.5/tasks/bin/cross-ruby.rake000066400000000000000000000151711334215447600211360ustar00rootroot00000000000000#-- # Cross-compile ruby, using Rake # # This source code is released under the MIT License. # See LICENSE file for details #++ # # This code is inspired and based on notes from the following sites: # # http://tenderlovemaking.com/2008/11/21/cross-compiling-ruby-gems-for-win32/ # http://github.com/jbarnette/johnson/tree/master/cross-compile.txt # http://eigenclass.org/hiki/cross+compiling+rcovrt # # This recipe only cleanup the dependency chain and automate it. # Also opens the door to usage different ruby versions # for cross-compilation. # require 'rake' require 'rake/clean' begin require 'psych' rescue LoadError end require 'yaml' require "rbconfig" # load compiler helpers # add lib directory to the search path libdir = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib')) $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir) if RUBY_PLATFORM =~ /mingw|mswin/ then puts "This command is meant to be executed under Linux or OSX, not Windows (is for cross-compilation)" exit(1) end require 'rake/extensioncompiler' MAKE = ENV['MAKE'] || %w[gmake make].find { |c| system("#{c} -v > /dev/null 2>&1") } USER_HOME = File.expand_path("~/.rake-compiler") RUBY_CC_VERSION = "ruby-" << ENV.fetch("VERSION", "1.8.7-p371") RUBY_SOURCE = ENV['SOURCE'] RUBY_BUILD = RbConfig::CONFIG["host"] # grab the major "1.8" or "1.9" part of the version number MAJOR = RUBY_CC_VERSION.match(/.*-(\d.\d).\d/)[1] # Use Rake::ExtensionCompiler helpers to find the proper host MINGW_HOST = ENV['HOST'] || Rake::ExtensionCompiler.mingw_host MINGW_TARGET = MINGW_HOST.gsub('msvc', '') # Unset any possible variable that might affect compilation ["CC", "CXX", "CPPFLAGS", "LDFLAGS", "RUBYOPT"].each do |var| ENV.delete(var) end # define a location where sources will be stored directory "#{USER_HOME}/sources/#{RUBY_CC_VERSION}" directory "#{USER_HOME}/builds/#{MINGW_HOST}/#{RUBY_CC_VERSION}" # clean intermediate files and folders CLEAN.include("#{USER_HOME}/sources/#{RUBY_CC_VERSION}") CLEAN.include("#{USER_HOME}/builds/#{MINGW_HOST}/#{RUBY_CC_VERSION}") # remove the final products and sources CLOBBER.include("#{USER_HOME}/sources") CLOBBER.include("#{USER_HOME}/builds") CLOBBER.include("#{USER_HOME}/ruby/#{MINGW_HOST}/#{RUBY_CC_VERSION}") CLOBBER.include("#{USER_HOME}/config.yml") # ruby source file should be stored there file "#{USER_HOME}/sources/#{RUBY_CC_VERSION}.tar.bz2" => ["#{USER_HOME}/sources"] do |t| # download the source file using wget or curl chdir File.dirname(t.name) do if RUBY_SOURCE url = RUBY_SOURCE else url = "http://cache.ruby-lang.org/pub/ruby/#{MAJOR}/#{File.basename(t.name)}" end sh "wget #{url} || curl -O #{url}" end end # Extract the sources source_file = RUBY_SOURCE ? RUBY_SOURCE.split('/').last : "#{RUBY_CC_VERSION}.tar.bz2" file "#{USER_HOME}/sources/#{RUBY_CC_VERSION}" => ["#{USER_HOME}/sources/#{source_file}"] do |t| chdir File.dirname(t.name) do t.prerequisites.each { |f| sh "tar xf #{File.basename(f)}" } end end # backup makefile.in file "#{USER_HOME}/sources/#{RUBY_CC_VERSION}/Makefile.in.bak" => ["#{USER_HOME}/sources/#{RUBY_CC_VERSION}"] do |t| cp "#{USER_HOME}/sources/#{RUBY_CC_VERSION}/Makefile.in", t.name end # correct the makefiles file "#{USER_HOME}/sources/#{RUBY_CC_VERSION}/Makefile.in" => ["#{USER_HOME}/sources/#{RUBY_CC_VERSION}/Makefile.in.bak"] do |t| content = File.open(t.name, 'rb') { |f| f.read } out = "" content.each_line do |line| if line =~ /^\s*ALT_SEPARATOR =/ out << "\t\t ALT_SEPARATOR = \"\\\\\\\\\"; \\\n" else out << line end end when_writing("Patching Makefile.in") { File.open(t.name, 'wb') { |f| f.write(out) } } end task :mingw32 do unless MINGW_HOST then warn "You need to install mingw32 cross compile functionality to be able to continue." warn "Please refer to your distribution/package manager documentation about installation." fail end end # generate the makefile in a clean build location file "#{USER_HOME}/builds/#{MINGW_HOST}/#{RUBY_CC_VERSION}/Makefile" => ["#{USER_HOME}/builds/#{MINGW_HOST}/#{RUBY_CC_VERSION}", "#{USER_HOME}/sources/#{RUBY_CC_VERSION}/Makefile.in"] do |t| options = [ "--host=#{MINGW_HOST}", "--target=#{MINGW_TARGET}", "--build=#{RUBY_BUILD}", '--enable-shared', '--disable-install-doc', '--with-ext=' ] # Force Winsock2 for Ruby 1.8, 1.9 defaults to it options << "--with-winsock2" if MAJOR == "1.8" chdir File.dirname(t.name) do prefix = File.expand_path("../../../ruby/#{MINGW_HOST}/#{RUBY_CC_VERSION}") options << "--prefix=#{prefix}" sh File.expand_path("../../../sources/#{RUBY_CC_VERSION}/configure"), *options end end # make file "#{USER_HOME}/builds/#{MINGW_HOST}/#{RUBY_CC_VERSION}/ruby.exe" => ["#{USER_HOME}/builds/#{MINGW_HOST}/#{RUBY_CC_VERSION}/Makefile"] do |t| chdir File.dirname(t.prerequisites.first) do sh MAKE end end # make install file "#{USER_HOME}/ruby/#{MINGW_HOST}/#{RUBY_CC_VERSION}/bin/ruby.exe" => ["#{USER_HOME}/builds/#{MINGW_HOST}/#{RUBY_CC_VERSION}/ruby.exe"] do |t| chdir File.dirname(t.prerequisites.first) do sh "#{MAKE} install" end end task :install => ["#{USER_HOME}/ruby/#{MINGW_HOST}/#{RUBY_CC_VERSION}/bin/ruby.exe"] desc "Update rake-compiler list of installed Ruby versions" task 'update-config' do config_file = "#{USER_HOME}/config.yml" if File.exist?(config_file) then puts "Updating #{config_file}" config = YAML.load_file(config_file) else puts "Generating #{config_file}" config = {} end files = Dir.glob("#{USER_HOME}/ruby/*/*/**/rbconfig.rb").sort files.each do |rbconfig| version, platform = rbconfig.match(/.*-(\d.\d.\d).*\/([-\w]+)\/rbconfig/)[1,2] platforms = [platform] # fake alternate (binary compatible) i386-mswin32-60 platform platform == "i386-mingw32" and platforms.push "i386-mswin32-60" platforms.each do |plat| config["rbconfig-#{plat}-#{version}"] = rbconfig # also store RubyGems-compatible version gem_platform = Gem::Platform.new(plat) config["rbconfig-#{gem_platform}-#{version}"] = rbconfig end puts "Found Ruby version #{version} for platform #{platform} (#{rbconfig})" end when_writing("Saving changes into #{config_file}") { File.open(config_file, 'w') do |f| f.puts config.to_yaml end } end task :default do # Force the display of the available tasks when no option is given Rake.application.options.show_task_pattern = // Rake.application.display_tasks_and_comments end desc "Build #{RUBY_CC_VERSION} suitable for cross-platform development." task 'cross-ruby' => [:mingw32, :install, 'update-config'] rake-compiler-1.0.5/tasks/bootstrap.rake000066400000000000000000000005671334215447600202760ustar00rootroot00000000000000desc 'Ensure all the cross compiled versions are installed' task :bootstrap do fail "Sorry, this only works on OSX and Linux" if RUBY_PLATFORM =~ /mswin|mingw/ versions = %w(1.8.7-p371 1.9.3-p392 2.0.0-p0) versions.each do |version| puts "[INFO] Attempt to cross-compile Ruby #{version}" ruby "-Ilib bin/rake-compiler cross-ruby VERSION=#{version}" end end rake-compiler-1.0.5/tasks/common.rake000066400000000000000000000003421334215447600175400ustar00rootroot00000000000000require 'rake/clean' # common pattern cleanup CLOBBER.include('tmp') # set default task task :default => [:spec, :features] # make packing depend on success of running specs and features task :package => [:spec, :features] rake-compiler-1.0.5/tasks/cucumber.rake000066400000000000000000000012771334215447600200650ustar00rootroot00000000000000begin require 'cucumber/rake/task' rescue LoadError warn "Cucumber gem is required, please install it. (gem install cucumber)" end if defined?(Cucumber) namespace :cucumber do Cucumber::Rake::Task.new('default', 'Run features testing C extension support') do |t| t.profile = 'default' t.cucumber_opts = '--format pretty --no-source' end Cucumber::Rake::Task.new('java', 'Run features testing Java extension support') do |t| t.profile = 'java' t.cucumber_opts = '--format pretty --no-source' end desc 'Run all features' task :all => [:default, :java] end desc 'Alias for cucumber:default' task :cucumber => 'cucumber:default' end rake-compiler-1.0.5/tasks/gem.rake000066400000000000000000000005021334215447600170160ustar00rootroot00000000000000require 'rubygems/package_task' gemspec_path = File.join(__dir__, "..", "rake-compiler.gemspec") gemspec_path = File.expand_path(gemspec_path) GEM_SPEC = eval(File.read(gemspec_path), TOPLEVEL_BINDING, gemspec_path) gem_package = Gem::PackageTask.new(GEM_SPEC) do |pkg| pkg.need_tar = false pkg.need_zip = false end rake-compiler-1.0.5/tasks/news.rake000066400000000000000000000020351334215447600172250ustar00rootroot00000000000000desc 'Generate email template to standard output' task :announce do fail "no GEM_SPEC is found or defined. 'announce' task cannot work without it." unless defined?(GEM_SPEC) # read project info and overview notes = begin r = File.read("README.rdoc") r.split(/^(=+ .*)/)[1..4].join.strip rescue warn "Missing README.rdoc" '' end # read changes changes = begin h = File.read("History.txt") h.split(/^(===+ .*)/)[1..2].join.strip rescue warn "Missing History.txt" '' end # standard fields subject = "#{GEM_SPEC.name} #{GEM_SPEC.version} Released" title = "#{GEM_SPEC.name} version #{GEM_SPEC.version} has been released!" body = "#{notes}\n\nChanges:\n\n#{changes}" urls = [GEM_SPEC.homepage].map { |u| "* <#{u.strip}>" }.join("\n") puts "=" * 80, "" puts "Subject: [ANN] #{subject}" puts puts title puts puts urls puts puts body puts puts "=" * 80, "" end rake-compiler-1.0.5/tasks/release.rake000066400000000000000000000014001334215447600176640ustar00rootroot00000000000000desc 'Package gems and upload to RubyGems' task :release, [:version] => [:package] do |t, args| args.with_defaults(:version => "") ver = args.version fail "no GEM_SPEC is found or defined. 'release' task cannot work without it." unless defined?(GEM_SPEC) # compare versions to avoid mistakes unless ver == GEM_SPEC.version.to_s then fail "Version mismatch (supplied and specification versions differ)." end files = FileList["pkg/#{GEM_SPEC.name}-#{GEM_SPEC.version}*.*"].to_a fail "No files found for the release." if files.empty? puts "Files to release:" files.each do |f| puts " * #{f}" end puts "Releasing #{GEM_SPEC.name} version #{GEM_SPEC.version}..." files.each do |f| system "gem push #{f}" end puts "Done." end rake-compiler-1.0.5/tasks/rspec.rake000066400000000000000000000003231334215447600173630ustar00rootroot00000000000000begin require "rspec/core/rake_task" rescue LoadError => e warn "RSpec gem is required, please install it (gem install rspec)." end if defined?(RSpec::Core::RakeTask) RSpec::Core::RakeTask.new(:spec) end