Giter Club home page Giter Club logo

gem-compiler's Issues

Support for latest Rubygems 2.2.x?

Are there any plans for supporting ruby gems 2.2? It doesn't seem to work against that version because of some of the ways temp directories are needed.

mysql2.so is not included in the packed gem

Mysql2 gemspec (https://github.com/brianmario/mysql2/blob/master/mysql2.gemspec) loads gem's files using git ls-files. However it has a .gitignore file (https://github.com/brianmario/mysql2/blob/master/.gitignore) that excludes compiled files, for instance *.so are excluded. In the compile method, after gathering the artifacts, we have to check if the .so files are still in the gemspec definition, if not, they must be reloaded. I am going to provide a patch with this implementation.

gem-compile fails when gem has no Gemfile (SUSE/OpenSUSE)

Hi Luis,

A few years on, I have found a blocking issue. I have found that some gems (with native extensions) do not have a Gemfile, and that this causes gem compilation to fail.

Config:

gem 2.7.6.2
gem-compiler 0.9.0 
ruby 2.5.8p224 (2020-03-31 revision 67882) [x86_64-linux-gnu]
OS SLES15 SP2 docker container.

Examples of failing gems:

libxml-ruby-3.2.1.gem
mysql2-0.5.3.gem
passenger-6.0.8.gem
racc-1.5.2.gem
ruby_deep_clone-0.8.0.gem
websocket-driver-0.7.3.gem

With some hacking I found that Gem::Package.build(gemspec) is what appears to expect the Gemfile, and that creating an empty one with a touch command is sufficient to fix the issue. Strictly speaking I guess this should be fixed in Gem::Package, but as it is gem-compiler that suffers - I'm not sure they'd have the insentive to fix this.

Adding the unindented line in /usr/lib64/ruby/gems/2.5.0/gems/gem-compiler-0.9.0/lib/rubygems/compiler.rb seems to do the trick, though it's probably not the most ruby-like of solutions ...

  def repackage(gemspec)
    # clear out extensions from gemspec
    gemspec.extensions.clear

    # adjust platform
    gemspec.platform = Gem::Platform::CURRENT

    # adjust version of Ruby
    adjust_abi_lock(gemspec)

    # build new gem
    output_gem = nil

    Dir.chdir target_dir do
system("touch #{@target_dir}/Gemfile")
      output_gem = Gem::Package.build(gemspec)
    end

    unless output_gem
      raise CompilerError,
            "There was a problem building the gem."
    end

    # move the built gem to the original output directory
    FileUtils.mv File.join(target_dir, output_gem), @output_dir

    # return the path of the gem
    output_gem
  end

Would you consider a fix?

cheers,
Stefan

For completeness, adding stack-trace:

# gem compile racc-1.5.2.gem 
Unpacking gem: 'racc-1.5.2' in temporary directory...
Building native extensions. This could take a while...
ERROR:  While executing gem ... (Errno::ENOENT)
    No such file or directory @ rb_file_s_stat - Gemfile
	/usr/lib64/ruby/2.5.0/rubygems/package.rb:117:in `stat'
	/usr/lib64/ruby/2.5.0/rubygems/package.rb:117:in `build'
	/usr/lib64/ruby/gems/2.5.0/gems/gem-compiler-0.9.0/lib/rubygems/compiler.rb:182:in `block in repackage'
	/usr/lib64/ruby/gems/2.5.0/gems/gem-compiler-0.9.0/lib/rubygems/compiler.rb:180:in `chdir'
	/usr/lib64/ruby/gems/2.5.0/gems/gem-compiler-0.9.0/lib/rubygems/compiler.rb:180:in `repackage'
	/usr/lib64/ruby/gems/2.5.0/gems/gem-compiler-0.9.0/lib/rubygems/compiler.rb:45:in `compile'
	/usr/lib64/ruby/gems/2.5.0/gems/gem-compiler-0.9.0/lib/rubygems/commands/compile_command.rb:78:in `execute'
	/usr/lib64/ruby/2.5.0/rubygems/command.rb:313:in `invoke_with_build_args'
	/usr/lib64/ruby/2.5.0/rubygems/command_manager.rb:173:in `process_args'
	/usr/lib64/ruby/2.5.0/rubygems/command_manager.rb:143:in `run'
	/usr/lib64/ruby/2.5.0/rubygems/gem_runner.rb:59:in `run'
	/usr/bin/gem:21:in `<main>'

Compiler errors when it finds nothing to do?

I tried to set up a loop compiling all the dependencies of the thing I was working on.

  • gem compile addressable-2.5.2.gem
    ERROR: While executing gem ... (Gem::Compiler::CompilerError)
    There are no extensions to build on this gem file.
    Unpacking gem: 'addressable-2.5.2' in temporary directory...

Sanity Checks for compiled gems would be lovely.

I'm playing around with gem-compiler to generate a binary version of therubyracer for x86_64-linux.

I generated the gem on a local virtual machine with a ruby compiled with rvm:

rvm reinstall 1.9.3 -C --enable-shared --enable-load-relative

Trying it out on heroku though generates the following error:

$ bundle exec ruby -rv8 -e 'puts V8::Context.new.eval("1+1")'
<internal:lib/rubygems/custom_require>:29:in `require': libruby.so.1.9: cannot open shared object file: No such file or directory - /app/vendor/bundle/ruby/1.9.1/gems/therubyracer-0.11.0beta3-x86_64-linux/lib/v8/init.so (LoadError)

full trace here: https://gist.github.com/c419ee5184ab3cb97b2e

I'm uncertain how to diagnose exactly what's going on here, but I suspect 'm doing something wrong here with the paths. Is there a way at all for gem-compiler to sanity check this?

Using these compiled gems with bundle

I compiled a gem successfully but now I want to use it with bundle.

In directory A, I have vendor/cache and into vendor cache I put unf_ext-0.0.7.4-x86-mingw32.gem, the compiled gem, but when I try to use it with bundle like so: bundle install --local --path ../vendor --without development, I get this error:

Some gems seem to be missing from your vendor/cache directory.
Could not find unf_ext-0.0.7.4 in any of the sources

So what is the correct way to use these precompiled gems with bundle?

Using gem compiler in a restricted server environment

Hi Luis,

I am aiming to have a production machine running a Ruby on Rails app. However, this production machine is managed with Plesk and allows only very rudimentary access, but was promised to be able to run Ruby on Rails apps.

Indeed it is in principle able to run Ruby on rails for an very simple example, but running any app requiring gems with native extensions (as e.g. nokogiri, which is required already by the rails default app, generated by rails new) already fails.

Part of the log looks like this:

libruby.so.2.4: cannot open shared object file: No such file or directory - /var/www/vhosts/hosting116285.a2f45.netcup.net/test.gcsb.info/vendor/bundle/ruby/2.4.0/gems/msgpack-1.2.6-x86_64-linux/lib/msgpack/msgpack.so (LoadError)
/var/www/vhosts/hosting116285.a2f45.netcup.net/test.gcsb.info/vendor/bundle/ruby/2.4.0/gems/msgpack-1.2.6-x86_64-linux/lib/msgpack.rb:11:in `require'
...
...
...
/var/www/vhosts/hosting116285.a2f45.netcup.net/test.gcsb.info/vendor/bundle/ruby/2.4.0/gems/rack-2.0.6/lib/rack/builder.rb:55:in `initialize'
config.ru:1:in `new'
config.ru:1:in `<main>'
/usr/share/passenger/helper-scripts/rack-preloader.rb:110:in `eval'
/usr/share/passenger/helper-scripts/rack-preloader.rb:110:in `preload_app'
/usr/share/passenger/helper-scripts/rack-preloader.rb:156:in `<module:App>'
/usr/share/passenger/helper-scripts/rack-preloader.rb:30:in `<module:PhusionPassenger>'
/usr/share/passenger/helper-scripts/rack-preloader.rb:29:in `<main>'

I have the options to "restart the app", "install packages" (which executes a bundle install --path vendor/bundle according to documentation), and "add environment variables".

I have very limited SSH access to the machine, but no access to any compilers or libraries.

The support advised me to "precompile my gems", but did not give any specific advice how to do this. I set up a virtual development machine which is somewhat near to the production machine, but definitely not yet the same in terms of all paths and e.g. Linux kernel version. I compiled the gems which supposedly works fine, put the precompiled gems in vendor/cache on the server, and install them via the Plesk interface.

However, the app keeps throwing errors. The pre-compiled gems (msgpack is one of them; originally with native extensions) seem to be linked in a wrong fashion? Maybe it's the linkage to ruby that it broken? I read about another (closed) issue where this linking is referenced?

Do you have an idea on this, or could you provide me with a "this is how we usually do it"-strategy? Do you intended gem-compiler to work for such a scenario, or am I misled? (If so, maybe we can update the Readme together?)

Thanks in advance! -- Robert

Thanks!!!

No issues, just wanted to say thanks for this incredibly useful piece of work. When I was struggling to install prawn on a non-techy colleague's computer because it now relies on a compiled racc, I discovered gem-compiler and it worked for me first time, exactly as set out in the readme. I am very grateful.

Now I've created extra work for you in having to file this non-issue, so sorry about that, but you deserve to know how helpful the software has been.

Packaging gems with non-traditional extensions

Background

Over the years, several gems have decided to bundle certain dependencies within the source code in order to take advantage of certain functionality or simplify the gem development itself.

That is the case of gems like mosq and rabbitmq (and perhaps others) that use ffi as binding instead of MRI C extensions.

In the above examples, these gems uses Rakefile compile mechanism to build native shared libraries (ie. .so, .dll) binaries to be used later with FFI.

Because these shared libraries are not Ruby native extensions, it makes sense not to expose them to require lookup mechanism (ie. place them inside lib directory). The gem itself takes care of loading the extension via FFI and using it correctly.

However, since these shared libraries are not within the lookup directories detected by gem-compiler, those are not included in the package and thus, fail on usage.

While those are really not Ruby extensions, they are required to normal operation of these gems, which is why I believe they should be considered.

Proposal

Introduce an additional option to compile that, when used, allow us indicate the additional directory where it should look for build artifacts.

This option should be off by default, to avoid including build artifacts into the generated package.

When used, it should lookup for files with platform-specific extensions, collect them as artifacts and ensure are packaged in the final gem.

UI

$ gem compile mosq-0.2.3.gem --include-ext-dir=ext

Above will make gem-compiler lookup into ext directory for shared library artifacts.

Technical details

Determine platform-specific extensions for these artifacts similar how FFI does LIBSUFFIX:

  • darwin: dylib
  • linux, bsd, solaris: so
  • mingw, mswin, cygwin, msys: dll
  • Other: so

Use RbConfig::CONFIG['host_os'] as OS condition. Better use Gem::Platform.local instead.

modify the version of the gem

Is it possible to alter the version of the fat gem ?

I would like to use a version like that: 1.0.0.20200525 for the fat gem when the gem is itself 1.0.0.

Why ?

Because if there is a problem with the fat gem after being uploaded in a local gemstash, there is no way to push a new one with the same version and we are dependant of the creation of a new version in the upstream gem.

cannot compile nokogiri

I tried on CentOS 7(ruby 2.0.0p598) and Mac(ruby 2.1.5p273, ruby 2.0.0p481). both failed

# gem fetch nokogiri
Fetching: nokogiri-1.6.6.2.gem (100%)
Downloaded nokogiri-1.6.6.2
# gem compile nokogiri-1.6.6.2.gem -- --use-system-libraries
Unpacking gem: 'nokogiri-1.6.6.2' in temporary directory...
Building native extensions with: '--use-system-libraries'
This could take a while...
WARNING:  See http://guides.rubygems.org/specification-reference/ for help
ERROR:  While executing gem ... (Gem::InvalidSpecificationException)
    ["ports/archives/libxml2-2.9.2.tar.gz", "ports/archives/libxslt-1.1.28.tar.gz"] are not files
# gem compile nokogiri-1.6.6.2.gem
Unpacking gem: 'nokogiri-1.6.6.2' in temporary directory...
Building native extensions.  This could take a while...
WARNING:  See http://guides.rubygems.org/specification-reference/ for help
ERROR:  While executing gem ... (Gem::InvalidSpecificationException)
    ["ports/archives/libxml2-2.9.2.tar.gz", "ports/archives/libxslt-1.1.28.tar.gz", "ports/patches/libxml2/0001-Revert-Missing-initialization-for-the-catalog-module.patch", "ports/patches/libxml2/0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch", "ports/patches/libxslt/0001-Adding-doc-update-related-to-1.1.28.patch", "ports/patches/libxslt/0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch", "ports/patches/libxslt/0003-Initialize-pseudo-random-number-generator-with-curre.patch", "ports/patches/libxslt/0004-EXSLT-function-str-replace-is-broken-as-is.patch", "ports/patches/libxslt/0006-Fix-str-padding-to-work-with-UTF-8-strings.patch", "ports/patches/libxslt/0007-Separate-function-for-predicate-matching-in-patterns.patch", "ports/patches/libxslt/0008-Fix-direct-pattern-matching.patch", "ports/patches/libxslt/0009-Fix-certain-patterns-with-predicates.patch", "ports/patches/libxslt/0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch", "ports/patches/libxslt/0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch", "ports/patches/libxslt/0014-Fix-for-bug-436589.patch", "ports/patches/libxslt/0015-Fix-mkdir-for-mingw.patch", "ports/patches/sort-patches-by-date"] are not files

Specific case: puma with SSL support

As explained here: puma/puma#2277

I try to make a native gem of puma with SSL support and I don't succeed.

gem-compiler does create a puma-4.3.3-x86_64-linux.gem but it doesn't seem to have SSL support as the error log below can show:

gemstash_1  | /home/ruby/vendor/bundle/ruby/2.5.0/gems/puma-4.3.3-x86_64-linux/lib/puma/minissl/context_builder.rb:6:in `check': SSL not available in this build (StandardError)
gemstash_1  | 	from /home/ruby/vendor/bundle/ruby/2.5.0/gems/puma-4.3.3-x86_64-linux/lib/puma/minissl/context_builder.rb:6:in `initialize'
gemstash_1  | 	from /home/ruby/vendor/bundle/ruby/2.5.0/gems/puma-4.3.3-x86_64-linux/lib/puma/binder.rb:158:in `new'
gemstash_1  | 	from /home/ruby/vendor/bundle/ruby/2.5.0/gems/puma-4.3.3-x86_64-linux/lib/puma/binder.rb:158:in `block in parse'
gemstash_1  | 	from /home/ruby/vendor/bundle/ruby/2.5.0/gems/puma-4.3.3-x86_64-linux/lib/puma/binder.rb:90:in `each'
gemstash_1  | 	from /home/ruby/vendor/bundle/ruby/2.5.0/gems/puma-4.3.3-x86_64-linux/lib/puma/binder.rb:90:in `parse'
gemstash_1  | 	from /home/ruby/vendor/bundle/ruby/2.5.0/gems/puma-4.3.3-x86_64-linux/lib/puma/cluster.rb:436:in `run'
gemstash_1  | 	from /home/ruby/vendor/bundle/ruby/2.5.0/gems/puma-4.3.3-x86_64-linux/lib/puma/launcher.rb:172:in `run'
gemstash_1  | 	from /home/ruby/vendor/bundle/ruby/2.5.0/gems/puma-4.3.3-x86_64-linux/lib/puma/cli.rb:80:in `run'
gemstash_1  | 	from /home/ruby/vendor/bundle/ruby/2.5.0/gems/gemstash-2.1.0/lib/gemstash/cli/start.rb:16:in `run'
gemstash_1  | 	from /home/ruby/vendor/bundle/ruby/2.5.0/gems/gemstash-2.1.0/lib/gemstash/cli.rb:79:in `start'
gemstash_1  | 	from /home/ruby/vendor/bundle/ruby/2.5.0/gems/thor-0.20.3/lib/thor/command.rb:27:in `run'
gemstash_1  | 	from /home/ruby/vendor/bundle/ruby/2.5.0/gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'
gemstash_1  | 	from /home/ruby/vendor/bundle/ruby/2.5.0/gems/thor-0.20.3/lib/thor.rb:387:in `dispatch'
gemstash_1  | 	from /home/ruby/vendor/bundle/ruby/2.5.0/gems/thor-0.20.3/lib/thor/base.rb:466:in `start'
gemstash_1  | 	from /home/ruby/vendor/bundle/ruby/2.5.0/gems/gemstash-2.1.0/lib/gemstash/cli.rb:34:in `start'
gemstash_1  | 	from /home/ruby/vendor/bundle/ruby/2.5.0/gems/gemstash-2.1.0/exe/gemstash:6:in `<top (required)>'
gemstash_1  | 	from /home/ruby/vendor/bundle/ruby/2.5.0/bin/gemstash:23:in `load'
gemstash_1  | 	from /home/ruby/vendor/bundle/ruby/2.5.0/bin/gemstash:23:in `<main>'

Benchmarks?

Do you have any benchmark to show how does this improves build time?

Collect information about installed Rubies

In order to compile a gem using a different version of Ruby, I should be able to collect a list of Ruby interpreters that will be used at compilation to select a specific version.

A proposed CLI for this will be an additional RubyGems command named interpreters.

This information will be stored in ~/.gem/interpreters so it can be shared across multiple interpreters.

Add a interpreter

$ gem interpreters --add [/path/to/interpreter/ruby]

Where /path/to/interpreter/ruby is the location of ruby executable that will be analyzed and later on added to the list.

If an interpreter is found at indicated location, a message similar to the one below should be displayed:

Ruby interpreter found.
       path: C:/Ruby193/bin/ruby.exe
    version: 1.9.3
 patchlevel: 194
   platform: x86-mingw32
        abi: 1.9.1

When no path is provided, it will analyze and store current Ruby.

Adding the same interpreter path twice should not result in multiple entries but instead a refresh of existing information.

List interpreters

$ gem interpreters [--list]

Obtain a list of interpreters grouped by platform. Expected output:

*** Ruby interpreters ***

x86-mingw32
  1.9.3-p194
    path: C:/Ruby193/bin/ruby.exe
     abi: 1.9.1

  1.8.7-p358
    path: C:/Ruby187/bin/ruby.exe
     abi: 1.8

x64-mingw32
  2.0.0dev
    path: V:/ruby-dev/bin/ruby.exe
     abi: 2.0.0

The list of interpreters is the default behavior if no suboptions is provided.

Remove interpreter

$ gem interpreters --remove [/path/to/interpreter/ruby]

This removes any recorded interpreter from the list.

If /path/to/interpreter/ruby didn't exist in the list, a note will be displayed to the user:

No record of '/path/to/interpreter/ruby' exists in interpreters list.

When no path is provided, it will remove from the list current Ruby (same behavior than --add)

Compile using a different version of Ruby

In order to produce binary gems for other versions of Ruby, I should be able to indicate the version of Ruby or compatibility version (ABI) desired.

Using a specific Ruby version

$ gem compile GEMFILE --ruby=1.9.3[-p194]

You can specify the version (X.Y.Z) of a Ruby interpreter that is already identified (using interpreters command)

If patchlevel (-pN) is omitted, the latest patchlevel for the specified version will be used.

This option will always use the same platform as the Ruby used to invoke the compilation process.

When used, Ruby version, patchlevel, platform and ABI will be displayed during compilation:

Unpacking gem: 'yajl-ruby-1.1.0' in temporary directory...
Using Ruby 1.9.3-p194 (1.9.1) (x86-mingw32)...
Building native extensions.  This could take a while...
  Successfully built RubyGem
...

A version is required for --ruby option to work.

Using a compatiblity version (ABI)

$ gem compile GEMFILE --abi=1.9.1

Instead of using a specific version, gem-compiler can accept the ABI (Application Binary Interface) and select the latest Ruby version that matches the requested one.

At this time two known ABIs exists: 1.9.1 (for Ruby 1.9.1 to 1.9.3) and 1.8(for Ruby 1.8.5 to 1.8.7).

When used, the information of the used Ruby version will be displayed during compilation:

Unpacking gem: 'yajl-ruby-1.1.0' in temporary directory...
Using Ruby 1.8.7-p358 (1.8) (x86-mingw32)...
Building native extensions.  This could take a while...
...

A version is required for --abi option to work.

Considerations about compiling to different versions

To be able to compile to a different version of Ruby, gem-compiler need to invoke the different Ruby interpreter while inside your current one.

Under some circumstances this process could fail, mostly caused by tools that manage or allow user switching of interpreters (RVM and rbenv).

Please be aware of this before reporting any issue.

Compile targeting a different platform of Ruby (cross-compilation)

In order to produce binaries for another platform, I should be able to indicate the platform so cross-compilation could happen.

Add cross-compiled Ruby to the list of interpreters

Using interpreters command, user should be able to add Ruby interpreters for platforms other than the current one.

Compile to a different platform

$ gem compile GEMFILE --platform=x86-mingw32

Specify the platform (which is mentioned in the list of interpreters) to target the compilation.

If no --ruby or --abi is provided, it will assume the current Ruby version but targeting the specified platform.

If such version is not found, it should trigger an error.

Compile to different platform and version

$ gem compile GEMFILE --ruby=1.8.7 --platform=x86-mingw32

Combining both --platfrom and --ruby (or --abi) provides the maximum flexibility when current Ruby version is not the same you are targeting.

When used, the Ruby version, patchlevel, platform and ABI will be displayed:

Unpacking gem: 'yajl-ruby-1.1.0' in temporary directory...
Using Ruby 1.8.7-p358 (1.8) (x86-mingw32, non-native)...
Building native extensions.  This could take a while...

An additional non-native legend is displayed, indicating that using is actually attempting to mimic the target configuration.

Notes about cross-compilation

Under some circumstances, certain versions of Ruby cannot be cross-compiled when the current Ruby is greater than the target.

For example, it fails to cross-compile to Ruby 1.8.7 when current Ruby version is 1.9.3. However, cross-compile to 1.9.3 from 1.8.7 is possible.

This is a Ruby limitation that you need to keep in mind when using this functionality.

Use only in gemfile?

Somewhat similar to #8 but here is my case:

I have a unique process that will collect all needed gems and distribute them as a single application to windows. I do this on OS X.

So I have successfully created unf_ext-0.0.7.4-x86-mingw32.gem on windows, moved that to my project, and added this to the Gemfile

gem 'unf_ext', :path => './'

but when I try to work my rake tasks on OS X, I get

rake package                                                                                                                                               โŽ
Could not find gem 'unf_ext' in source at `./`.
Source does not contain any versions of 'unf_ext'
Run `bundle install` to install missing gems.

Which I guess is because the binary formats are different, but there must be a way to get around this because it shouldn't matter, we're just moving it around, not running it.

Method to execute commands/scripts before packaging the new gem

We need to provide pre-compiled gems without internet access. We download from rubygems.org, compile using gem compiler, and push the compiled gems to our local geminabox server. From here the gems are downloaded onto target machines that do not have compilers.

My problem is the passenger gem. This requires unpacking, then running a cmd which builds mod_passeneger.so. I want to include this file in the compiled gem.

gem compiler unpacks in a tmp area in a dir containing a time stamp - so I cannot unpack, compile & run gem compiler on the same dir hoping it will include mod_passenger.so.

Ideally I need a hook to be able to insert a file into the unpacked area before it is repackaged.

I can use gem unpack - but can I& place a file in the unpacked area and perhaps gem-compile the unpacked gem dir?

Or can I unpack & re-pack the gem-compiled gem file??

Package not found

Hi,

I've tried to make some binaries for my Synology lately and i got atomic and json to compile.
Installation seems to work also:

/usr/local/ruby/bin/gem install json-1.8.1-x86-linux.gem 
Successfully installed json-1.8.1-x86-linux
Parsing documentation for json-1.8.1-x86-linux
unable to convert "\x80" from ASCII-8BIT to UTF-8 for lib/json/ext/generator.so, skipping
unable to convert "\xB4" from ASCII-8BIT to UTF-8 for lib/json/ext/parser.so, skipping
1 gem installed

but when i try to start the app with rake i still get the following output:

/usr/local/ruby/bin/rake db:create
Could not find json-1.8.1 in any of the sources
Run `bundle install` to install missing gems.

gem list --local lists them correctly:

atomic (1.1.16 x86-linux, 1.1.14 x86-linux)
json (1.8.1 x86-linux, 1.7.7)

also i dont know why there is a x86-linux suffix and if maybe thats the problem?

running bundle install isn't really an option here because i don't have any compiler on the target system so that will fail too.

Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.
An error occurred while installing json (1.8.1), and Bundler cannot continue.
Make sure that `gem install json -v '1.8.1'` succeeds before bundling.

Fail when artifacts are empty?

Hi! I just had an issue with http-parser. It built correctly but the library was missing because the rake task wasn't copying it into lib/, the gem requires it directly from ext/.

So I had to add --include-shared-dir ext/ to the build, but I think it could be better if gem compiler fails if there aren't artifacts to add to the binary gem.

I can send a PR :)

