Kompilasi silang

Platform target, optimasi, dan build rilis.

Daftar isi

Compiler Odin dapat menghasilkan binari untuk sistem operasi dan arsitektur lain dari kode sumber yang sama, kemampuan yang disebut kompilasi silang (cross-compilation). Topik ini membahas pemilihan target melalui flag -target, pembuatan modul WebAssembly, syarat membangun untuk Windows, serta tingkat optimasi yang menentukan ukuran binari. Seluruh perintah dijalankan terhadap satu program statistik nilai ujian yang kecil, sehingga setiap angka target dan ukuran pada halaman ini dapat diulang dari berkas yang sama.

Bahan uji seluruh bagian berikutnya adalah program statistik sederhana berikut.

odin main.odin
package main

import "core:fmt"

// menjumlahkan seluruh nilai pada slice
hitung_total :: proc(nilai: []int) -> (total: int) {
	for v in nilai {
		total += v
	}
	return
}

main :: proc() {
	nilai := []int{75, 80, 90, 65, 88}
	total := hitung_total(nilai)
	rata_rata := f64(total) / f64(len(nilai))
	fmt.printfln("Target: %v / %v", ODIN_OS, ODIN_ARCH)
	fmt.println("Nilai ujian:", nilai)
	fmt.printfln("Total: %v", total)
	fmt.printfln("Rata-rata: %.2f", rata_rata)
}
bash
# jalankan program langsung dari sumbernya
odin run main.odin -file
text Keluaran
Target: Linux / amd64
Nilai ujian: [75, 80, 90, 65, 88]
Total: 398
Rata-rata: 79.60

Target lintas platform#

Flag -target pada odin build menentukan sistem operasi dan arsitektur tempat binari akhir berjalan. Daftar lengkapnya dapat diminta kepada compiler dengan memberi tanda tanya sebagai nilai flag tersebut.

bash
# tampilkan seluruh target yang didukung compiler
odin build . -target:"?"
text Keluaran
All supported targets:
	darwin_amd64
	darwin_arm64
	linux_i386
	linux_amd64
	linux_arm64
	linux_arm32
	linux_riscv64
	windows_i386
	windows_amd64
	freebsd_i386
	freebsd_amd64
	freebsd_arm64
	netbsd_amd64
	netbsd_arm64
	openbsd_amd64
	freestanding_wasm32
	wasi_wasm32
	js_wasm32
	orca_wasm32
	freestanding_wasm64p32
	js_wasm64p32
	wasi_wasm64p32
	freestanding_amd64_sysv
	freestanding_amd64_win64
	freestanding_amd64_mingw
	freestanding_arm64
	freestanding_arm32
	freestanding_riscv64

Daftar di atas mencakup tiga sistem operasi desktop, tiga varian BSD, keluarga WebAssembly, serta target freestanding, yaitu target tanpa sistem operasi. Untuk pekerjaan sehari-hari, hanya sebagian kecil dari daftar itu yang paling sering muncul, yaitu linux_amd64, linux_arm64, darwin_arm64, windows_amd64, dan tiga varian wasm32 yang dibahas pada bagian berikutnya.

Tanpa flag -target, compiler menggunakan mesin tempat build dijalankan sebagai target, sehingga odin build . di sandbox ini menghasilkan binari Linux amd64. Nama keluaran bawaannya diambil dari nama folder topik, yaitu kompilasi-silang, dan flag -out: menggantinya. Ukuran binari di bawah ditampilkan dalam byte, sedangkan kolom tanggal pada ls -la disaring dengan awk karena berubah setiap kali build diulang.

bash
# bangun program untuk mesin yang sedang dipakai
odin build . -target:linux_amd64
# tampilkan ukuran binari dalam byte
ls -la kompilasi-silang | awk '{print $5, $9}'
text Keluaran
391472 kompilasi-silang

Kompilasi silang pada Odin berjalan dalam dua tahap, yaitu generasi kode oleh LLVM dan pengaitan berkas objek oleh linker, program yang menggabungkan berkas objek menjadi binari utuh. Generasi kode lintas target berjalan tanpa kendala, tetapi tahap linker bergantung pada alat yang tersedia di sistem. Hasil uji di sandbox ini menunjukkan kedua kasus: linux_amd64 lulus penuh, sedangkan darwin_arm64 dihentikan compiler sebelum tahap linker dijalankan.

bash
# coba target macOS ARM64
odin build . -target:darwin_arm64
text Keluaran
Linking for cross compilation for this platform is not yet supported (darwin arm64)

Untuk linux_arm64, generasi kode selesai tetapi linker sistem, GNU ld, menolak berkas objek ARM64 dengan pesan Relocations in generic ELF dan file in wrong format. Pada lingkungan kerja nyata, kasus seperti ini diselesaikan dengan memasang toolchain silang yang sesuai, misalnya lld yang dikonfigurasi untuk arsitektur tujuan. Di sandbox ini, kelompok target yang dapat dibangun penuh adalah varian WebAssembly, dan itulah yang dipakai pada bagian berikutnya.

Membangun untuk WebAssembly#

