Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for cross builds for multiple target platforms. #74

Merged
merged 3 commits into from
May 5, 2013

Conversation

larskanis
Copy link
Member

Hi Luis,

I use rake-compiler's cross compilation support in several projects and now that you released Ruby-2.0.0-p0 for 32 and 64 bit Windows platforms, it would like to update it properly for 64 bit. So attached you can find two patches that allow the following use case:

$ rake-compiler cross-ruby VERSION=1.8.7-p371
$ rake-compiler cross-ruby VERSION=1.9.3-p125
$ 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

With

ext.cross_platform = %w[i386-mingw32 x64-mingw32]

it builds 4 different targets of the extension.

Unfortunately only the compile task does work right now. The native task copies the compiled extension binaries into the lib directory in order to later build a gem from the base directory. This conflicts for the 2.0 so-file which then is built only once but packaged into two gems.

I guess the only solution is to use different temporary directories for the packaging of cross compiled gems. How would you like to solve this issue?

… platform.

Also prefix the selection of rbconfig in config.yml with the corresponding
Ruby platform.

This allowes to use cross compiled Ruby-builds for multiple target
architectures on the same machine. This is especially usefull to compile
for Ruby-2.0 i386-mingw32 and x64-mingw32 platforms.
This is especially useful to set distinct library paths for different
target platforms.
@luislavena
Copy link
Contributor

@larskanis nice!

I honestly must admit that I've been neglecting rake-compiler support for 64bits because I want to focus on gem-compiler instead.

I'll try to update rake-compiler dependencies and ensure Travis builds again so I can merge your work.

Thank you!

@larskanis
Copy link
Member Author

Thank you for the pointer to gem-compiler. But since it lacks cross compilation completely, it is probably not the best choice for me, currently.
May I help regarding to travis? What about the issue with the 'native' task described above? May I propose a solution per pull request?

@luislavena
Copy link
Contributor

Thank you for the pointer to gem-compiler. But since it lacks cross compilation completely, it is probably not the best choice for me, currently.

I know, but wanted to mention that I'm investing my time on an different approach that might help in the long run (and that I need help, too) 😉

I'll take a look to the Travis stuff, specially to determine if we can setup a cross-compiler or something to test the features.

Will merge this soon, promise.

@larskanis
Copy link
Member Author

I've setup cross compilation on travis for https://github.com/ged/ruby-pg . The rake-compiler ruby-cross task is insofar a bit tested there (but sure does not help for this project).

Do you plan to stop supporting rake-compiler in favor of gem-compiler?

@flavorjones
Copy link
Contributor

We've got people asking for 64-bit 2.0 support for Nokogiri at sparklemotion/nokogiri#864, so I'd love to see this merged as well. <3 <3 <3!

@stibra
Copy link

stibra commented Mar 23, 2013

Hi all,

I would like to help with time and servers for testing to bring the best experience for Ruby on Rails running on Windows Servers (2008 R2 and 2012) in enterprise and cloud enviroments using IIS for web server. There is no real need to support 32-bit anymore in Windows for production enviroment because there is no more 32-bit version of Windows Server available, so x64 is the only way to go.

Cheers,

Ratko

Building gems for distinct platforms within one rake run conflicted
in the lib/ directory, because all binary extensions were stored
there and were copied from there to become packaged.
This resulted in storing a binary extension of a wrong platform in
a gem.

To avoid this, the files to package are now stored in a platform specific
stage directory and are used to package the specific gem.
@larskanis
Copy link
Member Author

OK, above is a proposal for the packaging of gem files targeting distinct platforms (within one rake run). Maybe it is overly complicated, but I couldn't find a more simple and clean way to accomplish this. This way building fat binary gems for x86 and x64 should work out of the box for many projects after adding 'x64-mingw32' to the cross_platform list and the usual commands:

rake cross native gem RUBY_CC_VERSION=1.8.7:1.9.3:2.0.0

