Python Programming

PyPI Ötesi: Scikit-Build ile Veri Bilimi İçin C-Extensions ve Binary Wheels Ustalık

Python, veri biliminin evrensel dili haline gelmiş olsa da, ekosistemin saf Python'a olan bağımlılığı genellikle kritik bir darboğazı: performansı gizler. Ağır sayısal hesaplamalar için veri bilimciler sık sık NumPy, SciPy ve Pandas gibi C, C++ veya Fortran üzerine inşa edilmiş kütüphanelere yönelirler. Ancak, bu kütüphanelerin dağıtımı, bakımcılar için benzersiz bir zorluk sunar. Standart Python paketlerinin aksine, yerel uzantılara sahip kütüphaneler, karmaşık bir derleme ortamı, derleyici araç setleri ve uyumlu bağımlılıklar gerektirmeden her kullanıcının makinesinde kaynaktan kurulamaz. Sonuç genellikle kurulumu yavaş ve farklı işletim sistemlerinde derleme hatalarına yatkın olan "sadece kaynak" dağıtımlardır.

İşte modern Python paketleme araçlarının devreye girdiği yer. Geleneksel setup.py betikleri ile setuptools yapılandırması, PEP 517 ve PEP 621'e uyan derleme arka uçları tarafından giderek daha fazla değiştirilmektedir. Bunların arasında, C/C++ uzantıları gerektiren projeler için scikit-build-core altın standart haline gelmiştir. Bu kılavuzda, veri bilimi kütüphanenizin her kullanıcının ortamına bakılmaksızın en üst düzey performansı sunmasını sağlamak için scikit-build-core'u kullanarak sağlam, mimariye özgü binary wheel'ler oluşturmayı nasıl kullanacağımızı inceleyeceğiz.

Python Paketlemenin Evrimi

scikit-build'in neden çözüm olduğunu anlamak için önce geçmişin acı noktalarını kabul etmemiz gerekir. Daha önce geliştiriciler, derleme mantığını kurulum mantığıyla karıştıran setup.py dosyalarına güveniyorlardı. Bu prosedürel yaklaşım, derleme ortamı hedef ortamla eşleşmediğinde "bir kez derle, her yerde dağıt" başarısızlıklarına yol açıyordu. Ayrıca, birden fazla platform (Linux, macOS, Windows) ve mimari (x86_64, ARM64) için wheel'ler (binary dağıtımlar) oluşturmak, karmaşık ve manuel yapılandırma gerektiriyordu.

Python paketleme, beyan edici yapılandırmalara doğru kaymıştır. PEP 621, proje meta verilerinin pyproject.toml içinde tanımlanmasına olanak tanır ve derleme mantığını proje yapılandırmasından ayırır. Scikit-build-core, bu beyan edici iş akışı için özel olarak tasarlanmış modern bir CMake tabanlı derleme arka ucudur. CMake'ı çağırma, derleyicileri yönetme ve ikili dosyaları wheel'lere otomatik olarak paketleme karmaşıklıklarını yönetir.

Proje Yapısı ve Yapılandırma

scikit-build-core ile bir proje kurmak, iyi yapılandırılmış bir dizin düzeni ile başlar. Python kodunuz için bir kaynak klasörü, C/C++ kodunuz için bir src dizini ve derleme sistemine ne yapması gerektiğini söyleyen bir pyproject.toml dosyasına ihtiyacınız var.

project-root/
├── src/
│   ├── my_package/
│   │   ├── __init__.py
│   │   └── _core.c
├── pyproject.toml
└── build_requirements.txt

Yapılandırmanın kalbi pyproject.toml dosyasında yer alır. Derleme arka ucunu scikit_build_core olarak tanımlar ve CMake gereksinimlerini belirtiriz. Bu, eski setup.py'yi tamamen değiştirir.

[build-system]
requires = ["scikit-build-core", "cmake>=3.15", "setuptools"]
build-backend = "scikit_build_core.build"

