Ruby erstellen

Abhängigkeiten

  1. Installieren Sie die erforderlichen Abhängigkeiten zum Erstellen des CRuby-Interpreters

    • C-Compiler

    Für RubyGems benötigen Sie außerdem

    Wenn Sie aus dem Git-Repository erstellen möchten, benötigen Sie außerdem

    • autoconf - 2.67 oder neuer

    • gperf - 3.1 oder neuer

      • Normalerweise nicht erforderlich; nur wenn Sie einige Quelldateien mit gperf bearbeiten

    • ruby - 3.1 oder neuer

      • Wir können diese Version auf die System-Ruby-Version des neuesten Ubuntu LTS aktualisieren.

    • git - 2.32 oder neuer

      • Ältere Versionen können funktionieren; 2.32 oder neuer verhindert Build-Fehler, falls Ihre systemeigene .gitconfig $HOME-Pfade verwendet.

  2. Optionale, empfohlene Abhängigkeiten installieren

    • libffi (zum Erstellen von fiddle)

    • gmp (wenn Sie Bignum-Operationen beschleunigen möchten)

    • rustc - 1.58.0 oder neuer, wenn Sie YJIT erstellen möchten.

    Wenn Sie Bibliotheken (z. B. gmp) verlinken möchten, die an einem anderen Ort als dem Standard-Betriebssystem-Speicherort installiert sind, typischerweise mit Homebrew unter macOS, übergeben Sie die Option --with-opt-dir (oder --with-gmp-dir für gmp) an configure.

    configure --with-opt-dir=$(brew --prefix gmp):$(brew --prefix jemalloc)

    Für Bibliotheken, die nur für bestimmte Erweiterungen und nicht für Ruby benötigt werden (openssl, readline, libyaml, zlib), können Sie --with-EXTLIB-dir-Optionen zur Befehlszeile oder zur Umgebungsvariable CONFIGURE_ARGS hinzufügen. Die Befehlszeilenoptionen werden in rbconfig.rb eingebettet, während die letztere Umgebungsvariable nicht eingebettet wird und nur beim Erstellen der Erweiterungsbibliotheken verwendet wird.

    export CONFIGURE_ARGS=""
    for ext in openssl readline libyaml zlib; do
      CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-$ext-dir=$(brew --prefix $ext)"
    done

Schnellstartanleitung

  1. Ruby-Quellcode herunterladen

    Wählen Sie eine der folgenden Optionen.

    1. Aus dem Tarball erstellen

      Laden Sie den neuesten Tarball von der Download Ruby-Seite herunter und entpacken Sie ihn. Beispiel für Ruby 3.0.2

      tar -xzf ruby-3.0.2.tar.gz
      cd ruby-3.0.2
    2. Aus dem Git-Repository erstellen

      CRuby-Quellcode auschecken

      git clone https://github.com/ruby/ruby.git
      cd ruby

      Das GNU Autoconf-Skript ausführen (das das configure-Skript generiert)

      ./autogen.sh
  2. Ein build-Verzeichnis im Repository-Verzeichnis erstellen

    mkdir build && cd build

    Obwohl es nicht notwendig ist, in einem dedizierten Verzeichnis wie diesem zu erstellen, ist es eine gute Praxis, dies zu tun.

  3. Wir werden unser neues Ruby in ~/.rubies/ruby-master installieren, also erstellen wir dieses Verzeichnis

    mkdir ~/.rubies
  4. Das configure-Skript ausführen (das die Makefile generiert)

    ../configure --prefix="${HOME}/.rubies/ruby-master"
    • Auch -C (oder --config-cache) würde die Konfigurationszeit beim nächsten Mal reduzieren.

  5. Ruby erstellen

    make
    
  6. Tests ausführen, um zu bestätigen, dass Ihr Build erfolgreich war.

  7. Unser neu kompiliertes Ruby in ~/.rubies/ruby-master installieren

    make install
    
    • Wenn Sie make install mit sudo ausführen müssen und die Dokumentengenerierung mit unterschiedlichen Berechtigungen vermeiden möchten, können Sie make SUDO=sudo install verwenden.

  8. Sie können dann Ihr neues Ruby ausprobieren, zum Beispiel

    ~/.rubies/ruby-master/bin/ruby -e "puts 'Hello, World!'"

Am Ende wird Ihr Repository wie folgt aussehen

ruby
├── autogen.sh      # Pre-existing Autoconf script, used in step 1
├── configure       # Generated in step 1, which generates the `Makefile` in step 4
├── build           # Created in step 2 and populated in step 4
│   ├── GNUmakefile # Generated by `../configure`
│   ├── Makefile    # Generated by `../configure`
│   ├── object.o    # Compiled object file, built my `make`
│   └── ... other compiled `.o` object files
│
│ # Other interesting files:
├── include
│   └── ruby.h      # The main public header
├── internal
│   ├── object.h
│   └── ... other header files used by the `.c` files in the repo root.
├── lib
│   └── # Default gems, like `bundler`, `erb`, `set`, `yaml`, etc.
├── spec
│   └── # A mirror of the Ruby specification from github.com/ruby/spec
├── test
│   ├── ruby
│   └── ...
├── object.c
└── ... other `.c` files

Unerklärliche Build-Fehler

Wenn Sie unerklärliche Build-Fehler haben, versuchen Sie nach dem Speichern Ihrer gesamten Arbeit, git clean -xfd im Quell-Root auszuführen, um alle von Git ignorierten lokalen Dateien zu entfernen. Wenn Sie mit einem Quellverzeichnis arbeiten, das mehrmals aktualisiert wurde, haben Sie möglicherweise temporäre Build-Artefakte aus früheren Releases, die Build-Fehler verursachen können.

Erstellen unter Windows

Die Dokumentation zum Erstellen unter Windows finden Sie in der separaten Datei.

Weitere Details

Wenn Sie an der Weiterentwicklung von Ruby interessiert sind, finden Sie hier weitere Details zum Build-Prozess von Ruby, die Ihnen helfen.

Make-Skripte parallel ausführen

In GNU make1 und BSD make-Implementierungen können Sie mit dem Flag -j<Anzahl der Prozesse> ein bestimmtes Make-Skript parallel ausführen. Um beispielsweise Tests auf 8 Prozessen auszuführen, verwenden Sie

make test-all -j8

Wir können auch MAKEFLAGS setzen, um *alle* make-Befehle parallel auszuführen.

Das richtige --jobs-Flag stellt sicher, dass alle Prozessoren beim Erstellen von Softwareprojekten ausgelastet werden. Um dies effektiv zu tun, können Sie MAKEFLAGS in Ihrer Shell-Konfiguration/Ihrem Profil setzen

# On macOS with Fish shell:
export MAKEFLAGS="--jobs "(sysctl -n hw.ncpu)

# On macOS with Bash/ZSH shell:
export MAKEFLAGS="--jobs $(sysctl -n hw.ncpu)"

# On Linux with Fish shell:
export MAKEFLAGS="--jobs "(nproc)

# On Linux with Bash/ZSH shell:
export MAKEFLAGS="--jobs $(nproc)"

Miniruby vs. Ruby

Miniruby ist eine Version von Ruby, die keine externen Abhängigkeiten hat und bestimmte Funktionen fehlen. Sie kann bei der Ruby-Entwicklung nützlich sein, da sie schnellere Build-Zeiten ermöglicht. Miniruby wird vor Ruby erstellt. Ein funktionsfähiges Miniruby ist zum Erstellen von Ruby erforderlich. Zum Erstellen von Miniruby

make miniruby

Debugging

Sie können entweder lldb oder gdb zum Debuggen verwenden. Vor dem Debugging müssen Sie eine test.rb mit dem Ruby-Skript erstellen, das Sie ausführen möchten. Sie können die folgenden Make-Ziele verwenden

Für VS Code-Benutzer können Sie eine editorbasierte Debugging-Umgebung einrichten, indem Sie Folgendes ausführen

cp -r misc/.vscode .vscode

Dies fügt Launch-Konfigurationen zum Debuggen von Ruby selbst hinzu, indem test.rb mit lldb ausgeführt wird.

