• [gentoo-user] How to install Ruby bindings in an ebuild

    From Ralph Seichter@21:1/5 to All on Wed Apr 19 01:10:02 2023
    I need to install Ruby bindings (something.so) during an ebuild,
    specifically into the /usr/lib64/ruby/vendor_ruby/3.0.0/x86_64-linux
    directory. I scanned existing ebuilds for an example, but have not yet
    found one. The developer manual [1] mentions newlib.so, but that
    function appears to inject "/lib64" into the destination path on my
    machine. Thus, I currently use the following crutch:

    exeinto /usr/lib64/ruby/vendor_ruby/3.0.0/x86_64-linux
    doexe ./bindings/ruby/something.so

    While this works for the time being, this seems quite wrong to me,
    because the destination path is obviously hardcoded. Is there perhaps
    something in the ruby-utils or ruby-single eclasses I missed? I had
    hoped to find support for installing vendor modules for Ruby here.

    Your suggestiions are appreciated.

    -Ralph

    [1] https://devmanual.gentoo.org/function-reference/install-functions/index.html

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael Orlitzky@21:1/5 to Ralph Seichter on Thu Apr 20 01:20:01 2023
    On 2023-04-19 01:08:23, Ralph Seichter wrote:
    I need to install Ruby bindings (something.so) during an ebuild,
    specifically into the /usr/lib64/ruby/vendor_ruby/3.0.0/x86_64-linux directory.

    Hey Ralph. I'm not an expert on the ruby eclasses, but they work more
    or less like the python ones, if that helps at all.

    In this case, it looks like you have a package that builds a binary
    ruby extension. That extension should be married to a specific version
    of ruby, namely the one it was built against. I think the best way to
    support that in a package is to declare which ruby versions are
    supported with USE_RUBY and ruby-ng.eclass. USE_RUBY will be cross-
    referenced with the user's RUBY_TARGETS to determine which ruby
    versions are ultimately supported. Then, parts of the ebuild will be
    repeated for each ruby version that the ebuilds supports and that the
    user wants.

    You can fine-tune what happens in each phase with the eclass functions each_ruby_<phase>. So for example, if this is a C package, you might
    only want to run ./configure && make extension && make install-extension
    in the separate version-specific phases, so as to avoid rebuilding the
    whole entire package for each version of ruby.

    As always, the devil is in the details, but ruby-ng.eclass is a good
    starting point.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ralph Seichter@21:1/5 to All on Fri Apr 21 09:20:01 2023
    Hello Michael. Long time no read. ;-)

    I think the best way to support that in a package is to declare which
    ruby versions are supported with USE_RUBY and ruby-ng.eclass.

    I tried what you suggested. However, inheriting from ruby-ng.eclass
    introduces an odd problem: For some reason unknown to me, "${S}" no
    longer matches the default value of "${WORKDIR}/${P}", but only what I'd
    expect in "${WORKDIR}". That means the base directory for src_compile
    and src_install is not correct, causing the build to fail. It might be a
    bug in ruby-ng, or a side effect of inheriting from ruby-ng on top of
    the other eclasses already needed/used by the ebuild. I don't feel
    comfortable with opening this particular can of worms when only a single library something.so needs to be installed. Right now, I changed to
    this:

    local p=$(ruby -e 'puts $LOAD_PATH' | grep 'vendor.\+linux')
    [[ -d "${p}" ]] || die "'${p}' is not a directory"
    exeinto "${p}"

    Not very pretty either, but at least this avoids any hardcoded
    directories.

    -Ralph

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael Orlitzky@21:1/5 to Ralph Seichter on Fri Apr 21 21:30:01 2023
    On Fri, 2023-04-21 at 09:16 +0200, Ralph Seichter wrote:

    I tried what you suggested. However, inheriting from ruby-ng.eclass introduces an odd problem: For some reason unknown to me, "${S}" no
    longer matches the default value of "${WORKDIR}/${P}", but only what I'd expect in "${WORKDIR}".

    The eclass sets S=$WORKDIR at first because it creates a separate
    source tree for each version of ruby that will be built for. For
    example, you might have both $WORKDIR/ruby27 and $WORKDIR/ruby28. Later
    on in the each_ruby_foo phases, $S will point to one of those, so it
    should look more like what you're expecting.


    library something.so needs to be installed. Right now, I changed to
    this:

    local p=$(ruby -e 'puts $LOAD_PATH' | grep 'vendor.\+linux')
    [[ -d "${p}" ]] || die "'${p}' is not a directory"
    exeinto "${p}"

    Not very pretty either, but at least this avoids any hardcoded
    directories.


    That uses the currently-eselected version of ruby to determine the path
    though. If you eselect another version, or if you update the current
    one, the bindings will stop working.

    It may still not be worth the effort, but I'd keep that in mind when
    updating ruby.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ralph Seichter@21:1/5 to All on Fri Apr 21 22:20:01 2023
    * Michael Orlitzky:

    The eclass sets S=$WORKDIR at first because it creates a separate
    source tree for each version of ruby that will be built for. [...]

    Hm. While that sounds useful for "full Ruby" ebuilds, I don't see how to circumvent the impact for the particular ebuild I am trying to extend,
    other than overriding S in src_compile() etc.

    The build needs to create a C shared library, Python bindings, and now
    an additional shared library containing the Ruby bindings. Might this be
    a case where a new, separate ebuild for the Ruby bindings would be a
    better option than expanding the existing build?

    That uses the currently-eselected version of ruby to determine the
    path though.

    I thought of that and tried to use ${RUBY} instead, but the variable was
    empty. Hence I use the literal 'ruby' as a workaround, until a better
    method comes to mind.

    -Ralph

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael Orlitzky@21:1/5 to Ralph Seichter on Tue Apr 25 14:00:01 2023
    On Fri, 2023-04-21 at 22:15 +0200, Ralph Seichter wrote:

    Hm. While that sounds useful for "full Ruby" ebuilds, I don't see how to circumvent the impact for the particular ebuild I am trying to extend,
    other than overriding S in src_compile() etc.

    The build needs to create a C shared library, Python bindings, and now
    an additional shared library containing the Ruby bindings. Might this be
    a case where a new, separate ebuild for the Ruby bindings would be a
    better option than expanding the existing build?


    Ultimately what you want to do is build all of that other stuff once,
    and then build ruby binding for each version of ruby. You can probably
    make that happen by mucking around with the each_ruby_foo and
    all_ruby_foo phases, but I think a separate ebuild would work too.
    Assuming that the bindings link to the library, in both cases you face
    the same problem: to convince the build system to link against a
    different copy of the C library. With a single ebuild, you want the ruby-specific builds to link against the one shared library you just
    built; with a separate ebuild you'd want them all to link against the
    system copy that was installed by the main ebuild.


    I thought of that and tried to use ${RUBY} instead, but the variable was empty. Hence I use the literal 'ruby' as a workaround, until a better
    method comes to mind.

    One final option would be to figure out how the eclass is finding the
    supported ruby versions, and copy it. Then you could loop through them
    and use your hack with each one.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)