glibc ABI Uyumluluğu ve Eski RHEL Sistemleri
Yeni bir Linux dağıtımında derlenen ikili dosyanın eski RHEL üzerinde GLIBC_x.y not found ile çalışmaması çoğu zaman paket eksikliği değil, derleme-time ABI taban çizgisi problemidir.
Geliştirici makinesinde sorunsuz çalışan bir ikili dosyayı eski bir RHEL sunucuya kopyaladığınızda tek satırlık bir hata bütün dağıtımı bitirebilir:
version 'GLIBC_2.xx' not found
Bu hata bana göre Linux dağıtım tarafındaki en öğretici örneklerden biridir. Kaynak kodunuzda yeni bir API kullanmamış olabilirsiniz. Derleyici aynı olabilir. Yine de derleme aldığınız ortam ikili dosyanın çalışabileceği en eski kullanıcı alanını fiilen belirler.
RHEL tabanlı kapalı ve uzun ömürlü sistemlerde çalışırken bunu "sunucuda eksik paket var" şeklinde okumak yerine ELF ve ABI seviyesinde ele almak gerekir.
glibc neden yalnız bir paylaşılan kütüphane değildir?
Linux uygulamalarının önemli bölümü libc.so.6 üzerinden glibc'ye bağlanır. Ancak dinamik bağlayıcı yalnız fonksiyon adına bakmaz. glibc sembol sürümleme kullanır.
İkili dosya içinde örneğin memcpy@GLIBC_2.14 benzeri bağımlılıklar oluşabilir. Hedef sistemde memcpy fonksiyonu bulunması tek başına yeterli değildir. İstenen sembol sürümü da bulunmalıdır.
readelf --version-info ve objdump -T bu yüzden dağıtım incelemesinde değerlidir. Uygulamanın "glibc 2.x kullanıyor" demesi yerine hangi sembollerin hangi minimum sürümü istediğini görmek mümkündür.
Yeni sistemde derleme almak taban çizgisini yükseltir
Güncel bir Ubuntu veya Fedora üzerinde derlenen çalıştırılabilir dosya, araç zinciri ve bağlanan sistem kütüphaneleri üzerinden yeni sembol sürümlerine bağlanabilir.
Kaynak kodu eski API'lerle sınırlamak bunu otomatik olarak engellemez. Derleyicinin ürettiği çağrılar, başlangıç nesneleri veya transitif yerel bağımlılık yeni glibc sembolleri getirebilir.
Bu nedenle "C++17 kullandım ama eski RHEL'de niye çalışmıyor?" sorusunun cevabı çoğu zaman dil standardında değildir. Dil standardı ile çalışma zamanı ABI farklı katmanlardır.
En güvenli yöntem: en eski hedefte derleme
Backward uyumluluk yönü önemlidir. Eski glibc üzerinde derlenen ikili dosyanın daha yeni glibc üzerinde çalışma ihtimali yüksektir; ters yön garanti değildir.
Bu yüzden desteklenen en eski Linux dağıtımı derleme baseline olarak seçilebilir.
Ben üretim hedefi eski RHEL olduğunda derleme konteyner veya CI imajının da o uyumluluk tabanını temsil etmesini tercih ederim. Geliştirici makinesindeki güncel dağıtım üzerinden sürüm üretmek kolaydır fakat dağıtım sürprizlerini artırır.
Burada konteyner hedef çalışma zamanının yerini tutmaz; derleme araç zincirini tekrarlanabilir hale getirir.
Sysroot ile kontrollü çapraz derleme
Fiziksel veya virtual eski sistemde derleme almak her zaman pratik değildir. Alternatif olarak eski kullanıcı alanı başlık ve library'lerini içeren bir sysroot kullanılabilir.
Derleyici/bağlayıcı hedef glibc başlık'ları, başlangıç nesneleri, dynamic loader sözleşmesi ve hedef libstdc++/libgcc sürümlerine kontrollü biçimde yönlendirilir.
Bu yöntem yalnız -I ile eski başlık göstermekten daha kapsamlıdır. Yanlışlıkla host /usr/lib altındaki güncel library'nin link'e girmesi ABI tabanını tekrar yükseltebilir.
Derleme log'unda gerçek bağlayıcı command line'ını görmek bu nedenle değerlidir.
Sorun yalnız glibc değildir
C++ uygulamalarında GLIBCXX_x.y ve CXXABI_x.y bağımlılıkları da ortaya çıkar. Bunlar libstdc++ tarafındadır.
Bir native çalıştırılabilir dosya için uyumluluk matrisi en az kernel syscall beklentileri, glibc, dynamic loader, libstdc++, libgcc, transitif native library'ler ve CPU instruction set'i katmanlarını içerir.
Son madde özellikle -march=native kullanıldığında önemlidir. Binary glibc açısından uyumlu olsa bile derleme makinesindeki AVX2/AVX-512 instruction'larını içerebilir ve eski CPU'da illegal instruction ile düşebilir.
Statik glibc linklemek neden sihirli çözüm değildir?
İlk refleks -static olabilir. glibc ile tamamen statik linkleme DNS/NSS, locale ve bazı sistem entegrasyonları nedeniyle beklenmeyen davranışlar üretebilir. Ayrıca güvenlik güncellemesi paylaşılan kütüphane değiştirilerek otomatik alınamaz; ikili dosya yeniden derleme edilmelidir.
Musl gibi farklı libc ile statik dağıtım ayrı bir stratejidir, fakat uygulamanın ve yerel bağımlılık'lerin buna uygun olması gerekir.
"Statik linkledim, uyumluluk bitti" genellemesi güvenli değildir.
Java uygulaması da native dünyadan kaçamaz
Saf Java bytecode glibc'ye doğrudan link edilmiyor gibi görünür. Fakat JVM'nin kendisi native çalıştırılabilir dosyadır. JNI library'leri, compression codec'leri, database driver'ın native bileşenleri veya ML çalışma zamanları ayrıca ABI bağımlılığı getirebilir.
Özellikle AI çıkarım tarafında ONNX Çalışma zamanı, CTranslate2, CUDA çalışma zamanı veya özel C/C++ library kullanıldığında dağıtım matrisi tekrar native seviyeye iner.
Bu nedenle JAR'ın Java sürümünü bilmek tek başına yeterli değildir.
Release doğrulamasına ABI kontrolü eklemek
Ben eski Linux hedefleri olan projelerde release artifact'ına readelf -V, objdump -T, ldd --version, ldd ve readelf -l kontrollerini eklemeyi değerli buluyorum.
Ayrıca temiz hedef image üzerinde smoke test yapılmalıdır. Derleme makinesinde test etmek dependency leakage'i gizleyebilir.
Artifact'ın minimum desteklenen distribution üzerinde başlatılması, teorik uyumluluk yorumundan daha güçlü kanıttır.
ABI taban çizgisi bir proje gereksinimidir
"Linux destekleniyor" ifadesi üretim sistemi için yetersizdir. Hangi distribution ailesi, hangi minimum glibc, hangi CPU ISA ve hangi kernel tabanı destekleniyor açık olmalıdır.
Bu bilgi dokümantasyon ayrıntısı değil, derleme kararını belirleyen gereksinimdir.
Eski RHEL gibi uzun ömürlü sistemlerde doğru yaklaşım hedefi güncellemeye zorlamak değilse, derleme ortamını hedefin ABI sınırlarına göre kurmaktır. Binary uyumluluk problemi dağıtım sonunda değil, araç zinciri seçilirken çözülmelidir.
Kaynakça
- GNU Project. GNU Binary Utilities: readelf. https://sourceware.org/binutils/docs/binutils/
- GNU Project. The GNU C Library Reference Manual. https://sourceware.org/glibc/manual/
- Red Hat. Red Hat Enterprise Linux 10: Application Compatibility Guide. 2025. https://access.redhat.com/articles/rhel10-abi-compatibility