Dua target WebAssembly yang paling praktis adalah js_wasm32 untuk halaman web dan wasi_wasm32 untuk lingkungan yang mengikuti WASI (WebAssembly System Interface), antarmuka sistem standar untuk menjalankan WebAssembly di luar browser. Keduanya dihasilkan dengan perintah build yang sama, dan nama keluarannya adalah nama folder yang diberi akhiran .wasm.

bash
# bangun modul WebAssembly untuk runtime JavaScript
odin build . -target:js_wasm32
# periksa jenis berkas yang dihasilkan
file kompilasi-silang.wasm
text Keluaran
kompilasi-silang.wasm: WebAssembly (wasm) binary module version 0x1 (MVP)

Berkas yang dihasilkan berukuran 314352 byte, sekitar 307 KB, dan file mengenalinya sebagai modul WebAssembly versi MVP. Nama yang sama dipakai oleh target berikutnya, sehingga membangun wasi_wasm32 sesudahnya akan menimpa berkas tersebut. Flag -out: dengan nama yang berbeda mencegah penimpaan ini bila kedua target perlu dipertahankan sekaligus.

Untuk pengujian dari terminal, wasi_wasm32 adalah pilihan yang lebih mudah karena Node.js menyertakan implementasi WASI. Berkas pembungkus berikut membuat instance WebAssembly dengan API WASI milik Node, lalu menjalankannya.

js jalankan-wasi.js
// tidak-dijalankan
// pembungkus Node WASI untuk menjalankan berkas .wasm hasil wasi_wasm32
const { WASI } = require("node:wasi");
const fs = require("node:fs");

const wasmPath = process.argv[2] ?? "kompilasi-silang.wasm";
const wasi = new WASI({ version: "preview1" });
const wasm = new WebAssembly.Module(fs.readFileSync(wasmPath));
const inst = new WebAssembly.Instance(wasm, wasi.getImportObject());
wasi.start(inst);
bash
# bangun modul WebAssembly System Interface
odin build . -target:wasi_wasm32
# jalankan modul wasm melalui pembungkus Node
node --no-warnings jalankan-wasi.js
text Keluaran
Target: WASI / wasm32
Nilai ujian: [75, 80, 90, 65, 88]
Total: 398
Rata-rata: 79.60

Baris pertama keluaran menunjukkan manfaat konstanta ODIN_OS dan ODIN_ARCH: kode sumber yang sama melaporkan target yang berbeda pada Linux dan di dalam Node. Flag --no-warnings hanya menyembunyikan ExperimentalWarning yang dicetak Node ke stderr karena API WASI-nya masih berstatus eksperimental, sehingga keluaran program terlihat bersih. Ukuran modulnya 344211 byte, sedikit lebih besar daripada varian js karena runtime yang ditautkan berbeda.

Target ketiga, freestanding_wasm32, gagal untuk program ini, dan compiler menjawab dengan Error: 'println' is not declared by 'fmt'. Target freestanding bekerja tanpa sistem operasi, sehingga proc cetak konsol yang bergantung pada stdout tidak dideklarasikan oleh pustaka core:fmt. Program untuk target ini berkomunikasi dengan host melalui mekanisme yang ditetapkan oleh lingkungannya sendiri, bukan melalui konsol sistem operasi, dan perinciannya berada di luar lingkup topik ini.

Target Windows membutuhkan Windows SDK#

Membangun untuk Windows dari Linux gagal dengan pesan yang menunjuk Windows SDK, bukan dengan pesan kesalahan kode.

bash
# cobalah membangun untuk Windows tanpa Windows SDK
odin build . -target:windows_amd64
text Keluaran
-windows-sdk-root:<path> must be used to target Windows

Binari Windows dibangun dalam format PE (Portable Executable) dan ditautkan dengan pustaka sistem Windows, sehingga compiler membutuhkan Windows SDK, yaitu kumpulan header dan pustaka resmi Microsoft untuk pengembangan aplikasi Windows. SDK berisi pustaka impor sistem Windows, misalnya untuk kernel32 dan user32, yang menjadi pasangan bagi panggilan sistem pada runtime Odin untuk Windows. Bantuan compiler menjelaskan syaratnya: flag -windows-sdk-root:<path> harus menunjuk folder SDK tersebut, disertai flag -linker:lld dan pemasangan lld-link. Apabila ketiganya tersedia, perintah yang sama menghasilkan berkas .exe, dan kondisi itu tidak dapat direproduksi di sandbox sehingga tidak ditunjukkan di sini.

Pesan seperti ini menunjuk prasyarat lingkungan, bukan kesalahan kode. Ia muncul sebelum kompilasi dimulai, sehingga tidak ada binari setengah jadi yang perlu dibersihkan. Untuk proyek yang benar-benar menyasar Windows dari mesin Linux, folder SDK cukup disiapkan sekali di awal, kemudian ketiga flag tersebut diikat pada skrip build proyek agar tidak perlu dicari ulang. Memeriksa syarat target sebelum membangun lebih menghemat waktu daripada menafsirkan pesan tersebut sebagai bug.

Tingkat optimasi dan ukuran binari#