Uploading multiple versions of ABI to rubygems

Hi Luis,

My question probably not related to gem-compiler in particular. What if I've built two versions of binary gem for the same platform (say x86_64-linux). One with ABI 2.7 and another with 2.6. When I upload one of them to rubygems, it does not allow me to upload another complaining about republishing.

But when I later try to install without --platform=ruby it by default download binary version regardless the ABI I'm using right now.

So the actual question is, how to resolve this problem? Is it even possible to have separate packages on rubygems that compiled against different ABI? I can see it in gem's metadata, then why it does not use this information during install and does not allow to upload multiple versions of binaries.

Support for ruby 3.0

Hi @luislavena I tried installing gem-compiler (0.9.0) on ruby30 but it isn't working even after successful installation. I see a changes merged for support to ruby30 but i don't see latest version published. Can i please know if this change can be published anytime sooner as i was in need of this gem for my project. It works great with ruby27 or ruby26. So need it for ruby30 as well

[root@test-serverXXXX ~]# gem install gem-compiler
Successfully installed gem-compiler-0.9.0
Parsing documentation for gem-compiler-0.9.0
Done installing documentation for gem-compiler after 0 seconds
1 gem installed
[root@test-serverXXXX ~]#  gem list | grep gem-compiler
gem-compiler (0.9.0)
[root@test-serverXXXX ~]# gem help command
GEM commands are:

    build             Build a gem from a gemspec
    cert              Manage RubyGems certificates and signing settings
    check             Check a gem repository for added or missing files
    cleanup           Clean up old versions of installed gems
    contents          Display the contents of the installed gems
    dependency        Show the dependencies of an installed gem
    environment       Display information about the RubyGems environment
    fetch             Download a gem and place it in the current directory
    generate_index    Generates the index files for a gem server directory
    help              Provide help on the 'gem' command
    info              Show information for the given gem
    install           Install a gem into the local repository
    list              Display local gems whose name matches REGEXP
    lock              Generate a lockdown list of gems
    mirror            Mirror all gem files (requires rubygems-mirror)
    open              Open gem sources in editor
    outdated          Display all gems that need updates
    owner             Manage gem owners of a gem on the push server
    pristine          Restores installed gems to pristine condition from files
                      located in the gem cache
    push              Push a gem up to the gem server
    rdoc              Generates RDoc for pre-installed gems
    search            Display remote gems whose name matches REGEXP
    signin            Sign in to any gemcutter-compatible host. It defaults to
                      https://rubygems.org
    signout           Sign out from all the current sessions.
    sources           Manage the sources and cache file RubyGems uses to search
                      for gems
    specification     Display gem specification (in yaml)
    stale             List gems along with access times
    uninstall         Uninstall gems from the local repository
    unpack            Unpack an installed gem to the current directory
    update            Update installed gems to the latest version
    which             Find the location of a library file you can require
    yank              Remove a pushed gem from the index

