What exactly is a gem native extension? - ruby

I feel that a native extension is like libraries that you should install onto your system before trying to install those gems, which depend on the native extensions. Like the ImageMagic library. Is that correct? Is there something else that we should know about native extensions?

A gem native extension might link to a separate library that needs to be pre-installed, and RMagick is an example of that.
However, the term really just means "includes some code that needs to be compiled for your machine". The code is compiled and linked so that the resulting executable file can be required by Ruby on the machine.
The usual reasons for writing a Ruby C or C++ extension are:
Speed. For some CPU-intense tasks, C code can be 100 times faster than Ruby. In this case a native extension can be completely stand-alone with all C source code included in the gem.
Third-party library already written in C. In this case the gem will have C source code that binds the library functions into Ruby modules, classes and methods.
You can view the C source code for gems with native extensions, it is installed alongside the Ruby source code. By convention, there is a folder inside the gem called ext/gem_name which contains a Ruby file extconf.rb that passes information to the compiler (technically it creates a make file). In addition the C source files are put there as well.
MRI Ruby is implemented as a very "flat" structure in C, basically consisting of a large number of C functions. This makes it relatively easy to learn how to implement a native extension, even if you don't know much C. You can read Extending Ruby 1.9 as an introduction to the topic.
Native extensions can fail to install or work properly. There are many questions on Stack Overflow asking for help with specific failed installs. The usual problems are:
Missing libraries. Hopefully the gem author will explain what you need to pre-install in the README, but is not always clear.
Compiler mismatches. It is difficult to test all target systems, so sometimes the instructions in extconf.rb won't work on a specific system, or the C code will raise warnings or not compile due to differences. In Windows, you probably won't have a working compiler unless you install the Ruby Devkit
Will not work with all versions of Ruby. For instance, JRuby can use C native extensions, if it has been enabled but it is not always advisable - the topic is quite complex, but generally avoid mixing JRuby and native extensions.

Native extension is just a gem which is written (entirely or partially) in C.
It may or may not depend on an external library, this is not a factor here. What matters is that such gem needs to be compiled and it is likely to be platform-dependant (there was a reason to use C, right? Maybe for using some low-level OS API or something. But most often it's to interface with a library).

Quoting this article
“Native extensions” are the glue that connects a Ruby gem with some other non-Ruby software component or library present on your machine.
The native extensionis not the dependency. A native extension is generally a C code that interacts with a non-Ruby dependency.
For instance, a gem that uses ImageMagic have a native extension written in C that talks to ImageMagic and represents the bridge from the Ruby gem to ImageMagic.
When you install the gem and the native extension is compiled, you don't compile the C library (e.g ImageMagic), that library must be already present on your system. You compile the C bridge bundled with the gem.

I'm not big ruby specialist, so take this with a grain of salt:
I'm fairly certain that it's just a gem that needs to install a native (e.g. C-Library) library in order to work. A lot of gems simply wrap existing C-libraries with a Ruby API.
The installation of the gem will trigger the download of C-libraries, which will then be built using gcc or another compiler. If your system configuration is not supported, you'll need to pass parameters to gem tool to indicate the right directories, etc.. if you're unlucky you might need to change the make files directly.

Related

Create Ruby/Rake executable

Is there any way to create executable binaries from Ruby/Rake task?
I have simple FileUtil tool written in ruby and I'd like to package it somehow into script that can be run or OSX, Linux or Windows. Is there any way to do that?
Ruby is an interpreted language and not a compiled one like C or Java. Then answering your question is not so easy.
But there are some tools that permit you to protect your source code (encrypting) and creating some packages that are runnable cross platform (but in this case you should ever resolve any dependency).
This question covers pretty good how you can distribuite your code without (or encrypting) your source code: Can you Distribute a Ruby on Rails Application without Source?
Other useful tools that I have founded in these moments:
- Compiling a rake https://github.com/luislavena/rake-compiler
- Debian (.deb) packaging http://crohr.me/pkgr/

TCPServer Class NameError in RubyMotion (OSX)

I have some code I am porting over to RubyMotion from MacRuby and I'm getting a TCPServer Name error: Here is the error message:
app_delegate.rb:29:in `control_server:': uninitialized constant AppDelegate::TCPServer (NameError)
This is the line of code that causes the problem:
dts = TCPServer.new(ip, port)
I have read that some classes from Ruby aren't included in RubyMotion but I'm not sure which classes and how to determine which classes aren't available.
Thanks
RubyMotion doesn't include the entire Ruby standard library because RubyMotion doesn't come with a built-in way to deal with certain parts of the Ruby language that are required by lots of the standard library and community gems - such as require, eval, load and so on.
Traditionally, we've dealt with this by using Objective-C libraries instead, since RubyMotion bridges Objective-C classes seamlessly. There's a wealth of existing Objective-C libraries out there and a fabulous dependency management system in CocoaPods. If you're down for a little rewriting, the CocoaAsyncSocket library should suit your needs.
If you're feeling a little more adventurous, you could try getting your existing code working by using MotionBundler. It attempts to add require support to RubyMotion, with varying levels of success. In theory, you'd simply put back that require 'socket' line in your code after you've set up MotionBundler and it should take care of the rest. I got some pretty scary-looking stack traces when I tried it myself though, so it's probably not a silver bullet. TCPServer is particularly worrying since I'm fairly sure it uses native C extensions, which are not supported by MotionBundler.

How can I build a Ruby interpreter with only needed libraries?

How can I build a Ruby interpreter with only Core API (exclude Process class) and without standard library?
It should not include irb or anything else. A pure interpreter with necessary components.
i have no idea how you can build it, but matz (the creator of ruby) published a project that provides a minimal version of ruby called mruby: https://github.com/mruby/mruby/

Ruby wrapper over a existing C library

I want write a ruby wrapper for a existing C library (.so files). Can anyone point me to books/websites that can get me started with this.
You have several options:
swig / hand written C
extension but those won't be
usable in other VM than MRI (won't
work in jruby, rubinius...)
FFI which will be usable on
other VM. example here
Take a look at FFI gem.

How do I make use of gtk with cmake under windows platform?

This is the FindGTK.cmake:
# don't even bother under WIN32
IF(UNIX)
...
ENDIF(UNIX)
So it's not intended to work in windows at all,even though I've already installed the gtk+-bundle_2.20.0-20100406_win32 days ago.
How should I properly use gtk with cmake now?
Given that you are using GTK 2.20.0 (i.e. version is >= 2), you should be using GTK2 instead of GTK. But, if FindGTK2 has the same problem, then you can use find_path to locate the header files, and you can use find_library to locate the associated library files. Putting those together, you can construct the symbols GTK2_FOUND, GTK2_LIBRARIES, and GTK2_INCLUDE_DIRS that it should produce. You may find my FindUnitTestPlusPlus.cmake file a little bit helpful; it makes use of "FindPackageHandleStandardArgs", which takes care of the nitty gritty details of making sure to fail if the library isn't there and the REQUIRED flag is given. Unfortunately, there really isn't much documentation out there on creating custom FindXYZ.cmake modules; however, you should be able to hack something together from the existing modules, I think.
Another option is to contact the maintainer of that particular module. A list of CMake find module maintainers may be found at the link. Philip Lowman is the go-to guy for the FindGTK2 module.

Resources