Episode ini membahas pengembangan lintas platform: menulis kode portabel untuk Windows, Linux, dan macOS, abstraksi platform-specific dengan conditional compilation, cross-compilation untuk target arsitektur berbeda, serta portabilitas library dan dependency.

Aplikasi modern jarang hidup di satu platform. Sebuah layanan bisa berjalan di Linux server, client desktop di Windows dan macOS, hingga perangkat mobile. C++ sangat cocok untuk portabilitas — standard library-nya sama di semua platform — tetapi tetap ada area yang berbeda: file system, jaringan, dan threading.
Episode 20 mengajarkan cara menulis C++ yang berjalan di banyak platform: prinsip portabilitas, conditional compilation untuk kode spesifik platform, cross-compilation untuk menargetkan arsitektur berbeda, serta memilih library dan dependency yang vendor-neutral agar tidak terkunci pada satu ekosistem.
Langkah pertama menuju portabilitas: gunakan standard library sebanyak mungkin. std::filesystem, std::thread, dan std::string bekerja identik di GCC, Clang, dan MSVC. Perbedaan muncul saat memakai API sistem operasi seperti fork (Linux) atau Winsock (Windows) — batasi API tersebut ke dalam lapisan abstraksi tipis.
Kontrak implisit juga perlu diperhatikan: ukuran int umumnya 4 byte, tetapi long berbeda di Windows (4 byte) dan Linux 64-bit (8 byte). Untuk data biner, gunakan tipe eksplisit std::int32_t dari <cstdint> agar ukurannya pasti di semua platform:
cat > portabel.cpp <<'EOF'
#include <cstdint>
#include <iostream>
int main() {
std::int32_t nilai = 100000;
std::int64_t besar = 5000000000LL;
std::cout << sizeof(nilai) << " " << sizeof(besar) << "\n";
}
EOF
g++ -std=c++20 portabel.cpp -o portabel
./portabelstd::int32_t dan std::int64_t menjamin ukuran byte yang sama di setiap platform — krusial untuk file biner dan protokol jaringan yang dibahas di episode 9 dan 13.
Hal kecil yang sering menjebak: baris baru di file teks Windows adalah \r\n sedangkan di Linux \n; path memakai \ di Windows dan / di Linux; dan beberapa fungsi threading berperilaku sedikit berbeda. Pakai std::filesystem::path untuk menangani path, dan buka file teks dengan mode yang sesuai bila perlu.
Compiler mendefinisikan makro platform: _WIN32 di Windows, __linux__ di Linux, __APPLE__ di macOS. Conditional compilation memilih kode yang tepat saat preprocessing:
cat > platform.cpp <<'EOF'
#include <iostream>
#ifdef _WIN32
const char* SO = "Windows";
#elif defined(__APPLE__)
const char* SO = "macOS";
#elif defined(__linux__)
const char* SO = "Linux";
#else
const char* SO = "Unknown";
#endif
int main() {
std::cout << "Sistem operasi: " << SO << "\n";
}
EOF
g++ -std=c++20 platform.cpp -o platform
./platformBlok #ifdef _WIN32 diproses hanya di Windows, #elif defined(__APPLE__) hanya di macOS. Compiler menolak kode di cabang yang tidak aktif — sehingga error kode platform lain baru muncul saat membangun di platform tersebut. CI matriks build di episode 19 menangkap ini lebih awal.
Conditional compilation menyebar di banyak #ifdef membuat kode sulit dibaca. Batasi ke dalam satu lapisan abstraksi: sebuah header yang mengekspor fungsi netral platform, dan di belakangnya beberapa file implementasi yang dipilih build system. CMake memilih file sesuai platform dengan if(WIN32) dan if(UNIX) — lebih bersih daripada makro di mana-mana.
Cross compilation membangun executable untuk platform atau arsitektur berbeda dari mesin pembangun — misalnya membangun binary ARM untuk Raspberry Pi di mesin x86. Kunci utamanya adalah toolchain: compiler, library, dan header untuk target. Dengan CMake:
cat > toolchain-arm.cmake <<'EOF'
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)
EOF
cmake -S . -B build-arm \
-DCMAKE_TOOLCHAIN_FILE=toolchain-arm.cmake
cmake --build build-armset(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++) memakai compiler ARM untuk menghasilkan binary ARM, dan CMAKE_TOOLCHAIN_FILE memberi tahu CMake seluruh pengaturan target. Binary hasilnya dijalankan di perangkat ARM, bukan di mesin pembangun.
Cross compilation menuntut pustaka untuk target dipasang terpisah — library x86 tidak bisa dipakai untuk build ARM. Gunakan sysroot, direktori yang berisi file sistem target. Docker dan container sangat membantu di sini: jalankan build di image dengan toolchain target terpasang.
Memilih library yang portabel menentukan seberapa mudah kode berpindah platform. Standard library dan library header-only seperti nlohmann/json hampir selalu portabel. Library yang bergantung pada API OS tertentu perlu diperiksa dukungan platformnya. Boost dan asio mendukung Windows, Linux, dan macOS secara luas.
Abstraction libraries menyembunyikan perbedaan platform di balik satu API: fmt untuk pemformatan, spdlog untuk logging, dan GoogleTest untuk pengujian. Semua portabel dan vendor-neutral — tidak mengikat kalian pada ekosistem compiler tertentu:
set(CMAKE_CXX_STANDARD 20)
find_package(fmt CONFIG REQUIRED)
target_link_libraries(app PRIVATE fmt::fmt)find_package(fmt CONFIG REQUIRED) mencari library fmt terpasang, dan target_link_libraries(app PRIVATE fmt::fmt) menghubungkannya. Alih-alih menulis sendiri, memakai library portabel yang sudah diuji di banyak platform mengurangi beban pemeliharaan secara drastis.
Tip
Aturan umum: kode aplikasi harus bebas dari #ifdef _WIN32. Semua perbedaan platform disembunyikan di library atau lapisan abstraksi, sehingga logika bisnis tetap satu source of truth.
Inti yang harus dibawa pulang:
<cstdint> seperti std::int32_t menjamin ukuran tetap di semua platform._WIN32, __linux__, dan __APPLE__ memilih kode saat preprocessing.#ifdef tersebar.Di episode 21 selanjutnya kita akan membahas embedded dan high-performance systems — C++ untuk embedded dan real-time applications, kendala memori dan perilaku deterministik dengan integrasi RTOS, profiling kode embedded dan optimasi tingkat rendah, serta deployment untuk firmware dan hardware.