Flag -o mengatur seberapa keras compiler mengoptimalkan program. Bantuan odin build mencantumkan lima tingkat, yaitu -o:none, -o:minimal, -o:size, -o:speed, dan -o:aggressive, dengan -o:minimal sebagai nilai bawaan. Lima variasi berikut dibangun satu per satu dengan nama keluaran yang berbeda agar saling tidak menimpa.

bash
# bangun lima variasi build dengan nama keluaran yang berbeda
odin build . -o:none -out:ujian-none
odin build . -o:minimal -out:ujian-minimal
odin build . -o:size -out:ujian-size
odin build . -o:speed -out:ujian-speed
odin build . -debug -out:ujian-debug
# tampilkan ukuran setiap binari dalam byte
ls -la ujian-none ujian-minimal ujian-size ujian-speed ujian-debug | awk '{print $5, $9}'
text Keluaran
863856 ujian-debug
391344 ujian-minimal
460928 ujian-none
212264 ujian-size
235736 ujian-speed

Ukuran setiap variasi dirangkum pada tabel berikut.

TingkatUkuran (byte)
-o:none460928
-o:minimal391344
-o:size212264
-o:speed235736
-debug863856

Angka pada tabel memperlihatkan pola yang wajar. -o:none tidak mengoptimalkan apa pun dan menghasilkan binari terbesar di antara keempat tingkat biasa, sedangkan -o:minimal yang menjadi nilai bawaan sudah memangkasnya sekitar lima belas persen. Tingkat -o:size memangkas ukuran menjadi sekitar 207 KB karena tujuannya memperkecil berkas yang diserahkan atau diunduh, sedangkan -o:speed sedikit lebih besar karena menyusun kode demi kecepatan eksekusi, bukan demi ukuran.

Flag -debug menghasilkan binari terbesar, sekitar 844 KB, karena menyertakan informasi debugger dan menurunkan optimasi ke -o:none. Meski ukurannya berbeda, kelima binari mencetak keluaran yang sama persis. Perbedaannya terletak pada ukuran, kecepatan eksekusi, dan kemudahan pemeriksaan, bukan pada hasil program. Tingkat -o:aggressive juga tersedia, dan bantuan compiler sendiri melabelinya dengan peringatan agar digunakan dengan hati-hati.

Build rilis dan build debug#

Build rilis (release) adalah binari yang diserahkan kepada pengguna akhir, sedangkan build debug adalah binari yang dipakai ketika mencari penyebab error pada waktu pengembangan. Keduanya dibangun dari kode sumber yang sama, dan pilihannya sepenuhnya ditentukan oleh flag compiler.

Pada lini dev-2026-10, odin build tidak memiliki flag -release, sehingga build rilis diperoleh melalui tingkat optimasi, lazimnya -o:speed, atau -o:size apabila ukuran lebih penting. Build debug dibangun dengan flag -debug, yang menetapkan optimasi ke -o:none, menyertakan informasi debugger, dan menetapkan konstanta ODIN_DEBUG menjadi true. Praktisnya, build debug mempertahankan pemeriksaan runtime dan pemetaan antara binari dan baris kode, sehingga pesan error dan debugger dapat menunjuk sumber persisnya. Konsekuensinya, ukuran binari paling besar dan eksekusi lebih lambat.

Konstanta ODIN_DEBUG juga dapat dibaca oleh kode, sehingga bagian program yang hanya relevan saat pengembangan dapat dipisahkan pada waktu kompilasi.

odin Contoh: kode yang menyadari mode build
// tidak-dijalankan
when ODIN_DEBUG {
	fmt.println("mode debug")
} else {
	fmt.println("mode rilis")
}

Apabila dijalankan tanpa flag, program dengan cabang di atas mencetak mode rilis, sedangkan -debug membuatnya mencetak mode debug. Kebiasaan yang sehat adalah mengembangkan dan menguji dalam mode debug, lalu membangun rilis dengan -o:speed ketika program siap diserahkan, karena pemeriksaan runtime yang utuh paling berguna ketika program belum selesai. Bila ukuran atau kecepatan rilis masih belum memenuhi kebutuhan, flag seperti -disable-assert menyingkirkan pemeriksaan assert dari binari, dengan konsekuensi berkurangnya jaring pengaman pada runtime.

Ringkasan#

  • Flag -target memilih sistem operasi dan arsitektur tujuan, odin build . -target:"?" mencantumkan seluruhnya, dan -out: menamai keluaran agar tidak tertimpa build berikutnya.
  • js_wasm32 menghasilkan modul WebAssembly untuk browser dengan runtime odin.js, sedangkan wasi_wasm32 dapat dijalankan dari terminal melalui API WASI milik Node.js.
  • windows_amd64 menuntut Windows SDK melalui -windows-sdk-root, disertai -linker:lld dan lld-link, sebelum dapat dibangun dari Linux.
  • -o:minimal adalah tingkat optimasi bawaan, -o:size menghasilkan binari terkecil, -o:speed menjadi dasar build rilis, dan -debug menghasilkan binari terbesar beserta konstanta ODIN_DEBUG.

Referensi#