Is nixpkgs.ruby's closure supposed to include clang?

I just noticed today that ruby’s closure includes clang, and therefore it has a rather large closure size:

> nix path-info -rsSh nixpkgs.ruby
...
/nix/store/pvsvf70ww1xgqqixcp1fcsz1m0xq8baz-clang-7.1.0                            	 387.3M	 503.2M
/nix/store/gkcr1p2x0psdc31bavmqbfb2nwq0d6jn-clang-wrapper-7.1.0                    	  43.1K	 674.9M
/nix/store/3896j4c7xc101nw1nrhb449rqv0sqkxr-ruby-2.6.6                             	  16.4M	 721.1M
...

I know gem and bundler can build C gems and therefore need the compiler, but surely I don’t need the compiler in order to run ruby itself? This also means any package built with bundlerApp transitively includes clang.

Is this a known issue? Any way to avoid it? Or are we stuck because the bundler runtime support used for loading gems also has the capability of building them?

I ask because I’m working on trying to deploy Nix to my team at work, and I really don’t want everyone to have to download almost 700MB of compiler support when everything is served from a binary cache.

@lilyball on Darwin I expect ruby to reference clang as well as it references gcc on Linux. See:

https://github.com/NixOS/nixpkgs/issues/89445

And:

https://github.com/NixOS/nixpkgs/pull/90151

1 Like

Thanks, I’ll look into what’s referenced in those links. It looks like this does require building a custom version of ruby though, which is unfortunate as I assume that takes a non-trivial amount of time to compile, but I guess I’ll find out tomorrow.

It doesn’t take that long to build a ruby, at least for me, on an newish i7 laptop (~5 minutes).

Spending 5 minutes building ruby will dwarf the entire rest of the time spent building dependencies for my project (most of what we need is satisfied by the binary cache, right now we only need to compile a few gems and a small Go tool). If I can get a private binary cache set up accessible to developers on my team that would help, but I’m not doing that yet, so I’m trying to keep the “build dependencies” step as fast as possible.

I don’t suppose there’s any reasonable way for me to copy the ruby output and muck with it to remove the clang dependency, is there?

You could I guess use removeReferencesFrom… But perhaps we should revert this commit:

https://github.com/NixOS/nixpkgs/commit/9db44f61a78a3a1fea720de7465787383a52d010

I wanted that PR to get in because it bothered me that asciidoctor pulls in gcc. But, even the rubyMinimal we had right before that commit, didn’t include the features apparently asciidoctor requires. Which are, according to my tests:

{
  ruby = super.ruby.override {
    # rubyMinimal disables too much features required by asciidoctor
    rubygemsSupport = true;
    jitSupport = false;
    useRailsExpress = false;
    zlibSupport = true;
    opensslSupport = true;
    gdbmSupport = false;
    cursesSupport = false;
    docSupport = false;
    yamlSupport = false;
    fiddleSupport = false;
  };
}

I.e zlib, openssl support (rubygems was included already).

It looks like rubyMinimal turned off a ton of stuff.

It would be nice to simply have a version of ruby where the only difference is jitSupport = false (assuming that’s sufficient to remove the compiler references). I can declare this myself but having that be in nixpkgs would get me prebuilt binaries. In addition, we could then do a pass over any bundlerApp packages and move them to the new jitless ruby when possible, to reduce closure sizes.