Archive:PackagingDrafts/RubyGem with C code

= Proposal for package Ruby Gem including extension library written in C =

Current status
Current packaging guidelines on Fedora about Ruby Gems are mainly written on https://fedoraproject.org/wiki/Packaging/Ruby#Ruby_Gems

The guideline says: The install should be performed with the command $ gem install --local --install-dir %{buildroot}%{gemdir} --force %{SOURCE0}

Problem
This causes some problems especially when Ruby Gem contains extension libraries written in C because of the following reason.

A-1
First of all the above procedure will cause the error like following. + /usr/lib/rpm/check-buildroot Binary file /home/tasaka1/rpmbuild/INSTROOT/rubygem-zoom-0.4.1-4.fc9p-root-tasaka1/usr/lib/debug/usr/lib/ruby/site_ruby/1.8/i386-linux/zoom.so.debug matches Found '/home/tasaka1/rpmbuild/INSTROOT/rubygem-zoom-0.4.1-4.fc9p-root-tasaka1' in installed files; aborting error: Bad exit status from /home/tasaka1/rpmbuild/INSTROOT/rpm-tmp.84251 (%install) This is because with above command: So the rebuilt C library may contain  string.
 * first unpacks files in the gem file under
 * Then  (actually  ) compiles C source files installed under there.

A-2
So to avoid this error some maintainers on Fedora of rubygems including extension written in C simply  compiled C libraries before   stage ends.
 * Of course this won't create debuginfo file correctly.
 * Also, when Gem is directly installed under  and   is blank,   won't be called anyway because   is not defined (this is because   can't be written when   is missing).

Solution to A
The problem written in A can be resolved when Ruby Gems are installed under  first.

B
Currently there is no mention about how to pass Fedora specific compilation flags correctly.

Solution to B
Usually ruby extension uses ruby script file named  which has. module accepts environment to specify  so using this is preferred. which usually contain. In such case export CONFIGURE_ARGS="--with-cflags='%{optflags}'" can be used, too. So using this method is preferred even for non-Gem packages.
 * even for non-Gem Ruby packages, many packages containing C shared libraries
 * have  in the source archives
 * or have  which create
 * A package which uses  directly can take   argument directly, like , however in the case that   creates  , usually   does not accept   argument.

Proposition

 * Add the following sentences at the end of Ruby packages with binary content/shared libraries

For packages which create C shared libraries using export CONFIGURE_ARGS="--with-cflags='%{optflags}'" should be used to pass  to   correctly. This also applies to Ruby Gems.


 * And add below.

Ruby Gem with extension libraries written in C

When Ruby Gem contains extension libraries written in C,
 * First  must be created at   stage.
 * Then the Ruby Gem must be installed under  at   stage to get C libraries compiled under the directory.
 * When using  command to install Gem file, using   option is recommend to check if   is correctly honored.
 * Finally at  stage the whole tree under   should be copied (not moved) to under.
 * When all tree under  is moved to under ,   will complain that the corresponding source files are missing.
 * Installed C codes (usually under %{geminstdir}/etc) may be removed even if  reports that installed C codes should be found there.

Revised proposition
From the comments I received, it seems that the following proposition is clearer.

(The part  stays unchanged)

Ruby Gem with extension libraries written in C

When Ruby Gem contains extension libraries written in C,
 * First,  stage must contain   to create the directory where C libraries are compiled.
 * Then at %build stage the Ruby Gem must be installed under the directory created at %prep stage to get C libraries compiled under there.
 * When  is used to install Gem file, using   option is recommend to check if   is correctly honored.
 * Finally at  stage the whole tree under the directory created at %prep stage should be copied (not moved) to under.
 * When all tree under the directory created at %prep stage is moved to under,   will complain that the corresponding source files are missing.
 * Installed C codes (usually under ) may be removed even if   reports that installed C codes should be found there.

Note
The current guideline If the Gem contains binary content (e.g., for a database driver), it must be marked as architecture specific, and all architecture specific content must be moved from the %{gemdir} to the [#ruby_sitearch %{ruby_sitearch} directory] during %install must still apply.

Example
%prep %setup -q -T -c

%build mkdir -p ./%{gemdir} export CONFIGURE_ARGS="--with-cflags='%{optflags}'" gem install --local --install-dir ./%{gemdir} -V --force %{SOURCE0}

%install rm -rf %{buildroot} mkdir -p %{buildroot}%{gemdir} cp -a ./%{gemdir}/* %{buildroot}%{gemdir}

mkdir -p %{buildroot}%{ruby_sitearch} mv %{buildroot}%{geminstdir}/lib/*.so %{buildroot}%{ruby_sitearch} rm -rf %{buildroot}%{geminstdir}/ext

%clean rm -rf %{buildroot}

%files %defattr(-,root,root,-) %{ruby_sitearch}/*.so %{geminstdir}/ %{gemdir}/cache/%{gemname}-%{version}.gem %{gemdir}/specifications/%{gemname}-%{version}.gemspec

[SOLVED] Installed C codes
Currently all C codes (in Gem file) are also installed with  (usually under  ). In my recognition these files are used only for creating C libraries and are not needed anymore. So actually some packagers simply remove these files.
 * Note that when also non-Gem type of source archive is provided, when using non-Gem version such C codes are usually not installed.

However Gem has its own metadata and Gem actually reports that these files should have been installed.
 * Example
 * Currently in rubygem-pam rpm no files are under  (on i386 this is currently  ).
 * However  actually returns some files under this directory.

How should we treat these files?
 * simply don't remove these files
 * ignore gem report in this case and remove these anyway
 * seperate these files into subpackages (e.g. -source subpackage)
 * or anything else

[SOLVED] To pass CFLAGS correctly
I noticed that even for non-Gem Ruby packages, many packages containing C shared libraries which usually contain. In such case export CONFIGURE_ARGS="--with-cflags='%{optflags}'" can be used.
 * have  in the source archives
 * or have  which create
 * A package which uses  directly can take   argument directly, like , however in the case that   creates  , usually   does not accept   argument.

So, maybe the part of how to pass  correctly in the proposal written above can be replaced by more general guideline like following.

Alternative proposal (for both Gem and non-Gem)
export CONFIGURE_ARGS="--with-cflags='%{optflags}'" should be used to pass  to   correctly. This also applies to Ruby Gems.
 * For packages which create C shared libraries using