Chapter sebelumnya berakhir dengan pertanyaan yang belum dijawab: mengapa apt install tidak pernah benar-benar memasang satu package saja? Jawabannya ada pada deklarasi dependensi — metadata yang menyatakan apa yang dibutuhkan sebuah package, apa yang diinginkannya, dan apa yang dilarang baginya. Seluruh deklarasi itu membentuk graf raksasa yang dirayapi resolver sebelum setiap transaksi. Pada Chapter ini kita belajar membaca graf itu dari dua arah: ke depan (package ini membutuhkan apa) dan ke belakang (siapa yang membutuhkan package ini) — keduanya cukup memakai query baca-saja.
Graf Dependensi: Satu Pustaka untuk Semua #
Program di Linux tidak membawa salinan pustakanya sendiri. Satu libc6 melayani hampir seluruh program di sistem, satu libtinfo6 melayani semua software berbasis terminal, dan satu libssl melayani semua yang butuh enkripsi. Tanpa model berbagi ini, setiap package harus memaketkan ratusan megabyte pustaka yang sama — bayangkan berapa kali libc6 terduplikasi pada sistem dengan seribu package. Deklarasi dependensi menjawabnya: setiap package cukup menyatakan kebutuhannya, dan resolver memastikan seluruh graf konsisten — semua kebutuhan terpenuhi, versinya cocok, tanpa konflik. Bentuk graf pada potongan kecil sistem kita misalnya:
Graf sesungguhnya memuat ribuan node, tetapi prinsipnya sama: panah menyatakan “membutuhkan”, dan node yang sama bisa melayani banyak pemakai. Saat kita menghapus salah satu node, semua panah yang menujunya ikut putus — inilah mengapa apt begitu berhati-hati setiap kali kita melepas sesuatu.
Depends, Recommends, dan Suggests #
Kebutuhan itu sendiri berjenjang kekuatan, dan Debian mendefinisikannya dengan istilah yang presisi (rinciannya di Debian Policy bab Relationships ):
| Relasi | Makna | Perilaku default apt |
|---|---|---|
Depends | syarat mutlak agar package berfungsi | wajib dipenuhi |
Pre-Depends | seperti Depends, harus siap sebelum package dibongkar | dipasang paling awal |
Recommends | kuat diinginkan, bukan syarat | ikut dipasang |
Suggests | pelengkap opsional | tidak ikut dipasang |
Breaks | versi tertentu package lain merusaknya | yang dilanggar dinaikkan/dihapus |
Conflicts | tidak boleh hidup bersamaannya | transaksi ditolak |
Replaces | boleh mengambil alih file package lain | file boleh ditimpa |
Provides | menyediakan fasilitas package virtual | bisa memenuhi Depends |
Empat jenjang pertama bisa kita lihat langsung pada package yang paling akrab bagi kita:
apt-cache depends bash | head -8Output yang Dihasilkan:
bash
PreDepends: libc6
PreDepends: libtinfo6
Depends: base-files
Depends: debianutils
Recommends: bash-completion
Suggests: bash-docMari kita baca baris per baris:
- Baris 1 (
bash): judul — nama package yang sedang dibedah. - Baris 2–3 (
PreDepends):libc6danlibtinfo6wajib sudah berada di sistem sebelum filebashdibongkar; jenjang ini dipakai untuk package yang sangat dasar. - Baris 4–5 (
Depends):base-filesdandebianutilsadalah syarat normal — dipasang dalam transaksi yang sama, tanpa syarat urutan khusus. - Baris 6–7 (
RecommendsdanSuggests):bash-completionmembuat pengalaman mengetik lebih nyaman,bash-dochanya dokumentasi — keduanya boleh tidak ada.
Opsi head -8 sengaja memotong daftar karena bash masih punya beberapa relasi lanjutan; jalankan apt-cache depends bash tanpa pemotong untuk daftar penuh. Ringkasan seluruh sub-perintah apt-cache tersedia di apt-cache(8)
.
Reverse Depends: Menelusuri ke Belakang #
Pertanyaan paling sering sebelum melepas sebuah pustaka: siapa saja yang bergantung padanya? apt-cache rdepends menjawab dengan membalik arah panah. Opsi --installed membatasi hasil pada package yang benar-benar terpasang:
apt-cache rdepends --installed debianutils
echo ---
apt-cache rdepends --installed debianutils | tail -n +3 | sort -uOutput yang Dihasilkan:
debianutils
Reverse Depends:
bash
dash
bash
autoconf
---
autoconf
bash
dashBedah dua bentuk output di atas:
- Bentuk mentah:
debianutilsdiikuti empat baris dependen —bash,dash,bash, danautoconf. Namabashmuncul dua kali karena apt menghitung relasi dari versi terpasang sekaligus versi kandidat dari repository; keduanya berbeda di sistem kita. - Bentuk rapat:
tail -n +3membuang dua baris judul, lalusort -umengurutkan sekaligus membuang duplikat — hasilnya daftar bersih tiga nama.
Sebelum menghapus sebuah package, periksa dulu reverse depends-nya. Pertanyaan sebaliknya — “file ini milik package mana?” — sudah kita jawab dengan dpkg -S pada Chapter apt dan dpkg
, dan tetap berguna saat sebuah error menyebut file yang hilang.
Mengapa Package Ini Ada di Sistem #
Saat merapikan sistem kita pasti menemukan package yang tak dikenal. Triasenya dua langkah: periksa penanda manual/auto, lalu periksa kandidat pembersihan:
apt-mark showmanual | head -6
echo ---
apt-get -s autoremove 2>/dev/null | tail -1Output yang Dihasilkan:
antiword
apt-transport-https
bind9-dnsutils
build-essential
ca-certificates
curl
---
0 upgraded, 0 newly installed, 0 to remove and 7 not upgraded.Cara membacanya:
apt-mark showmanual: daftar package yang diminta secara eksplisit —build-essentialdi situ karena memang dipasang sengaja, bukan ditarik orang lain. Package yang tidak muncul di daftar ini hampir pasti datang karena dependensi.apt-get -s autoremove: simulasi pembersihan orphan. Angka0 to removeberarti tidak ada package auto yang kehilangan pemiliknya — sistem kita bersih dari sampah dependensi.- Ekor baris terakhir (
not upgraded) mengingatkan bahwa beberapa package punya versi lebih baru di repository — urusan kita pada Chapter Updating dan Upgrading System .
Konflik, Provides, dan Replaces #
Relasi tidak selalu soal kebutuhan. Kadang sebuah kebutuhan cukup dipenuhi package mana pun yang menyediakan fasilitas itu — dpkg menyebutnya virtual package. Contoh paling jelas ada pada toolchain kompilasi:
apt-cache depends build-essentialOutput yang Dihasilkan:
build-essential
|Depends: libc6-dev
Depends: <libc-dev>
libc6-dev
Depends: gcc
Depends: g++
Depends: make
make-guile
Depends: dpkg-devAda tiga pola menarik di output tersebut:
|Depends: libc6-dev: tanda|menyatakan relasi alternatif —build-essentialmenerimalibc6-devatau relasi pada baris berikutnya.<libc-dev>: nama dalam kurung siku adalah virtual package. Bukan package nyata, melainkan fasilitas; provider-nya ditulis menjorok di bawah (di sini:libc6-dev).Depends: makediikutimake-guile:make-guilemenyediakan fasilitasmakelewat relasi Provides — resolver menerima salah satunya.
Pola Provides + Conflicts + Replaces sering bekerja serentak pada satu skenario klasik: mail server. exim4 dan postfix sama-sama Provides: mail-transport-agent, dan keduanya Conflicts satu sama lain karena memperebutkan port dan tool yang sama — sistem hanya boleh memilih satu, dan package lain yang hanya Depends: mail-transport-agent tetap puas. Replaces muncul ketika versi baru sebuah package mengambil alih file yang dulunya milik package lain — misalnya ketika satu package besar dipecah menjadi beberapa kecil.
Dengan graf yang kini bisa kita baca ke segala arah, pertanyaan berikutnya masuk akal: package-package di graf itu terus diperbarui oleh pengembangnya — bagaimana kita memperbarui seluruh graf dengan aman? Jawabannya adalah ritual update dan upgrade, materi Chapter Updating dan Upgrading System.