Feature #17760
closedWhere we should install a header file when `gem install --user`?
Description
As digest
have been made a default gem at Ruby 3.0, it can be installed by gem install
command.
When we install digest
, digest.h
is installed at the same directory as ruby.h
. But when we use gem install --user
for installing it, where should digest.h
is installed in?
Now, the location of digest.h
is always the same directory as ruby.h
regardless of whether we use gem install --user
. It occurs permission error when non-root user uses gem install --user
for installing digest
on the system-ruby.
Updated by mrkn (Kenta Murata) over 3 years ago
The permission error was reported at https://github.com/ruby/digest/issues/14.
Updated by nobu (Nobuyoshi Nakada) over 3 years ago
- Tracker changed from Feature to Bug
- Backport set to 2.5: REQUIRED, 2.6: REQUIRED, 2.7: REQUIRED, 3.0: REQUIRED
Updated by nobu (Nobuyoshi Nakada) over 3 years ago
- Related to Bug #17761: Install location of header files in extension libraries added
Updated by nobu (Nobuyoshi Nakada) over 3 years ago
- Tracker changed from Bug to Feature
- Status changed from Open to Third Party's Issue
- Backport deleted (
2.5: REQUIRED, 2.6: REQUIRED, 2.7: REQUIRED, 3.0: REQUIRED)
This is because rubygems doesn't manage header files installed from gems, since no gems had installed headers until digest has been gemified.
Now rubygems needs to support such gems.
Updated by Eregon (Benoit Daloze) about 3 years ago
Is there a RubyGems issue tracking this?
Updated by byroot (Jean Boussier) about 3 years ago
@deivid (David Rodríguez) are you aware of this issue? Any idea how we could fix this or what decision would need to be taken?
I fear that the digest
extraction might cause major problem to people trying to upgrade to 3.1 next year, or trying to test 3.1.0-preview1
soon.
Updated by deivid (David Rodríguez) about 3 years ago
Hi, no I wasn't, and I'm not sure how it should be fixed. If I understand correctly, this is about cases where rubygems does not have write access to the location where ruby itself is installed, while it does have write access to the location where gems are installed, correct?
Updated by byroot (Jean Boussier) about 3 years ago
Kind of yes. From my understanding the problem is that $INSTALL_FILES always install files in site_ruby
https://github.com/ruby/digest/blob/1cb6bac1a6732a1415278b94fad2fdc695477dec/ext/digest/extconf.rb#L7-L9
So from my limited understanding I see two ways out of this:
- Require that
site_ruby
is user writable (sounds weird) - Have a location defined by rubygems that acts as "user" site ruby.
But then I suppose them that compile against digest.h
would also need to know where to look, I'm really unsure how it's supposed to work. If I have 5 different versions of digest, which one should I compile against?
e.g. I have app1
with digest 3.0.0
and app2
with digest 3.2.0
, both have somegem-that-link-to-digest
, this means we'd need to compile that gem twice and link against different headers?
Seems complicated. Maybe I should put this to the next developers meeting agenda.
Updated by Eregon (Benoit Daloze) about 3 years ago
byroot (Jean Boussier) wrote in #note-8:
But then I suppose them that compile against
digest.h
would also need to know where to look, I'm really unsure how it's supposed to work. If I have 5 different versions of digest, which one should I compile against?
Because digest is a default gem, I think there is a simple answer here: latest version wins.
That's the behavior of default gems, if you gem install some_default_gem
, RubyGems will then always use that version (instead of the version shipped with Ruby).
When using bundler, I'd think it's possible to choose an explicit version, and bundler would resolve which one is used.
Probably RubyGems and/or Bundler need to set CPATH to the header is found (seems better), or we need some explicit API in RubyGems and/or mkmf for a gem to ask headers for another gem (seems bad as then we have the version problem).
Updated by Eregon (Benoit Daloze) about 3 years ago
byroot (Jean Boussier) wrote in #note-8:
e.g. I have
app1
withdigest 3.0.0
andapp2
withdigest 3.2.0
, both havesomegem-that-link-to-digest
, this means we'd need to compile that gem twice and link against different headers?
This is a good point.
Maybe it can be resolved by somegem-that-link-to-digest
depending on an exact version (or small range of versions) of digest which have the same header and fully compatible (both forward and backward between all those versions)?
I.e., the header is also part of API (or technically ABI) so if digest
changes the header in some incompatible way (including what gets generated by gems using it), then it should bump the major version (or some other well-documented scheme).
Seems complicated. Maybe I should put this to the next developers meeting agenda.
Yes, I think that would be useful.
Updated by byroot (Jean Boussier) about 3 years ago
then it should bump the major version (or some other well-documented scheme).
I can hardly see something like this working in practice. Maybe for digest it would work as realistically it won't change much in the future. But if Rubygems introduce this header file management, other gems will start using it, and I can foresee tons of problems.
Updated by knu (Akinori MUSHA) about 3 years ago
We have discussed this in today's developer meeting.
- As a tentative workaround, I'll fix the digest gem not to try to install
digest.h
to an unwritable directory sogem install --user digest
succeeds. - It is (technically) possible for RubyGems to specify where to install header files by passing
HDRDIR=destination
tomake install
for example, and to expose the installed header files of activated gems to a newly built gem by passingCPPFLAGS
toextconf.rb
that lists the header directories.