No longer using the lib/ directory for packaging can have implications to the projects using rake-compiler. The ffi.gem for instance does strip the binaries before packaging within lib/ . It is trivial to fix, but this patch makes rake-compiler obviously not 100% compatible to the previous state.

I also tested the cross compiled built of pg.gem, fxruby.gem and pkcs11.gem successfully.

@luislavena
Copy link
Contributor

Hello @larskanis

I'm working on integrate this, I haven't forgotten.

I noticed that the change on config.yml will require current users to reinstall or relocate the existing versions of installed Rubies before they can cross-compile again.

I'll merge this in an plan for 0.9.0 release this weekend.

@larskanis
Copy link
Member Author

I noticed that the change on config.yml will require current users to reinstall or relocate the existing versions of installed Rubies before they can cross-compile again.

Not really. They only need to run "rake-compiler update-config" once.

luislavena added a commit that referenced this pull request May 5, 2013
Add support for cross builds for multiple target platforms.
@luislavena luislavena merged commit 2af5978 into rake-compiler:master May 5, 2013
@luislavena
Copy link
Contributor

@larskanis in case you missed, I've merged this into master and pushed further modifications so Travis now works:

https://travis-ci.org/luislavena/rake-compiler

However, there is a small issue.

Now that platform is in the configuration file, I'm no longer able to cross compile for i386-mswin32 unless I manually duplicate i386-mingw32 into i386-mswin32

This will affect my current setup for gems like mysql and sqlite3, and dunno any other developers out there building gems for both platforms.

I'll do some changes in cross-ruby task so we fake it, but wanted to let you know some of the caveats (and will serve me to point later on when people ask me questions) 😁

Once again, thank you for your work on this and please sorry my delay on getting this merged.

Thank you! ❤️ ❤️ ❤️

@larskanis
Copy link
Member Author

Now that platform is in the configuration file, I'm no longer able to cross compile for i386-mswin32 unless I manually duplicate i386-mingw32 into i386-mswin32

That's true. I always considered this as a bug, but worried that it could be a feature. I think we can live with the fake until MSVC++ is natively available on Linux/OSX ;-)

Thank you for merging this and releasing the prerelease. I'll test it.

@luislavena
Copy link
Contributor

@larskanis I've encountered one issue with this while attempting to build x64-mingw32 of sqlite3-ruby gem.

cross-platforms are defined as:

    ext.cross_platform = ['i386-mswin32-60', 'i386-mingw32', 'x64-mingw32']

Since it depends on sqlite3 dependency, it needs to be build, that is no problem 😉

Problem is that: rake cross compile RUBY_CC_VERSION=1.8.7:1.9.3:2.0.0 will also attempt to build x64-mingw32 without tweaking the HOST platform of the recipe, causing it to fail:

cp tmp/i386-mingw32/sqlite3_native/2.0.0/sqlite3_native.so tmp/i386-mingw32/stage/lib/sqlite3/2.0/sqlite3_native.so
cd tmp/x64-mingw32/sqlite3_native/2.0.0
/opt/rbenv/versions/1.8.7-p371/bin/ruby -I. ../../../../ext/sqlite3/extconf.rb --enable-local
LDFLAGS: "-L/home/vagrant/sqlite3-ruby/ports/i686-w64-mingw32/sqlite3/3.7.11/lib"
checking for sqlite3.h... yes
checking for sqlite3_libversion_number()... -lsqlite3

In the above output I added some debug lines to extconf.rb to check LDFLAGS (set by mini_portile)

The only alternative I think of is by making the platform selection something triggered by a flag:

$ rake cross compile RUBY_CC_VERSION=1.8.7:1.9.3:2.0.0
...
$ rake cross compile RUBY_CC_VERSION=2.0.0 X64=1

But that will require modifications to every single recipe.

I think my approach to enabling sqlite3 dependency is flawed. Any recommendation by your experiments building ruby-pg?

Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants