Skip to content

Problem with native extension compilation when using a git source #41

Description

@schneems

Hello! I've got a bit of a weird issue. When I install this gem on Heroku via rubygems it works fine.

source "https://rubygems.org"
ruby "3.1.3"

gem "seven_zip_ruby", github: "masamitsu-murase/seven_zip_ruby"

However when I install it via a git dependency it compiles the shared object to a location that causes problems.

Reproduction

Put this in the Gemfile:

source "https://rubygems.org"
ruby "3.1.3"

gem "seven_zip_ruby", github: "masamitsu-murase/seven_zip_ruby"

When I install this on Heroku the shared object file ends up in:

$ heroku run bash
~ $  find / -iname "7z.so"
# ...
/app/vendor/ruby-3.1.3/lib/ruby/site_ruby/3.1.0/x86_64-linux/seven_zip_ruby/7z.so

This is a problem because this entire /app/vendor/ruby-3.1.3 directory is replaced on every deploy.

First deploy

So what happens is that on the first deploy Ruby is downloaded to /app/vendor/ruby-3.1.3 and then gems are installed where seven_zip_ruby creates /app/vendor/ruby-3.1.3/lib/ruby/site_ruby/3.1.0/x86_64-linux/seven_zip_ruby/7z.so and the deploy is fine. No problems.

Second deploy

The next deploy, Ruby is downloaded to /app/vendor/ruby-3.1.3 which overw-writes the shared object file. However Bundler sees that the gem is already installed so it won't try to recompile it. The release is successful but then at runtime the library cannot be loaded:

$ heroku run "bundle exec ruby -e 'require %Q{seven_zip_ruby}; puts %Q{worked}'"
/app/vendor/bundle/ruby/3.1.0/gems/seven_zip_ruby-1.3.0/lib/seven_zip_ruby.rb:12:in `find_external_lib_dir': Failed to find 7z.dll or 7z.so (RuntimeError)
        from /tmp/build_2d5b5659/vendor/bundle/ruby/3.1.0/gems/seven_zip_ruby-1.3.0/lib/seven_zip_ruby.rb:17:in `<module:SevenZipRuby>'

Thoughts

I don't know why this only happens when using a git source via bundler and only with this gem. This line is likely the reason that the gem is installed in that location

SO_TARGET_DIR = File.expand_path(File.join(RbConfig::CONFIG["sitearchdir"], "seven_zip_ruby"))
. I do not know what location bundler expects you to place shared objects while compiling. I work at Heroku for the past ~10 years and this is the only gem that I've seen that attempts to install to this location. I don't know where other gems typically install to.

I also don't know why we are getting different locations when using a rubygems source versus git source.

FWIW when I install via gem "seven_zip_ruby" (without git) the shared objects end up in these directories:

/app/vendor/bundle/ruby/3.1.0/extensions/x86_64-linux/3.1.0/seven_zip_ruby-1.3.0/seven_zip_ruby/7z.so
/app/vendor/bundle/ruby/3.1.0/gems/seven_zip_ruby-1.3.0/lib/seven_zip_ruby/7z.so

I think the directory that the gem installs to needs to be updated in extconf.rb but unfortunately I don't know what that directory should be. If anyone in the community knows. I would appreciate a comment.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions