Bugs item #29075, was opened at 2011-03-11 13:36
You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=575&aid=29075&group_id=126

Category: `gem install` command (extensions)
Group: next
Status: Open
Resolution: None
Priority: 3
Submitted By: Torsten Curdt (tcurdt)
Assigned to: Nobody (None)
Summary: need for a post_install hook

Initial Comment:
While there is Gem.post_install this cannot be used for gems that want to run 
some code on installation.

In my particular case I need to compile some C++ code -a command line tool- 
that the gem depends on. It does not come with an extension though. Since there 
is no post_install hook exposed to the gem lifecycle people use the extconf for 
things like this. Since that one makes the assumption of building an extension, 
leaving out the create_makefile() results in

 Building native extensions.  This could take a while...
 ERROR:  Error installing ...
        ERROR: Failed to build gem native extension.

 No builder for extension 'path/to/extconf.rb'

Which result in people doing things like this 
http://blog.costan.us/2008/11/post-install-post-update-scripts-for.html

The best solution would certainly be to have some gem lifecyle hooks. But just 
making less assumption on the extension building would already be a first step.


----------------------------------------------------------------------

Comment By: Jon Forums (jonforums)
Date: 2011-03-12 15:18

Message:
That snippet from our install script results in a 
rubygems/defaults/operating_system.rb file being generated similar to the 
following:

# :DK-BEG: override 'gem install' to enable RubyInstaller DevKit usage
Gem.pre_install do |gem_installer|
  unless gem_installer.spec.extensions.empty?
    unless ENV['PATH'].include?('C:\DevKit\mingw\bin') then
      Gem.ui.say 'Temporarily enhancing PATH to include DevKit...' if 
Gem.configuration.verbose
      ENV['PATH'] = 'C:\DevKit\bin;C:\DevKit\mingw\bin;' + ENV['PATH']
    end
    ENV['RI_DEVKIT'] = 'C:\DevKit'
    ENV['CC'] = 'gcc'
    ENV['CPP'] = 'cpp'
    ENV['CXX'] = 'g++'
  end
end
# :DK-END

While my usage is fairly simple and the only mildly clever parts are (a) 
checking whether a native extension is being installed, and (b) wrapping the 
code snippet in markers so I can manage non-clobbering/upgrades of existing 
operating_system.rb files, I'm still betting that you could use `system` to 
call out to your toolchain and build your C++ tool in a similar way.

It's the combination of the filename/location in combination with the block to 
Gem.pre_install which sets the pre-install hook that RG calls at the 
appropriate time during an install.  These two places in the source should help:

https://github.com/rubygems/rubygems/blob/master/lib/rubygems.rb#L65-82

https://github.com/rubygems/rubygems/blob/master/lib/rubygems/installer.rb#L140


----------------------------------------------------------------------

Comment By: Torsten Curdt (tcurdt)
Date: 2011-03-12 10:55

Message:
@Jon: Still don't quite understand when you are setting that hook. Why would 
that code be called on a 'gem install' ?

----------------------------------------------------------------------

Comment By: Jon Forums (jonforums)
Date: 2011-03-11 16:05

Message:
In the DevKit (MSYS/MinGW toolchain for Windows) subproject of the 
RubyInstaller we have a Ruby install script which dynamically builds a gem 
override script that uses the pre-install hook to setup the environment for 
building native gems on Windows using the DevKit:

https://github.com/oneclick/rubyinstaller/blob/master/resources/devkit/dk.rb.erb#L46-65

Basically, it automagically brings the DevKit toolchain into the environment 
when doing something like `gem install bson_ext`

Thinking out loud, but I wonder if you can do something similar but use 
`system` or `IO.popen` to optimistically compile your gem's C++ dependency 
before the install and abort if you get any errors.  Might also want to 
check/cleanup in post-build.

A wild-eyed idea, but it might work if you can split things into "pre-build 
dependencies" and "build extension" and abort if things go badly. 

----------------------------------------------------------------------

Comment By: Torsten Curdt (tcurdt)
Date: 2011-03-11 15:46

Message:
Maybe I misunderstood but I think Eric said on IRC that the existing 
post_install is 
not for gems. Which is why he asked me to open this issue.

Jon, can you give an example how that would work?

Whether it is pre or post install is not important to me. It's just that one 
might want 
to build more than just extension on install. I got that working by abusing the 
extconf to execute my build and creating an empty Makefile.

But that smells.


----------------------------------------------------------------------

Comment By: Jon Forums (jonforums)
Date: 2011-03-11 15:13

Message:
Can you split things up to use the pre-install and post-build hooks which as of 
1.5.0 that can cancel gem installation...optimistically compile in the 
pre-install and abort if needed in either pre-install or post-build?

http://blog.segment7.net/2011/01/31/rubygems-1-5

----------------------------------------------------------------------

Comment By: Torsten Curdt (tcurdt)
Date: 2011-03-11 13:54

Message:
Then you also cannot allow native builds. Where is the difference?

----------------------------------------------------------------------

Comment By: Luis Lavena (luislavena)
Date: 2011-03-11 13:44

Message:
I would say no to this.

Most of the users do not check what the gem do inside, so there is a huge 
potential of security risks on this.



----------------------------------------------------------------------

You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=575&aid=29075&group_id=126
_______________________________________________
Rubygems-developers mailing list
http://rubyforge.org/projects/rubygems
Rubygems-developers@rubyforge.org
http://rubyforge.org/mailman/listinfo/rubygems-developers

Reply via email to