For help on a particular command, use 'gem help COMMAND'.

load relative libruby.so

Path to libruby.so is hardcoded in the compiled gem:

$ ldd /home/mpapis/.rvm/gems/ruby-1.9.3-p125/gems/nokogiri-1.5.2-x86_64-linux/lib/nokogiri/nokogiri.so
...
libruby.so.1.9 => /home/mpapis/.rvm/rubies/ruby-1.9.3-p194/lib64/libruby.so.1.9 (0x00007f7c5968a000)
...

gem was compiled in 1.9.3-p194 and installed in 1.9.3-p125.

ruby has a switch --enable-load-relative which in my understanding should be equivalent to (Linux):

LDFLAGS="-Wl,-rpath,../lib,-rpath,../lib64,-rpath,../libexec"

I have added the lib64 / libexec as at least lib64 might be happening on some systems (like mine), I'm not sure if the ../ is proper way to make it working.

Not sure what effects --enable-load-relative has on OSX and if there is anything needed for Windows.

gem compile test-4.0.6.gem

gem compile test-4.0.6.gem
Unpacking gem: 'test-4.0.6' in temporary directory...
ERROR: While executing gem ... (Gem::Compiler::CompilerError)
There are no extensions to build on this gem file.

Please help me...

Lock down Ruby's ABI when packaging new gem

The compiled extensions are bind to the specific version of Ruby used.

At this time, required_ruby_version in the gem specification is not updated, which should be to avoid installation of incorrect binaries on different versions.

Perhaps we should use RbConfig::CONFIG["ruby_version"] as ABI indicator:

$ ruby -rrbconfig -ve 'p RbConfig::CONFIG["ruby_version"]'
ruby 1.8.7 (2013-06-27 patchlevel 374) [i686-darwin14.0.0]
"1.8"

$ ruby -rrbconfig -ve 'p RbConfig::CONFIG["ruby_version"]'
ruby 1.9.3p551 (2014-11-13) [x86_64-darwin14.0.0]
"1.9.1"

$ ruby -rrbconfig -ve 'p RbConfig::CONFIG["ruby_version"]'
ruby 2.0.0p598 (2014-11-13) [x86_64-darwin14.0.0]
"2.0.0"

$ ruby -rrbconfig -ve 'p RbConfig::CONFIG["ruby_version"]'
ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-darwin14.0]
"2.1.0"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.