Building C extension compatibility
-
Is it possible to compile/build a Ruby C extension that would be compatible on all Ruby versions or perhaps compile extension that requires Ruby 1.8.7+ on Ruby 1.8.6? I just have troubles compiling Ruby FFI for Ruby 1.8.6. It seems Ruby FFI requires some library from Ruby 1.8.7, but is not included in 1.8.6. Of course, I can ask the plugin user to update their Ruby core to 1.8.7, but I'm aware that not many people would like doing this tick. Any suggestion?
-
I would not go down the path of asking the user to update the Ruby interpreter. Consider that voiding the warranty - it haven't been tested by us and would not be supported.
I think they did a few incompatible changes between 1.8.7 and 1.8.6 which makes binaries incompatible. FFI was never released to 1.8.6? There are no archived versions?
-
@tt_su said:
I would not go down the path of asking the user to update the Ruby interpreter. Consider that voiding the warranty - it haven't been tested by us and would not be supported.
I think they did a few incompatible changes between 1.8.7 and 1.8.6 which makes binaries incompatible. FFI was never released to 1.8.6? There are no archived versions?
I don't know about the archived version. FFI uses rb_hash_lookup funciton which comes available in Ruby 1.8.7+. I tried copying some files from 1.8.7 to ffi gem, but copied files required even more files, and the other more, until I couldn't even handle 'em anymore . So thats the trouble of compiling on 1.8.6 - can't happen lol. I came across a different idea though. I would use Ruby Dl for 1.8.6 and below, and FFI for 1.8.7+.
-
Was rb_hash_lookup the only function it was missing? Sounds like there should be a function like that - might be under a different name. On the olden days they where quite found of naming functions post_fixed with 1,2,3 etc instead of proper names.
-
@tt_su said:
Was rb_hash_lookup the only function it was missing? Sounds like there should be a function like that - might be under a different name.
Aha!!! rb_hash_lookup is very similar to rb_hash_aref. rb_hash_aref is in both 1.8.6 and 1.8.7. The difference between is that one's default return value is 0 and the other's default return value is nil. I will replace rb_hash_lookup with rb_hash_aref and try compile.
Edit: Yes, to compile FFI for ruby 1.8.6 you only had to replace the rb_hash_lookup. I tested and it works well! Now, FFI will work in Ruby 1.8.6+, which means I can use it in SU8 or later; however, SU6 and SU7 uses Ruby 1.8.0, I will have to find what its missing...
Edit: Is there a windows installer for Ruby 1.8.0? Can you help me find it?
Edit: Actually I think there shouldn't be support for SU7 or below. I will simply ask them to update their Ruby core to 1.8.6 or 1.8.7 if for some reason they are willing to use the plugin in SU7 or below.
-
You might not need to recompile for 1.8.0. I think in large part 1.8.0-1.8.6 Ruby will run 1.8.6 binaries. It's first at 1.8.7 they made notable change.
If anyone hook 1.8.7 into SketchUp that might break other extensions.Vertex Tools contained a C Extension, and it ran all the way down to SU6 - no need to recompile. Though I don't recall which Ruby version I used then - it was written in pure C. But I think it was a newer 1.8.x version.
-
The reason I asked about 1.8.0 because the recompiled ams_ffi_c.so works on 1.8.6 or 1.8.7, but raises an error in 1.8.0.
If not much changes were made between 1.8.0 and 1.8.6, can you give me a link to windows installer for 1.8.0? I wanna find a ruby function which made ffi incompatible.
Also, Thomthom, I'm wondering on what Ruby version did you compile your C extension? Was it on 1.8.7, 1.8.6 or 1.8.0? Is it supposed to be compiled on the least available Ruby version in 1.8.x categories in order to have it work on all 1.8 versions?
-
Ok, I found a link to old Ruby versions: https://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/
I will investigate. -
@anton_s said:
Also, Thomthom, I'm wondering on what Ruby version did you compile your C extension? Was it on 1.8.7, 1.8.6 or 1.8.0? Is it supposed to be compiled on the least available Ruby version in 1.8.x categories in order to have it work on all 1.8 versions?
I have moved away from doing pure C extensions using Ruby's own build tools. C++ is so much nicer to work with and having multiple versions of Ruby under OSX is a pain - even with RVM. The old 1.8 32bit Ruby versions really has reached their end of days and getting it to compile under Maverics etc just thins out your hair... :s
I now recommend anyone to use the C++ example we have at GitHub. It has the libraries and headers that SketchUp uses: https://github.com/SketchUp/ruby-c-extension-examples
All though, not the 1.8.0 ones - they are just too old to keep support for. -
To clarify, I currently compile 1.8.6 and 2.0.0 for my extensions. (PC)
-
Unfortunately, I couldn't compile ffi on 1.8.0.
First I added devkit to 1.8.0I had to do a few things to make it compatible:
- Add to rbconfig.rb:
RbConfig = Config # compatibility for ruby-1.9
- Modify LongDouble.c in ffi: Replace RSTRING_PTR(s) with (RSTRING(s)->ptr) in line 44
- Add
find_header
method to mkfk.rb; copied it from Ruby 1.8.6 mkfk.rb
Then I called ruby extconf.rb once again to ensure I have no errors.
Then I calledmake
and got the missing separator error at line 138 in makefile.
So, I replacedLIBFFI_HOST=--host=i686-mswin32 !include $(srcdir)/libffi.vc.mk
with
LIBFFI_HOST=--host= include ${srcdir}/libffi.mk
I copied the code from Makefile created in Ruby 1.8.6.
After that everything started compiling, until it got to AbstractMemory.obj:
Google search tells me I have to include cl.exe, but I haven't figured out how, even after looking in from stack overflow: http://stackoverflow.com/questions/7865432/command-line-compile-using-cl-exe - Add to rbconfig.rb:
-
@tt_su said:
I now recommend anyone to use the C++ example we have at GitHub. It has the libraries and headers that SketchUp uses: https://github.com/SketchUp/ruby-c-extension-examples
Thanks for mentioning.
@tt_su said:
If anyone hook 1.8.7 into SketchUp that might break other extensions.
Thanks for mentioning that too. I once came up with an error when copied the latest 1.8.7 core to SU8, but can't recall which plugin raised it. Though, there is a stable release which Dan Rathbun provided. It didn't raise any errors.
@tt_su said:
To clarify, I currently compile 1.8.6 and 2.0.0 for my extensions. (PC)
Right... Compiled ams__api (win32-api) on Ruby 1.8.7 and it works on all ruby 1.8.x versions.
-
@anton_s said:
[*]Modify LongDouble.c in ffi: Replace RSTRING_PTR(s) with (RSTRING(s)->ptr) in line
Easier and more maintainable to add the macros if they are undefined:
https://bitbucket.org/thomthom/tt-library-2/src/be17bac137aa5421323733cc206d80b9ff885dc4/Ruby%20C%20Extensions/win32-api/ext/tt_api.c?at=Version%202.9#cl-5
Advertisement