RHEL 9 Üzerinde Python 3.12'yi Kaynaktan Derlemek

Selamlar, bu yazımda RHEL 9 üzerinde Python 3.12'yi kaynaktan nasıl derlediğimi, hangi ./configure bayraklarının gerçekten işe yaradığını ve dnf ile gelen paket yerine neden bazen kaynaktan derlemenin zorunlu olduğunu paylaşacağım. Konuya yabancı arkadaşlar için adım adım ilerleyeceğiz, ama bu sıradan bir 'kopyala yapıştır' rehberi değil. Hadi başlayalım.

RHEL 9'un depolarında Python 3.9 sistem yorumlayıcısı olarak gelir, AppStream üzerinden 3.11'i de kurabilirsiniz. Ama 3.12'nin yeni hata mesajları, daha hızlı yorumlayıcı çekirdeği ve typing tarafındaki iyileştirmeleri için kaynaktan derleme tek seçenek. Üstelik PGO (Profile-Guided Optimization) ve LTO (Link-Time Optimization) bayraklarını açtığınızda, dnf'ten gelen paketin sunamadığı bir performansı kendi makinenizin profiline göre çıkarmış oluyorsunuz.

Neden dnf install yerine kaynaktan?

Aslına bakarsanız dnf install python3.12 çoğu durumda yeter. Peki o zaman neden uğraşıyoruz? Üç sebep var:

  • Sürüm kontrolü: Depo bir yama gecikmeli kalabilir. Kaynaktan derlerseniz python.org'un yayınladığı an o sürümdesinizdir.
  • Build bayrakları: Distro paketleri muhafazakar derlenir. PGO ve LTO açık paketleri her zaman bulamazsınız.
  • Sistem Python'una dokunmamak: RHEL'in yum, dnf, firewalld gibi araçları sistem Python'una bağımlıdır. Yanlış bir make install ortalığı dağıtır. Biz altinstall ile bu riski sıfırlıyoruz.

Bence ekibinizde standart bir geliştirme imajı varsa kaynaktan derleme şart. Aksi halde her makine kendi sürüm dramasını yaşar.

Altmodul bağımlılıkları

Python'u boş bir makinede derlerseniz _ssl, _sqlite3, readline gibi modullerin sessizce devre dışı kaldığını görürsünüz. make size bunu kırmızı bir hata olarak söylemez, sadece sonuç olarak import ssl patladığında anlarsınız. Bu yüzden derlemeye geçmeden önce gerekli kütüphaneleri kurmak gerekiyor:

sudo dnf groupinstall -y 'Development Tools'

sudo dnf install -y \
    openssl-devel \
    bzip2-devel \
    libffi-devel \
    zlib-devel \
    readline-devel \
    sqlite-devel \
    xz-devel \
    tk-devel \
    gdbm-devel \
    libuuid-devel \
    ncurses-devel \
    expat-devel \
    wget

openssl-devel olmadan pip HTTPS yapamaz, libffi-devel olmadan ctypes çalışmaz, sqlite-devel olmadan da yerel cache çözümleriniz çöker. Bu listeyi eksik bırakmak en sık karşılaşılan tuzak.

Configure ve derleme

Kaynak arşivini indirip configure adımına geliyoruz. Şahsi tercihim her şeyi /usr/local/python3.12 altına ayrı bir prefix ile koymak; böylece bir gün silmek istersem tek rm -rf yetiyor.

PYTHON_VERSION=3.12.4
cd /tmp
wget "https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tgz"
tar xzf "Python-${PYTHON_VERSION}.tgz"
cd "Python-${PYTHON_VERSION}"

./configure \
    --prefix=/usr/local/python3.12 \
    --enable-optimizations \
    --with-lto \
    --enable-shared \
    --with-system-ffi

--enable-optimizations PGO'yu açar. Bu yorumlayıcıyı önce derleyip kendi test takımıyla profil çıkarır, sonra o profile göre yeniden derler. İki kat süre alır ama çalışma zamanında yüzde 10-20 hız farkı görüyorsunuz. --with-lto derleme zamanı son optimizasyonu açar, ek maliyeti küçük, kazancı somut. --enable-shared ise libpython3.12.so'yu üretir; gömülü Python kullanan uygulamalarınız varsa ihtiyacınız olur.

make -j "$(nproc)"
sudo make altinstall

Buradaki kritik nokta altinstall. install derseniz /usr/local/bin/python3 sembolik linki sistem Python'una çakışır ve dnf çalışmaz hale gelir. altinstall ise yorumlayıcıyı yalnızca python3.12 ismiyle kurar, sistemde başka hiçbir şeye dokunmaz.

Paylaşılan kütüphane ve dogrulama

--enable-shared ile derlediğimiz için libpython3.12.so'yu çalışma zamanında bulabilmesi gerekiyor:

echo '/usr/local/python3.12/lib' | sudo tee /etc/ld.so.conf.d/python3.12.conf
sudo ldconfig

Ardından kritik modulleri doğrulayalim. Bu adımı atlamayın, derleme başarılı görünse bile bir modul eksik olabilir:

/usr/local/python3.12/bin/python3.12 -c "
import ssl; print('ssl:', ssl.OPENSSL_VERSION)
import sqlite3, ctypes, readline, zlib, bz2, lzma
print('hepsi calisiyor')
"

Çıktıda OpenSSL sürümü ve hepsi calisiyor görüyorsanız iş tamam.

Sık karşılaşılan tuzaklar

  • openssl-devel eksik kurmak: pip install ilk paket çekiminde SSL hatasıyla patlar; derleme aşamasında uyarı bile yok.
  • make install yapmak: Sistem Python'unu eziyorsunuz. RHEL araçları çalışmaz hale gelir, geri dönüş zor.
  • ldconfig çalıştırmamak: --enable-shared ile derlediyseniz python3.12 çağrısı error while loading shared libraries ile düşer.
  • PATH'i güncellememek: Yorumlayıcı kurulu ama python3.12 komutu bulunamıyor diye yarım saat kafa yorabilirsiniz; ~/.bashrc içine export PATH="/usr/local/python3.12/bin:$PATH" eklemek yeter.

Kapanış

Bu yazıda RHEL 9 üzerinde Python 3.12'yi --enable-optimizations ve --with-lto ile kaynaktan derledik, altmodul bağımlılıklarının neden hayati olduğunu ve altinstall'in sistem Python'unu nasıl koruduğunu gördük. Bana sorarsanız PGO'nun maliyeti uzun derleme süresine değiyor, hele de aynı imajı çok makinede kullanacaksanız. Umarım faydalı olur, bir sonraki yazıda görüşmek üzere.