rubinius/rubinius — pull request #2302 by vmg (2013-04-21 15:24:32+00:00)
Title: Always export the RBX version number

Alright, this is not pretty, so excuse me in advance for the mess:

As you probably know, very bad things happen if you're working with 2 different C extensions that re-use small snippets of C code between them (e.g. a hash table implementation, an array implementation, a small library, and so on). As the two C extensions get loaded dynamically into the same memory space, their symbols table collide. If they are not using the same version of the shared code, one of the C extensions will break.

The only way to ensure this is to make sure that no other symbols besides the entry point are exported from the C extension, which is rather tricky to do in practice (it involves manually hiding every single function that is not set to `static` with visibility attributes).

Another way to accomplish this is the "shotgun" approach of hiding every single symbol in the C extension besides the `Init_` entry point by linking with `-Fvisibility=hidden` or with `-Bsymbol`. This works very well in practice for MRI, but Rubinius fails to load C extensions linked like this because it's looking for the `__X_rubinius_version` entry, which is now hidden at link time.

By enforcing a `default` visibility attribute on the Rubinius version, we make sure that it always gets exported and C extensions never fail to load, regardless of how they were linked.