This patch to devel/ruby-gems for ruby 1.8 and to lang/ruby/1.9 for ruby 1.9 allows installation of C extension gems as a user in more cases. The current patch just handles the case where --user-install is used (which the ports system uses to build packages). However, other libraries that use the rubygems API to install packages as the user (e.g. bundler) may still have problems, as experienced by jcs@.
Basically, ruby wants to use "install -o root -g bin" to install files, even when the install is run as non-root. We need to strip that "-o root -g bin" out if install is done as non-root. Instead of checking for a flag set by "gem install --user-install", just check whether the current user is root, and remove "-o root -g bin" otherwise. I've run this through a bulk of the ruby ports without problems. I've tested that this fixes a problem using bundler to install gems as a user. Tested on amd64. I plan to commit the lang/ruby/1.9 diff in a few days along the ruby 1.9.3-p286 update, and the devel/ruby-gems diff shortly thereafter. Thanks, Jeremy Index: lang/ruby/1.9/patches/patch-lib_rubygems_ext_builder_rb =================================================================== RCS file: /cvs/ports/lang/ruby/1.9/patches/patch-lib_rubygems_ext_builder_rb,v retrieving revision 1.1 diff -u -p -r1.1 patch-lib_rubygems_ext_builder_rb --- lang/ruby/1.9/patches/patch-lib_rubygems_ext_builder_rb 6 Oct 2010 18:43:11 -0000 1.1 +++ lang/ruby/1.9/patches/patch-lib_rubygems_ext_builder_rb 19 Oct 2012 21:35:37 -0000 @@ -14,7 +14,7 @@ according to a grep of the sources. mf = File.read('Makefile') mf = mf.gsub(/^RUBYARCHDIR\s*=\s*\$[^$]*/, "RUBYARCHDIR = #{dest_path}") mf = mf.gsub(/^RUBYLIBDIR\s*=\s*\$[^$]*/, "RUBYLIBDIR = #{dest_path}") -+ mf = mf.gsub(/-o root -g bin/, "") if Gem::Installer.path_warning ++ mf = mf.gsub(/-o root -g bin/, "") unless Process.euid == 0 File.open('Makefile', 'wb') {|f| f.print mf} Index: devel/ruby-gems/Makefile =================================================================== RCS file: /cvs/ports/devel/ruby-gems/Makefile,v retrieving revision 1.26 diff -u -p -r1.26 Makefile --- devel/ruby-gems/Makefile 27 Apr 2012 18:41:07 -0000 1.26 +++ devel/ruby-gems/Makefile 22 Oct 2012 18:13:03 -0000 @@ -5,6 +5,7 @@ COMMENT= package management framework fo V= 1.8.23 DISTNAME= rubygems-$V PKGNAME= ruby-gems-$V +REVISION= 0 CATEGORIES= devel HOMEPAGE= http://docs.rubygems.org/ Index: devel/ruby-gems/patches/patch-lib_rubygems_ext_builder_rb =================================================================== RCS file: /cvs/ports/devel/ruby-gems/patches/patch-lib_rubygems_ext_builder_rb,v retrieving revision 1.1 diff -u -p -r1.1 patch-lib_rubygems_ext_builder_rb --- devel/ruby-gems/patches/patch-lib_rubygems_ext_builder_rb 6 Oct 2010 18:12:19 -0000 1.1 +++ devel/ruby-gems/patches/patch-lib_rubygems_ext_builder_rb 19 Oct 2012 21:39:23 -0000 @@ -5,16 +5,13 @@ a user uses gem install --user-install, /usr/bin/install -o root -g bin, which fails due to permission issues. This removes the -o root -g bin, so it can succeed as a regular user. -Gem::Installer.path_warning is only set if --user-install is used, -according to a grep of the sources. - --- lib/rubygems/ext/builder.rb.orig Wed Oct 6 10:27:31 2010 +++ lib/rubygems/ext/builder.rb Wed Oct 6 10:28:16 2010 @@ -19,6 +19,7 @@ class Gem::Ext::Builder mf = File.read('Makefile') mf = mf.gsub(/^RUBYARCHDIR\s*=\s*\$[^$]*/, "RUBYARCHDIR = #{dest_path}") mf = mf.gsub(/^RUBYLIBDIR\s*=\s*\$[^$]*/, "RUBYLIBDIR = #{dest_path}") -+ mf = mf.gsub(/-o root -g bin/, "") if Gem::Installer.path_warning ++ mf = mf.gsub(/-o root -g bin/, "") unless Process.euid == 0 File.open('Makefile', 'wb') {|f| f.print mf}