{"id":16871879,"url":"https://github.com/luislavena/gem-compiler","last_synced_at":"2025-04-05T12:05:06.163Z","repository":{"id":3209051,"uuid":"4243142","full_name":"luislavena/gem-compiler","owner":"luislavena","description":"A RubyGems plugin that generates binary gems","archived":false,"fork":false,"pushed_at":"2021-04-15T20:42:57.000Z","size":162,"stargazers_count":154,"open_issues_count":3,"forks_count":28,"subscribers_count":9,"default_branch":"master","last_synced_at":"2024-05-02T05:32:06.782Z","etag":null,"topics":["compiler-toolchain","ruby","rubygems","rubygems-plugin"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"zs-zs/grunt-selenium-standalone","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/luislavena.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-05-06T18:30:28.000Z","updated_at":"2024-02-26T21:13:34.000Z","dependencies_parsed_at":"2022-08-19T01:31:31.156Z","dependency_job_id":null,"html_url":"https://github.com/luislavena/gem-compiler","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luislavena%2Fgem-compiler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luislavena%2Fgem-compiler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luislavena%2Fgem-compiler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luislavena%2Fgem-compiler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/luislavena","download_url":"https://codeload.github.com/luislavena/gem-compiler/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247332602,"owners_count":20921853,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compiler-toolchain","ruby","rubygems","rubygems-plugin"],"created_at":"2024-10-13T15:10:04.089Z","updated_at":"2025-04-05T12:05:06.111Z","avatar_url":"https://github.com/luislavena.png","language":"Ruby","readme":"# gem-compiler\n\nA RubyGems plugin that generates binary (pre-compiled) gems.\n\n[![Gem Version](https://img.shields.io/gem/v/gem-compiler.svg)](https://rubygems.org/gems/gem-compiler)\n[![Maintainability](https://api.codeclimate.com/v1/badges/340423e051aa44275ca4/maintainability)](https://codeclimate.com/github/luislavena/gem-compiler/maintainability)\n\n- [home](https://github.com/luislavena/gem-compiler)\n- [bugs](https://github.com/luislavena/gem-compiler/issues)\n\n## Description\n\n`gem-compiler` is a RubyGems plugin that helps generates binary gems from\nalready existing ones without altering the original source code. It compiles\nRuby C extensions and bundles the result into a new gem.\n\nIt uses an *outside-in* approach and leverages on existing RubyGems code to\ndo it.\n\n## Benefits\n\nUsing `gem-compiler` removes the need to install a compiler toolchain on the\nplatform used to run the extension. This means less dependencies are required\nin those systems and can reduce associated update/maintenance cycles.\n\nAdditionally, by having only binaries, it reduces the time it takes to install\nseveral gems that normally take minutes to compile themselves and the needed\ndependencies.\n\nWithout `gem-compiler`, takes more than a minute to install Nokogiri on\nUbuntu 18.04:\n\n```console\n$ time gem install --local nokogiri-1.10.7.gem\nBuilding native extensions. This could take a while...\nSuccessfully installed nokogiri-1.10.7\n1 gem installed\n\nreal    1m22.670s\nuser    1m5.856s\nsys     0m18.637s\n```\n\nCompared to the installation of the pre-compiled version:\n\n```console\n$ gem compile nokogiri-1.10.7.gem --prune\nUnpacking gem: 'nokogiri-1.10.7' in temporary directory...\nBuilding native extensions. This could take a while...\n  Successfully built RubyGem\n  Name: nokogiri\n  Version: 1.10.7\n  File: nokogiri-1.10.7-x86_64-linux.gem\n\n$ time gem install --local nokogiri-1.10.7-x86_64-linux.gem\nSuccessfully installed nokogiri-1.10.7-x86_64-linux\n1 gem installed\n\nreal    0m1.697s\nuser    0m1.281s\nsys     0m0.509s\n```\n\n## Installation\n\nTo install gem-compiler you need to use RubyGems:\n\n    $ gem install gem-compiler\n\nWhich will fetch and install the plugin. After that the `compile` command\nwill be available through `gem`.\n\n## Usage\n\nAs requirement, gem-compiler can only compile local gems, either one you have\ngenerated from your projects or previously downloaded.\n\n### Fetching a gem\n\nIf you don't have the gem locally, you can use `fetch` to retrieve it first:\n\n    $ gem fetch yajl-ruby --platform=ruby\n    Fetching: yajl-ruby-1.1.0.gem (100%)\n    Downloaded yajl-ruby-1.1.0\n\nPlease note that I was explicit about which platform to fetch. This will\navoid RubyGems attempt to download any existing binary gem for my current\nplatform.\n\n### Compiling a gem\n\nYou need to tell RubyGems the filename of the gem you want to compile:\n\n    $ gem compile yajl-ruby-1.1.0.gem\n\nThe above command will unpack, compile any existing extensions found and\nrepackage everything as a binary gem:\n\n    Unpacking gem: 'yajl-ruby-1.1.0' in temporary directory...\n    Building native extensions.  This could take a while...\n      Successfully built RubyGem\n      Name: yajl-ruby\n      Version: 1.1.0\n      File: yajl-ruby-1.1.0-x86-mingw32.gem\n\nThis new gem do not require a compiler, as shown when locally installed:\n\n    C:\\\u003e gem install --local yajl-ruby-1.1.0-x86-mingw32.gem\n    Successfully installed yajl-ruby-1.1.0-x86-mingw32\n    1 gem installed\n\nThere are native gems that will invalidate their own specification after\ncompile process completes. This will not permit them be repackaged as binary\ngems. To workaround this problem you have the option to *prune* the package\nprocess:\n\n    $ gem fetch nokogiri --platform=ruby\n    Fetching: nokogiri-1.6.6.2.gem (100%)\n    Downloaded nokogiri-1.6.6.2\n\n    $ gem compile nokogiri-1.6.6.2.gem --prune\n    Unpacking gem: 'nokogiri-1.6.6.2' in temporary directory...\n    Building native extensions.  This could take a while...\n      Successfully built RubyGem\n      Name: nokogiri\n      Version: 1.6.6.2\n      File: nokogiri-1.6.6.2-x86_64-darwin-12.gem\n\n    $ gem install --local nokogiri-1.6.6.2-x86_64-darwin-12.gem\n    Successfully installed nokogiri-1.6.6.2-x86_64-darwin-12\n    1 gem installed\n\n#### Restricting generated binary gems\n\nGems compiled with `gem-compiler` be lock to the version of Ruby used\nto compile them, following Ruby's ABI compatibility (`MAJOR.MINOR`)\n\nThis means that a gem compiled with Ruby 2.6.1 could be installed in any\nversion of Ruby 2.6.x (Eg. 2.6.4).\n\nYou can tweak this behavior by using `--abi-lock` option during compilation.\nThere are 3 available modes:\n\n* `ruby`: Follows Ruby's ABI. Gems compiled with Ruby 2.6.1 can be installed\n  in any Ruby 2.6.x (default behavior).\n* `strict`: Uses Ruby's full version. Gems compiled with Ruby 2.6.1 can only\n  be installed in Ruby 2.6.1.\n* `none`: Disables Ruby compatibility. Gems compiled with this option can be\n  installed on any version of Ruby (alias for `--no-abi-lock`).\n\n**Warning**: usage of `none` is not recommended since different versions of\nRuby might expose different APIs. The binary might be expecting specific\nfeatures not present in the version of Ruby you're installing the gem into.\n\n#### Reducing extension's size (stripping)\n\nBy default, RubyGems do not strip symbols from compiled extensions, including\ndebugging information and can result in increased size of final package.\n\nWith `--strip`, you can reduce extensions by using same stripping options used\nby Ruby itself (see `RbConfig::CONFIG[\"STRIP\"]`):\n\n```console\n$ gem compile oj-3.10.0.gem --strip\nUnpacking gem: 'oj-3.10.0' in temporary directory...\nBuilding native extensions. This could take a while...\nStripping symbols from extensions (using 'strip -S -x')...\n  Successfully built RubyGem\n  Name: oj\n  Version: 3.10.0\n  File: oj-3.10.0-x86_64-linux.gem\n```\n\nOr you can provide your own stripping command instead:\n\n```console\n$ gem compile oj-3.10.0.gem --strip \"strip --strip-unneeded\"\nUnpacking gem: 'oj-3.10.0' in temporary directory...\nBuilding native extensions. This could take a while...\nStripping symbols from extensions (using 'strip --strip-unneeded')...\n  Successfully built RubyGem\n  Name: oj\n  Version: 3.10.0\n  File: oj-3.10.0-x86_64-linux.gem\n```\n\n#### Append build number to gem version\n\nGem servers like RubyGems or Gemstash treat gems as immutable, so once a gem\nhas been pushed, you cannot replace it.\n\nWhen playing with compilation options or library dependencies, you might\nrequire to build and push an updated version of the same version.\n\nYou can use `--build-number` to add the build number to the compiled version\nand push an updated build, maintaining gem dependency compatibility:\n\n```console\n$ gem compile oj-3.11.3.gem --build-number 10\nUnpacking gem: 'oj-3.11.3' in temporary directory...\nBuilding native extensions. This could take a while...\n  Successfully built RubyGem\n  Name: oj\n  Version: 3.11.3.10\n  File: oj-3.11.3.10-x86_64-linux.gem\n```\n\nThis new version remains compatible with RubyGems' dependency requirements\nlike `~\u003e 3.11` or `~\u003e 3.11.3`.\n\n### Compiling from Rake\n\nMost of the times, as gem developer, you would like to generate both kind of\ngems at once. For that purpose, you can add a task for Rake similar to the\none below:\n\n```ruby\ndesc \"Generate a pre-compiled native gem\"\ntask \"gem:native\" =\u003e [\"gem\"] do\n  sh \"gem compile #{gem_file}\"\nend\n```\n\nOf course, that assumes you have a task `gem` that generates the base gem\nrequired.\n\n## Requirements\n\n### Ruby and RubyGems\n\nIt's assumed you have Ruby and RubyGems installed. gem-compiler requires\nRubyGems 2.6.x to work.\n\nIf you don't have RubyGems 2.6.x, you can upgrade by running:\n\n    $ gem update --system\n\n### A compiler\n\nIn order to compile a gem, you need a compiler toolchain installed. Depending\non your Operating System you will have one already installed or will require\nadditional steps to do it. Check your OS documentation about getting the\nright one.\n\n### If you're using Windows\n\nFor those using RubyInstaller-based builds, you will need to download the\nDevKit from their [downloads page](http://rubyinstaller.org/downloads)\nand follow the installation instructions.\n\nTo be sure your installation of Ruby is based on RubyInstaller, execute at\nthe command prompt:\n\n    C:\\\u003e ruby --version\n\nAnd from the output:\n\n    ruby 2.4.9p362 (2019-10-02 revision 67824) [x64-mingw32]\n\nIf you see `mingw32`, that means you're using a RubyInstaller build\n(MinGW based).\n\n## Differences with rake-compiler\n\n[rake-compiler](https://github.com/luislavena/rake-compiler) has provided to\nRuby library authors a *tool* for compiling extensions and generating binary\ngems of their libraries.\n\nYou can consider rake-compiler's approach be an *inside-out* process. To do\nits magic, it requires library authors to modify their source code, adjust\nsome structure and learn a series of commands.\n\nWhile the ideal scenario is using a tool like rake-compiler that endorses\n*convention over configuration*, is not humanly possible change all the\nprojects by snapping your fingers :wink:\n\n## License\n\n[The MIT License](LICENSE)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluislavena%2Fgem-compiler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fluislavena%2Fgem-compiler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluislavena%2Fgem-compiler/lists"}