Hinweis: Wenn Sie Ruby im Verzeichnis ./build erstellen, müssen Sie den Programmeintrag in .vscode/launch.json entsprechend aktualisieren auf: "${workspaceFolder}/build/ruby"

Kompilieren für Debugging

Sie können Ruby mit dem Makro RUBY_DEBUG kompilieren, um das Debugging einiger Funktionen zu aktivieren. Ein Beispiel ist das Debuggen von Objektformen in Ruby mit RubyVM::Shape.of(object).

Zusätzlich kann Ruby so kompiliert werden, dass es die Umgebungsvariable RUBY_DEBUG unterstützt, um das Debugging einiger Funktionen zu aktivieren. Ein Beispiel ist die Verwendung von RUBY_DEBUG=gc_stress zum Debuggen von GC-bezogenen Problemen.

Es gibt auch Unterstützung für die Umgebungsvariable RUBY_DEBUG_LOG, um viele Informationen darüber zu protokollieren, was die VM tut, über das Makro USE_RUBY_DEBUG_LOG.

Sie sollten Ruby auch ohne Optimierung und andere Flags konfigurieren, die das Debugging beeinträchtigen könnten, indem Sie die Optimierungsflags ändern.

Alles zusammenführen

./configure cppflags="-DRUBY_DEBUG=1 -DUSE_RUBY_DEBUG_LOG=1" --enable-debug-env optflags="-O0 -fno-omit-frame-pointer"

Erstellen mit Address Sanitizer

Die Verwendung des Address Sanitizer (ASAN) ist eine hervorragende Möglichkeit, Speicherprobleme zu erkennen. Es kann Speicher-Sicherheitslücken in Ruby selbst erkennen, aber auch in C-Erweiterungen, die mit einem mit ASAN kompilierten Ruby kompiliert und geladen werden.

./autogen.sh
mkdir build && cd build
../configure CC=clang-18 cflags="-fsanitize=address -fno-omit-frame-pointer -DUSE_MN_THREADS=0" # and any other options you might like
make

Das kompilierte Ruby wird nun automatisch mit einem Bericht und einem Backtrace abstürzen, wenn ASAN ein Speicher-Sicherheitsproblem erkennt. Um die Testsuite von Ruby unter ASAN auszuführen, geben Sie den folgenden Befehl ein. Beachten Sie, dass dies ziemlich lange dauern wird (über zwei Stunden auf meinem Laptop); die Variablen RUBY_TEST_TIMEOUT_SCALE und SYNTAX_SUGEST_TIMEOUT sind erforderlich, um sicherzustellen, dass Tests nicht fälschlicherweise mit Timeouts fehlschlagen, wenn sie tatsächlich nur langsam sind.

RUBY_TEST_TIMEOUT_SCALE=5 SYNTAX_SUGGEST_TIMEOUT=600 make check

Bitte beachten Sie jedoch die folgenden Vorbehalte!

Wie man die Abdeckung von C- und Ruby-Code misst

Sie müssen in der Lage sein, gcc (gcov) und den lcov-Visualizer zu verwenden.

./autogen.sh
./configure --enable-gcov
make
make update-coverage
rm -f test-coverage.dat
make test-all COVERAGE=true
make lcov
open lcov-out/index.html

Wenn Sie nur C-Code-Abdeckung benötigen, können Sie COVERAGE=true aus dem obigen Prozess entfernen. Sie können auch den Befehl gcov direkt verwenden, um die Abdeckung pro Datei zu erhalten.

Wenn Sie nur Ruby-Code-Abdeckung benötigen, können Sie --enable-gcov entfernen. Beachten Sie, dass test-coverage.dat alle Durchläufe von make test-all ansammelt. Stellen Sie sicher, dass Sie die Datei entfernen, wenn Sie einen Testlauf messen möchten.

Sie können das Abdeckungsergebnis der CI sehen: rubyci.org/coverage


1 VORSICHT: GNU make 3 fehlen einige Funktionen für die parallele Ausführung, wir empfehlen ein Upgrade auf GNU make 4 oder neuer.