Sebagian besar perangkat lunak di Linux berawal dari source code yang harus diterjemahkan menjadi instruksi mesin sebelum dijalankan prosesor. Pekerjaan itu dipegang compiler, sementara build tool menyusun banyak file source menjadi satu hasil akhir secara otomatis. Pada Chapter ini kita memetakan anggota toolchain, membedakan binary hasil kompilasi dari script, lalu melihat bagaimana shell menemukan semuanya lewat variabel PATH.

Empat Penghuni Utama Toolchain #

Untuk bahasa C dan C++, Debian menyediakan toolchain dengan pembagian tugas yang tegas:

KomponenTugas
gcccompiler bahasa C — pintu masuk GNU Compiler Collection
g++compiler bahasa C++ — driver sama plus pustaka C++
makebuild automation berbasis resep di Makefile
ld, ar, asbinutils: linker, archiver, assembler

gcc adalah pengemudi (driver), bukan program tunggal: satu panggilan gcc memerintahkan preprocessor, compiler, assembler, dan linker bekerja bergantian — tahapannya dibedah di Chapter gcc dan g++ . Keempat komponen di atas pun tidak dipasang satu per satu; Debian merangkumnya dalam metapackage build-essential.

Memeriksa Toolchain yang Terpasang #

Sebelum mengompilasi, kita periksa dulu apa yang sudah ada di sistem. Pemeriksaan berikut dijalankan pada mesin uji ber-Debian 13:

bash
which gcc g++ make cc ld ar
gcc --version | head -1
make --version | head -1
dpkg -s build-essential | grep -E "^(Installed-Size|Depends)"

Output yang Dihasilkan:

text
/usr/bin/gcc
/usr/bin/g++
/usr/bin/make
/usr/bin/cc
/usr/bin/ld
/usr/bin/ar
gcc (Debian 14.2.0-19) 14.2.0
GNU Make 4.4.1
Installed-Size: 17
Depends: libc6-dev | libc-dev, gcc (>= 4:14.2), g++ (>= 4:14.2), make, dpkg-dev (>= 1.22.11)

Mari kita bedah hasilnya baris per baris:

  1. which gcc g++ make cc ld ar: lokasi tiap program di PATH. Nama cc adalah sebutan tradisional Unix untuk C compiler — di Debian menunjuk ke gcc; ld dan ar berasal dari binutils.
  2. gcc --version | head -1: compiler versi 14.2.0 pada mesin uji — angka mengikuti rilis distro Anda masing-masing.
  3. make --version | head -1: GNU Make 4.4.1, build automation standar de facto sejak 1980-an.
  4. dpkg -s build-essential | grep ...: baris Depends memperlihatkan isi metapackage ini: libc6-dev, gcc, g++, make, dpkg-dev. Bila perintah menjawab status of build-essential is unknown, obatnya: sudo apt install build-essential.

Rincian opsi ada di gcc(1) dan make(1) .

Biner Kompilasi versus Script #

Binary hasil kompilasi berisi instruksi mesin; script berisi teks yang dibaca interpreter baris demi baris. Perintah file mengenali keduanya dari isi bytenya, bukan dari nama file:

bash
cat > halo.c << 'AKHIR'
#include <stdio.h>

int main(void)
{
    printf("Halo dari C!\n");
    return 0;
}
AKHIR
gcc -Wall -o halo halo.c
./halo
file halo
ldd halo | awk '{print $1}'
stat -c "%n %s" halo halo.c
printf '#!/bin/bash\necho "Halo dari script"\n' > skrip.sh
chmod +x skrip.sh
file skrip.sh
./skrip.sh

Output yang Dihasilkan:

text
Halo dari C!
halo: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=46d351820f649bb12856e6780d41821431c389ea, for GNU/Linux 3.2.0, not stripped
linux-vdso.so.1
libc.so.6
/lib64/ld-linux-x86-64.so.2
halo 15952
halo.c 83
skrip.sh: Bourne-Again shell script, ASCII text executable
Halo dari script

Bedah perintah dan hasilnya:

  1. gcc -Wall -o halo halo.c: mengompilasi halo.c menjadi binary halo; diamnya gcc adalah tanda sukses — tanpa warning, tanpa error.
  2. file halo: mengidentifikasi ELF (Executable and Linkable Format), format executable standar Linux. Dynamically linked berarti binary memanggil pustaka eksternal saat berjalan; deret BuildID adalah sidik jari build yang berbeda di tiap mesin.
  3. ldd halo | awk '{print $1}': mendaftar pustaka dinamis yang dibutuhkan — libc.so.6 plus dynamic linker yang memuatnya ke memori.
  4. stat -c "%n %s" halo halo.c: source 83 byte menjadi binary ribuan byte karena compiler membungkus kode mesin dengan kerangka startup dan tabel ELF.
  5. file skrip.sh: script terdeteksi sebagai teks ASCII berisi perintah bash — tanpa tahap kompilasi. Perintah chmod +x memberi hak eksekusi yang sudah otomatis dimiliki binary; detail hak akses ada di Chapter chmod dan chown .

PATH dan Cara Shell Menemukan Perintah #

Ketika kita mengetik gcc, shell membaca variabel PATH — daftar folder dipisah titik dua — dan memeriksa folder demi folder dari kiri sampai ketemu:

bash
echo $PATH

Output yang Dihasilkan:

text
/usr/local/bin:/usr/bin:/bin

Tampilan di atas adalah PATH minimal lingkungan uji; di desktop biasanya lebih panjang, misalnya menyertakan ~/.local/bin — pembahasan variabel lingkungan ada di Chapter Environment Variables . Dua konsekuensi praktisnya:

  • Perintah ./halo tadi wajib diawali ./ karena direktori kerja tidak termasuk PATH — agar perintah tidak bisa “dibajak” file di folder kerja.
  • Bila dua program bernama sama hidup di dua folder PATH, yang dipakai adalah yang muncul lebih dulu — inilah guna /usr/local/bin di depan /usr/bin agar hasil kompilasi sendiri “menang” tanpa saling menimpa file (lihat Chapter Compiling from Source ).

Paket -dev dan Perpustakaan Header #

Untuk menjalankan program yang memanggil printf cukup package biasa libc6; untuk mengompilasi source-nya, compiler butuh deklarasi fungsi dari header stdio.h — dan header itu dikemas terpisah:

KebutuhanPackage pengisiIsi
Saat program berjalanlibc6pustaka .so yang dimuat dynamic linker
Saat program dikompilasilibc6-devheader .h dan stub untuk linker

Pola ini berulang di seluruh sistem: libssl3 berdampingan dengan libssl-dev, zlib1g dengan zlib1g-dev. Gejala -dev yang belum terpasang sangat khas — kompilasi berhenti dengan fatal error: stdio.h: No such file or directory — dan build-essential sudah menarik libc6-dev untuk kita.

Toolchain yang sehat barulah setengah cerita: kita belum tahu apa yang terjadi di antara gcc dan binary halo, padahal itu kunci membaca kegagalan build. Chapter berikutnya, gcc dan g++, membedah empat tahap kompilasi satu per satu beserta pesan error khasnya.