nixpkgs/pkgs/development/interpreters/ruby/default.nix

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

443 lines
15 KiB
Nix
Raw Normal View History

2017-10-29 15:51:16 -04:00
{
stdenv,
buildPackages,
lib,
fetchurl,
fetchpatch,
fetchFromSavannah,
zlib,
gdbm,
ncurses,
readline,
groff,
libyaml,
libffi,
jemalloc,
autoreconfHook,
bison,
2018-05-04 19:56:38 +02:00
autoconf,
libiconv,
libunwind,
buildEnv,
bundler,
bundix,
cargo,
rustPlatform,
rustc,
makeBinaryWrapper,
buildRubyGem,
defaultGemConfig,
removeReferencesTo,
2023-11-26 23:27:55 +01:00
openssl,
linuxPackages,
libsystemtap,
gitUpdater,
}@args:
let
op = lib.optional;
ops = lib.optionals;
opString = lib.optionalString;
config = import ./config.nix { inherit fetchFromSavannah; };
rubygems = import ./rubygems {
inherit
stdenv
lib
fetchurl
gitUpdater
;
};
# Contains the ruby version heuristics
rubyVersion = import ./ruby-version.nix { inherit lib; };
2023-12-13 06:47:11 +11:00
generic =
{
version,
hash,
cargoHash ? null,
}:
let
ver = version;
2023-03-09 17:55:45 +09:00
atLeast31 = lib.versionAtLeast ver.majMin "3.1";
atLeast32 = lib.versionAtLeast ver.majMin "3.2";
# https://github.com/ruby/ruby/blob/v3_2_2/yjit.h#L21
yjitSupported =
atLeast32
&& (
stdenv.hostPlatform.isx86_64 || (!stdenv.hostPlatform.isWindows && stdenv.hostPlatform.isAarch64)
);
rubyDrv = lib.makeOverridable (
2018-05-04 19:56:38 +02:00
{
stdenv,
buildPackages,
lib,
fetchurl,
fetchpatch,
fetchFromSavannah,
rubygemsSupport ? true,
zlib,
zlibSupport ? true,
2021-02-12 21:29:10 +01:00
openssl,
opensslSupport ? true,
gdbm,
gdbmSupport ? true,
ncurses,
readline,
cursesSupport ? true,
groff,
docSupport ? true,
libyaml,
yamlSupport ? true,
libffi,
fiddleSupport ? true,
jemalloc,
jemallocSupport ? false,
2018-05-04 19:56:38 +02:00
linuxPackages,
systemtap ? linuxPackages.systemtap,
libsystemtap,
2021-09-17 22:12:30 -07:00
dtraceSupport ? false,
2023-02-24 04:20:00 +00:00
# By default, ruby has 3 observed references to stdenv.cc:
#
# - If you run:
# ruby -e "puts RbConfig::CONFIG['configure_args']"
# - In:
2023-02-24 04:20:00 +00:00
# $out/${passthru.libPath}/${stdenv.hostPlatform.system}/rbconfig.rb
# Or (usually):
2018-12-25 14:25:45 -05:00
# $(nix-build -A ruby)/lib/ruby/2.6.0/x86_64-linux/rbconfig.rb
# - In $out/lib/libruby.so and/or $out/lib/libruby.dylib
removeReferencesTo,
jitSupport ? yjitSupport,
cargo,
rustPlatform,
rustc,
yjitSupport ? yjitSupported,
autoreconfHook,
bison,
autoconf,
buildEnv,
bundler,
bundix,
2018-05-04 19:56:38 +02:00
libiconv,
libunwind,
makeBinaryWrapper,
buildRubyGem,
defaultGemConfig,
2021-09-17 22:12:30 -07:00
baseRuby ? buildPackages.ruby.override {
docSupport = false;
rubygemsSupport = false;
},
2018-05-04 19:56:38 +02:00
useBaseRuby ? stdenv.hostPlatform != stdenv.buildPlatform,
gitUpdater,
}:
2018-05-04 19:56:38 +02:00
stdenv.mkDerivation (finalAttrs: {
2019-08-13 21:52:01 +00:00
pname = "ruby";
inherit version;
2018-05-04 19:56:38 +02:00
src = fetchurl {
url = "https://cache.ruby-lang.org/pub/ruby/${ver.majMin}/ruby-${ver}.tar.gz";
2023-12-13 06:47:11 +11:00
inherit hash;
};
2018-05-04 19:56:38 +02:00
# Have `configure' avoid `/usr/bin/nroff' in non-chroot builds.
NROFF = if docSupport then "${groff}/bin/nroff" else null;
outputs = [ "out" ] ++ lib.optional docSupport "devdoc";
strictDeps = true;
nativeBuildInputs =
[
autoreconfHook
bison
removeReferencesTo
]
++ (op docSupport groff)
++ (ops (dtraceSupport && stdenv.hostPlatform.isLinux) [
systemtap
2023-02-24 04:20:00 +00:00
libsystemtap
])
++ ops yjitSupport [
rustPlatform.cargoSetupHook
cargo
2023-02-24 04:20:00 +00:00
rustc
]
2023-12-03 14:09:56 +01:00
++ op useBaseRuby baseRuby;
2023-02-18 10:45:00 -05:00
buildInputs =
[ autoconf ]
2023-02-18 10:45:00 -05:00
++ (op fiddleSupport libffi)
++ (ops cursesSupport [
ncurses
readline
])
2023-02-18 10:45:00 -05:00
++ (op zlibSupport zlib)
2023-03-09 17:55:45 +09:00
++ (op opensslSupport openssl)
++ (op gdbmSupport gdbm)
2023-03-09 17:55:45 +09:00
++ (op yamlSupport libyaml)
# Looks like ruby fails to build on darwin without readline even if curses
# support is not enabled, so add readline to the build inputs if curses
# support is disabled (if it's enabled, we already have it) and we're
# running on darwin
++ op (!cursesSupport && stdenv.hostPlatform.isDarwin) readline
++ ops stdenv.hostPlatform.isDarwin [
libiconv
libunwind
];
propagatedBuildInputs = op jemallocSupport jemalloc;
enableParallelBuilding = true;
# /build/ruby-2.7.7/lib/fileutils.rb:882:in `chmod':
# No such file or directory @ apply2files - ...-ruby-2.7.7-devdoc/share/ri/2.7.0/system/ARGF/inspect-i.ri (Errno::ENOENT)
# make: *** [uncommon.mk:373: do-install-all] Error 1
enableParallelInstalling = false;
patches =
op (lib.versionOlder ver.majMin "3.1") ./do-not-regenerate-revision.h.patch
++ op useBaseRuby (
if atLeast32 then ./do-not-update-gems-baseruby-3.2.patch else ./do-not-update-gems-baseruby.patch
)
++ ops (ver.majMin == "3.0") [
# Ruby 3.0 adds `-fdeclspec` to $CC instead of $CFLAGS. Fixed in later versions.
(fetchpatch {
url = "https://github.com/ruby/ruby/commit/0acc05caf7518cd0d63ab02bfa036455add02346.patch";
2023-12-13 06:47:11 +11:00
hash = "sha256-43hI9L6bXfeujgmgKFVmiWhg7OXvshPCCtQ4TxqK1zk=";
})
]
2023-03-09 17:55:45 +09:00
++ ops atLeast31 [
# When using a baseruby, ruby always sets "libdir" to the build
# directory, which nix rejects due to a reference in to /build/ in
# the final product. Removing this reference doesn't seem to break
2025-06-02 15:54:57 +02:00
# anything and fixes cross compilation.
./dont-refer-to-build-dir.patch
];
cargoRoot = opString yjitSupport "yjit";
cargoDeps =
if yjitSupport then
rustPlatform.fetchCargoVendor {
inherit (finalAttrs) src;
sourceRoot = "${finalAttrs.pname}-${version}/${finalAttrs.cargoRoot}";
hash =
assert cargoHash != null;
cargoHash;
}
else
null;
postUnpack = opString rubygemsSupport ''
rm -rf $sourceRoot/{lib,test}/rubygems*
cp -r ${rubygems}/lib/rubygems* $sourceRoot/lib
'';
postPatch = ''
sed -i configure.ac -e '/config.guess/d'
cp --remove-destination ${config}/config.guess tool/
2018-10-17 20:05:14 -05:00
cp --remove-destination ${config}/config.sub tool/
'';
configureFlags =
[
(lib.enableFeature (!stdenv.hostPlatform.isStatic) "shared")
(lib.enableFeature true "pthread")
Merge staging-next into master (#44009) * substitute(): --subst-var was silently coercing to "" if the variable does not exist. * libffi: simplify using `checkInputs` * pythonPackges.hypothesis, pythonPackages.pytest: simpify dependency cycle fix * utillinux: 2.32 -> 2.32.1 https://lkml.org/lkml/2018/7/16/532 * busybox: 1.29.0 -> 1.29.1 * bind: 9.12.1-P2 -> 9.12.2 https://ftp.isc.org/isc/bind9/9.12.2/RELEASE-NOTES-bind-9.12.2.html * curl: 7.60.0 -> 7.61.0 * gvfs: make tests run, but disable * ilmbase: disable tests on i686. Spooky! * mdds: fix tests * git: disable checks as tests are run in installcheck * ruby: disable tests * libcommuni: disable checks as tests are run in installcheck * librdf: make tests run, but disable * neon, neon_0_29: make tests run, but disable * pciutils: 3.6.0 -> 3.6.1 Semi-automatic update generated by https://github.com/ryantm/nixpkgs-update tools. This update was made based on information from https://repology.org/metapackage/pciutils/versions. * mesa: more include fixes mostly from void-linux (thanks!) * npth: 1.5 -> 1.6 minor bump * boost167: Add lockfree next_prior patch * stdenv: cleanup darwin bootstrapping Also gets rid of the full python and some of it's dependencies in the stdenv build closure. * Revert "pciutils: use standardized equivalent for canonicalize_file_name" This reverts commit f8db20fb3ae382eba1ba2b160fe24739f43c0bd7. Patching should no longer be needed with 3.6.1. * binutils-wrapper: Try to avoid adding unnecessary -L flags (cherry picked from commit f3758258b8895508475caf83e92bfb236a27ceb9) Signed-off-by: Domen Kožar <domen@dev.si> * libffi: don't check on darwin libffi usages in stdenv broken darwin. We need to disable doCheck for that case. * "rm $out/share/icons/hicolor/icon-theme.cache" -> hicolor-icon-theme setup-hook * python.pkgs.pytest: setupHook to prevent creation of .pytest-cache folder, fixes #40273 When `py.test` was run with a folder as argument, it would not only search for tests in that folder, but also create a .pytest-cache folder. Not only is this state we don't want, but it was also causing collisions. * parity-ui: fix after merge * python.pkgs.pytest-flake8: disable test, fix build * Revert "meson: 0.46.1 -> 0.47.0" With meson 0.47.0 (or 0.47.1, or git) things are very wrong re:rpath handling resulting in at best missing libs but even corrupt binaries :(. When we run patchelf it masks the problem by removing obviously busted paths. Which is probably why this wasn't noticed immediately. Unfortunately the binary already has a long series of paths scribbled in a space intended for a much smaller string; in my testing it was something like lengths were 67 with 300+ written to it. I think we've reported the relevant issues upstream, but unfortunately it appears our patches are what introduces the overwrite/corruption (by no longer being correct in what they assume) This doesn't look so bad to fix but it's not something I can spend more time on at the moment. -- Interestingly the overwritten string data (because it is scribbled past the bounds) remains in the binary and is why we're suddenly seeing unexpected references in various builds -- notably this is is the reason we're seeing the "extra-utils" breakage that entirely crippled NixOS on master (and probably on staging before?). Fixes #43650. This reverts commit 305ac4dade5758c58e8ab1666ad0197fd305828d. (cherry picked from commit 273d68eff8f7b6cd4ebed3718e5078a0f43cb55d) Signed-off-by: Domen Kožar <domen@dev.si>
2018-07-24 16:04:48 +02:00
(lib.withFeatureAs true "soname" "ruby-${version}")
(lib.withFeatureAs useBaseRuby "baseruby" "${baseRuby}/bin/ruby")
(lib.enableFeature dtraceSupport "dtrace")
(lib.enableFeature jitSupport "jit-support")
(lib.enableFeature yjitSupport "yjit")
(lib.enableFeature docSupport "install-doc")
(lib.withFeature jemallocSupport "jemalloc")
(lib.withFeatureAs docSupport "ridir" "${placeholder "devdoc"}/share/ri")
# ruby enables -O3 for gcc, however our compiler hardening wrapper
# overrides that by enabling `-O2` which is the minimum optimization
# needed for `_FORTIFY_SOURCE`.
]
++ lib.optional stdenv.cc.isGNU "CFLAGS=-O3"
++ [
]
++ ops stdenv.hostPlatform.isDarwin [
# on darwin, we have /usr/include/tk.h -- so the configure script detects
# that tk is installed
"--with-out-ext=tk"
# on yosemite, "generating encdb.h" will hang for a very long time without this flag
"--with-setjmp-type=setjmp"
]
++ ops stdenv.hostPlatform.isFreeBSD [
"rb_cv_gnu_qsort_r=no"
"rb_cv_bsd_qsort_r=yes"
];
preConfigure = opString docSupport ''
# rdoc creates XDG_DATA_DIR (defaulting to $HOME/.local/share) even if
# it's not going to be used.
export HOME=$TMPDIR
'';
# fails with "16993 tests, 2229489 assertions, 105 failures, 14 errors, 89 skips"
2022-03-14 16:31:14 +09:00
# mostly TZ- and patch-related tests
# TZ- failures are caused by nix sandboxing, I didn't investigate others
doCheck = false;
2022-03-14 16:31:14 +09:00
preInstall = ''
# Ruby installs gems here itself now.
mkdir -pv "$out/${finalAttrs.passthru.gemPath}"
2024-10-30 12:00:45 -04:00
export GEM_HOME="$out/${finalAttrs.passthru.gemPath}"
'';
2024-10-30 12:00:45 -04:00
installFlags = lib.optional docSupport "install-doc";
# Bundler tries to create this directory
postInstall =
''
rbConfig=$(find $out/lib/ruby -name rbconfig.rb)
# Remove references to the build environment from the closure
sed -i '/^ CONFIG\["\(BASERUBY\|SHELL\|GREP\|EGREP\|MKDIR_P\|MAKEDIRS\|INSTALL\)"\]/d' $rbConfig
# Remove unnecessary groff reference from runtime closure, since it's big
sed -i '/NROFF/d' $rbConfig
${lib.optionalString (!jitSupport) ''
# Get rid of the CC runtime dependency
remove-references-to \
-t ${stdenv.cc} \
$out/lib/libruby*
remove-references-to \
-t ${stdenv.cc} \
$rbConfig
sed -i '/CC_VERSION_MESSAGE/d' $rbConfig
''}
# Allow to override compiler. This is important for cross compiling as
# we need to set a compiler that is different from the build one.
sed -i "$rbConfig" \
-e 's/CONFIG\["CC"\] = "\(.*\)"/CONFIG["CC"] = if ENV["CC"].nil? || ENV["CC"].empty? then "\1" else ENV["CC"] end/' \
-e 's/CONFIG\["CXX"\] = "\(.*\)"/CONFIG["CXX"] = if ENV["CXX"].nil? || ENV["CXX"].empty? then "\1" else ENV["CXX"] end/'
# Remove unnecessary external intermediate files created by gems
extMakefiles=$(find $out/${finalAttrs.passthru.gemPath} -name Makefile)
2022-03-14 16:31:14 +09:00
for makefile in $extMakefiles; do
make -C "$(dirname "$makefile")" distclean
done
find "$out/${finalAttrs.passthru.gemPath}" \( -name gem_make.out -o -name mkmf.log -o -name exts.mk \) -delete
# Bundler tries to create this directory
mkdir -p $out/nix-support
cat > $out/nix-support/setup-hook <<EOF
addGemPath() {
addToSearchPath GEM_PATH \$1/${finalAttrs.passthru.gemPath}
}
addRubyLibPath() {
addToSearchPath RUBYLIB \$1/lib/ruby/site_ruby
addToSearchPath RUBYLIB \$1/lib/ruby/site_ruby/${ver.libDir}
addToSearchPath RUBYLIB \$1/lib/ruby/site_ruby/${ver.libDir}/${stdenv.hostPlatform.system}
}
addEnvHooks "$hostOffset" addGemPath
addEnvHooks "$hostOffset" addRubyLibPath
EOF
''
+ opString docSupport ''
# Prevent the docs from being included in the closure
sed -i "s|\$(DESTDIR)$devdoc|\$(datarootdir)/\$(RI_BASE_NAME)|" $rbConfig
sed -i "s|'--with-ridir=$devdoc/share/ri'||" $rbConfig
# Add rbconfig shim so ri can find docs
mkdir -p $devdoc/lib/ruby/site_ruby
cp ${./rbconfig.rb} $devdoc/lib/ruby/site_ruby/rbconfig.rb
''
+ opString useBaseRuby ''
# Prevent the baseruby from being included in the closure.
remove-references-to \
-t ${baseRuby} \
$rbConfig $out/lib/libruby*
'';
installCheckPhase = ''
overriden_cc=$(CC=foo $out/bin/ruby -rrbconfig -e 'puts RbConfig::CONFIG["CC"]')
if [[ "$overriden_cc" != "foo" ]]; then
echo "CC cannot be overwritten: $overriden_cc != foo" >&2
false
fi
fallback_cc=$(unset CC; $out/bin/ruby -rrbconfig -e 'puts RbConfig::CONFIG["CC"]')
if [[ "$fallback_cc" != "$CC" ]]; then
2022-08-12 04:20:00 +00:00
echo "CC='$fallback_cc' should be '$CC' by default" >&2
false
fi
'';
2022-08-12 04:20:00 +00:00
doInstallCheck = true;
2022-08-12 04:20:00 +00:00
disallowedRequisites = op (!jitSupport) stdenv.cc ++ op useBaseRuby baseRuby;
meta = with lib; {
2017-09-08 12:07:39 +08:00
description = "Object-oriented language for quick and easy programming";
homepage = "https://www.ruby-lang.org/";
license = licenses.ruby;
maintainers = with maintainers; [ manveru ];
platforms = platforms.all;
2024-07-27 10:31:11 +02:00
mainProgram = "ruby";
knownVulnerabilities = op (lib.versionOlder ver.majMin "3.0") "This Ruby release has reached its end of life. See https://www.ruby-lang.org/en/downloads/branches/.";
};
passthru =
rec {
version = ver;
rubyEngine = "ruby";
libPath = "lib/${rubyEngine}/${ver.libDir}";
gemPath = "lib/${rubyEngine}/gems/${ver.libDir}";
devEnv = import ./dev.nix {
inherit buildEnv bundler bundix;
ruby = finalAttrs.finalPackage;
};
inherit rubygems;
inherit
(import ../../ruby-modules/with-packages {
inherit
lib
stdenv
makeBinaryWrapper
buildRubyGem
buildEnv
;
gemConfig = defaultGemConfig;
ruby = finalAttrs.finalPackage;
})
withPackages
buildGems
gems
;
2021-09-17 22:12:30 -07:00
}
// lib.optionalAttrs useBaseRuby {
inherit baseRuby;
};
})
) args;
in
rubyDrv;
in
{
mkRubyVersion = rubyVersion;
mkRuby = generic;
ruby_3_1 = generic {
2025-03-26 15:07:36 +01:00
version = rubyVersion "3" "1" "7" "";
hash = "sha256-BVas1p8UHdrOA/pd2NdufqDY9SMu3wEkKVebzaqzDns=";
};
ruby_3_2 = generic {
2025-03-26 15:08:05 +01:00
version = rubyVersion "3" "2" "8" "";
hash = "sha256-d6zdjPu+H45XO15lNuA8UQPfmJ3AX6aMcPARgzw1YHU=";
cargoHash = "sha256-CMVx5/+ugDNEuLAvyPN0nGHwQw6RXyfRsMO9I+kyZpk=";
};
2023-06-16 17:15:23 +10:00
ruby_3_3 = generic {
version = rubyVersion "3" "3" "8" "";
hash = "sha256-WuKKh6WaPkrWa8KTHSMturlT0KqPa687xPj4CXfInKs=";
cargoHash = "sha256-xE7Cv+NVmOHOlXa/Mg72CTSaZRb72lOja98JBvxPvSs=";
2023-06-16 17:15:23 +10:00
};
ruby_3_4 = generic {
version = rubyVersion "3" "4" "3" "";
hash = "sha256-VaTNHcvlyifPZeiak1pILCuyKEgyk5JmVRwOxotDf0Y=";
cargoHash = "sha256-5Tp8Kth0yO89/LIcU8K01z6DdZRr8MAA0DPKqDEjIt0=";
};
}