CMake adalah meta-build system yang paling banyak dipakai di komunitas C/C++. Alih-alih menulis Makefile untuk Linux, .vcxproj untuk Windows, dan Xcode project untuk macOS secara terpisah, kita menulis satu CMakeLists.txt dan CMake menghasilkan build files untuk platform target. Bab ini menuntun kita memasang CMake, membuat proyek multi-file pertama, dan menjalankan build out-of-source.

1. Pemasangan CMake #

Linux #

bash
# Debian/Ubuntu
sudo apt install -y cmake

# Fedora
sudo dnf install -y cmake

# Arch
sudo pacman -S --needed cmake

Verifikasi:

bash
cmake --version

Output yang Dihasilkan:

text
cmake version 3.30.4

macOS #

bash
brew install cmake

Atau download dari https://cmake.org/download/ (paket .dmg).

Windows #

  1. Download installer dari https://cmake.org/download/.
  2. Saat instalasi, pilih opsi Add CMake to system PATH.
  3. Verifikasi di PowerShell:
powershell
cmake --version

2. Membuat Struktur Proyek #

Buat folder proyek dengan struktur berikut:

text
mathapp/
├── CMakeLists.txt
├── main.c
├── mathutil.h
└── mathutil.c

File source:

c
/* File: main.c */
#include <stdio.h>
#include "mathutil.h"

int main(void) {
    printf("5 + 3 = %d\n", tambah(5, 3));
    printf("5 * 3 = %d\n", kali(5, 3));
    return 0;
}
c
/* File: mathutil.h */
#ifndef MATHUTIL_H
#define MATHUTIL_H
int tambah(int a, int b);
int kali(int a, int b);
#endif
c
/* File: mathutil.c */
#include "mathutil.h"
int tambah(int a, int b) { return a + b; }
int kali(int a, int b) { return a * b; }

File CMakeLists.txt:

cmake
cmake_minimum_required(VERSION 3.16)
project(mathapp C)

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)

add_executable(mathapp main.c mathutil.c)
target_compile_options(mathapp PRIVATE -Wall -Wextra -g)
target_include_directories(mathapp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})

3. Out-of-Source Build #

CMake modern menganjurkan out-of-source build—artefak build dipisahkan dari source. Keuntungan: source tree tetap bersih, mudah di-clean (cukup hapus folder build/), dan bisa membuat multiple build configuration (Debug, Release, RelWithDebInfo) dari source yang sama.

bash
cd mathapp
mkdir build
cd build
cmake ..
make

Output yang Dihasilkan (langkah cmake .. menghasilkan ringkasan konfigurasi, make menjalankan compiler):

text
-- The C compiler identification is GNU 14.2.0
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/gcc - skipped
-- Configuring done
-- Generating done
-- Build files have been written to: /home/budi/mathapp/build
[ 33%] Building C object CMakeFiles/mathapp.dir/main.c.o
[ 66%] Building C object CMakeFiles/mathapp.dir/mathutil.c.o
[100%] Linking C executable mathapp
[100%] Built target mathapp

Jalankan binary:

bash
./mathapp

Output yang Dihasilkan:

text
5 + 3 = 8
5 * 3 = 15

Mari kita telaah baris-baris CMakeLists.txt di atas:

  1. Baris 1 (cmake_minimum_required(VERSION 3.16)): Wajib di awal. CMake yang lebih tua dari versi ini akan menolak configure.
  2. Baris 2 (project(mathapp C)): Mendeklarasikan nama proyek. Parameter C mengaktifkan compiler C saja—tanpa CXX (C++) yang akan menambah requirement toolchain.
  3. Baris 4-5 (CMAKE_C_STANDARD 11, CMAKE_C_STANDARD_REQUIRED ON): Standar C diatur global. REQUIRED memastikan compiler benar-benar mendukung C11—jika tidak, configure gagal.
  4. Baris 7 (add_executable(mathapp main.c mathutil.c)): Membuat target executable. Nama mathapp menjadi nama binary yang dihasilkan.
  5. Baris 8 (target_compile_options): Flag compiler untuk target ini saja. PRIVATE berarti tidak disebar ke target yang memakai mathapp sebagai library.
  6. Baris 9 (target_include_directories): Tambah include path. ${CMAKE_CURRENT_SOURCE_DIR} adalah direktori tempat CMakeLists.txt berada.

4. Build Type Configuration #

Setiap build type memiliki flag optimasi dan debug berbeda. Pilih saat configure:

bash
# Debug build (optimasi -O0, dengan -g)
cmake -DCMAKE_BUILD_TYPE=Debug ..

make

# Release build (-O3 -DNDEBUG)
cmake -DCMAKE_BUILD_TYPE=Release ..
make

# RelWithDebInfo (-O2 -g -DNDEBUG) - paling populer untuk profiling
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo ..
make

Untuk multi-config generator (Visual Studio, Xcode, Ninja Multi-Config), pilih saat build:

bash
cmake -G "Ninja Multi-Config" ..
cmake --build . --config Release

Bila proyek memakai library eksternal (mis. libm untuk <math.h>):

cmake
cmake_minimum_required(VERSION 3.16)
project(mathapp C)

set(CMAKE_C_STANDARD 11)

add_executable(mathapp main.c mathutil.c)
target_compile_options(mathapp PRIVATE -Wall -Wextra -g)

# Link libm
target_link_libraries(mathapp PRIVATE m)

# Atau pakai find_library (lebih portable)
# find_library(MATH_LIB m)
# target_link_libraries(mathapp PRIVATE ${MATH_LIB})

6. Struktur Proyek Besar #

Untuk proyek dengan banyak file dan sub-direktori, pisahkan ke subfolder src/, include/, dan tests/:

text
myproject/
├── CMakeLists.txt          # Top-level
├── include/
│   └── myproject/
│       └── mathutil.h
├── src/
│   ├── CMakeLists.txt
│   ├── main.c
│   └── mathutil.c
└── tests/
    ├── CMakeLists.txt
    └── test_mathutil.c

CMakeLists.txt top-level:

cmake
cmake_minimum_required(VERSION 3.16)
project(myproject C)

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)

add_subdirectory(src)
enable_testing()
add_subdirectory(tests)

src/CMakeLists.txt:

cmake
add_executable(myapp main.c mathutil.c)
target_include_directories(myapp PUBLIC
    ${CMAKE_SOURCE_DIR}/include
)
target_compile_options(myapp PRIVATE -Wall -Wextra -g)

tests/CMakeLists.txt:

cmake
add_executable(test_mathutil test_mathutil.c)
target_link_libraries(test_mathutil PRIVATE myapp_lib)
add_test(NAME test_mathutil COMMAND test_mathutil)

Jalankan test:

bash
cd build
cmake ..
make
ctest --output-on-failure

7. Compile Commands JSON #

CMake dapat menghasilkan compile_commands.json yang dipakai editor (VS Code, CLion, clangd) untuk IntelliSense akurat.

bash
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..

Atau tambahkan ke CMakeLists.txt:

cmake
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

File compile_commands.json dihasilkan di folder build/. Buat symlink di root proyek agar editor dapat menemukan:

bash
ln -s build/compile_commands.json .

8. Troubleshooting #

CMake Error: Could not find CMAKE_C_COMPILER #

Compiler belum terpasang atau tidak ada di PATH. Pasang toolchain (lihat bab Setup Linux / Setup Windows / Setup macOS). Bila memakai compiler khusus, set secara eksplisit:

bash
cmake -DCMAKE_C_COMPILER=/usr/bin/gcc-14 ..

ninja: error: loading 'build.ninja' #

CMake menggunakan generator Ninja secara default bila terpasang. Pastikan ninja terinstal atau pakai Makefiles:

bash
cmake -G "Unix Makefiles" ..

Cache corrupt setelah ganti compiler #

CMake menyimpan path compiler di CMakeCache.txt. Bila compiler berubah (mis. dari GCC ke Clang), hapus cache dan re-configure:

bash
rm -rf build/
mkdir build && cd build
cmake -DCMAKE_C_COMPILER=clang ..

error: 'target_compile_options' without target #

Perintah target_* harus dipanggil setelah add_executable/add_library mendefinisikan target. Periksa urutan baris di CMakeLists.txt.

Build lambat di Windows WSL #

Pastikan folder proyek berada di filesystem Linux (~/), bukan di /mnt/c/. Lihat bab Setup WSL untuk detail.