[project]
name = "fast-data-lib"
version = "0.1.0"
description = "C uzantıları kullanarak yüksek performanslı veri işleme"
requires-python = ">=3.9"
dependencies = [
    "numpy>=1.24.0",
]

[tool.scikit-build]
cmake.version = "3.20.0"
build.type = "Release"
wheel.install-dir = "fast_data_lib"
# Bu, scikit-build'in tüm uyumlu platformlar için derleme yapmasını söyler
manylinux.manylinux_x86_64 = true

CMake ile C-Uzantısı Yazma

Python yapılandırması ayarlandıktan sonra, CMake kurulumu devreye girer. C kaynaklarını derlemek ve bunları bir Python modülü olarak bağlamak için projemiz kök dizininde bir CMakeLists.txt dosyasına ihtiyacımız var. Scikit-build-core, PYTHON_INCLUDE_DIRS ve PYTHON_LIBRARIES gibi değişkenleri otomatik olarak CMake'a iletir, bu da bağlantı işlemini basitleştirir.

cmake_minimum_required(VERSION 3.20)
project(fast_data_lib C)

# scikit-build-core'un Python yapılandırmasını kullan
include_directories(${PYTHON_INCLUDE_DIRS})

# Uzantı modülünü tanımla
python_add_library(_core MODULE src/my_package/_core.c)

# Standart Python kütüphanelerine bağlan
target_link_libraries(_core ${PYTHON_LIBRARIES})

# Kütüphanenin doğru konuma kurulmasını sağla
set_target_properties(_core PROPERTIES
    LIBRARY_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/src/my_package"
)

Burada, python_add_library komutu, Python yorumlayıcısı ile uyumlu paylaşımlı bir kütüphane (.so Linux'ta, .dll Windows'ta, .dylib macOS'ta) oluşturmayı yöneten CMake tarafından sağlanan yüksek seviyeli bir makrodur. Uzantı adı (_core), Python kodunuzdaki içe aktarma adıyla eşleşmelidir.

Binary Wheel'leri Oluşturma ve Dağıtma

scikit-build-core'un gücü, çeşitli platformlar için wheel'ler oluşturabilme yeteneğinde yatar. Yerel bir wheel oluşturmak için şunu kullanabilirsiniz:

pip wheel . --no-build-isolation

Bununla birlikte, gerçek çapraz platform dağıtımı için, bir CI/CD pipeline'ı (GitHub Actions gibi) içinde çalışan cibuildwheel aracını kullanmanızı öneririz. Desteklenen tüm Python sürümleri boyunca Linux, macOS ve Windows için otomatik olarak wheel'ler oluşturur. Bu wheel'leri PyPI'ye yüklediğinizde, pip kullanıcı makinesi için doğru binary wheel'i akıllıca seçer, böylece yerel olarak hiçbir şey derlemeye gerek kalmaz.

# Örnek .github/workflows/build.yml parçası
jobs:
  build_wheels:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    steps:
      - uses: actions/checkout@v4
      - name: Build wheels
        uses: pypa/cibuildwheel@v2.19
      - uses: pypa/gh-action-pypi-publish@release/v1

Sonuç

Yüksek performanslı veri bilimi kütüphaneleri sunmak, sadece optimize edilmiş algoritmalar gerektirmez; aynı zamanda sağlam bir paketleme stratejisi gerektirir. Eski setup.py betiklerinden scikit-build-core'un modern, beyan edici yaklaşımına geçerek, geliştiriciler C-uzantılarının ve binary wheel'lerin dağıtımını basitleştirebilirler. Bu, kullanıcıların karmaşık yerel derleme ortamlarının sürtünmesi olmadan yerel kodun hız avantajlarından yararlanmasını sağlar. Python ekosistemi gelişmeye devam ettikçe, bu araçları benimsemek sadece en iyi uygulama değil; aynı zamanda yüksek kaliteli, erişilebilir bilimsel yazılımı sürdürmek için bir zorunluluktur.

Share: