Tiga baris CMakeLists.txt pada Chapter CMake cukup untuk satu file, tetapi proyek nyata dibangun dari banyak satuan kerja yang saling berhubungan: aplikasi, pustaka internal, modul tes. Satuan kerja itulah yang di CMake disebut target — dan hampir semua sintaks CMake modern berputar di sekelilingnya: daftar source-nya, properti-nya, dan target lain yang ia butuhkan. Pada Chapter ini kita bangun proyek Kalkulator yang terdiri dari satu library geometri dan satu executable, membahas empat perintah inti yang akan Anda temui di hampir setiap CMakeLists.txt di dunia nyata, dan menjalankan program hasilnya sungguhan.
Target: Satuan Kerja Build #
Target adalah hasil akhir yang ingin dibangun CMake — executable atau library — beserta segala kebutuhannya. Konsep ini pemetaan langsung dari yang sudah kita kerjakan manual: satu target menggantikan satu daftar file .cpp + flag + dependensi yang tadinya Anda tulis di Makefile. Proyek kita punya dua target: library geometri (berisi rumus luas) dan executable kalkulator (program yang memakai library itu). Isi library-nya:
#pragma once
#include <numbers>
// Library mini geometri — header-only: semua fungsi inline di header.
inline double luasPersegi(double sisi) {
return sisi * sisi;
}
inline double luasSegitiga(double alas, double tinggi) {
return alas * tinggi / 2.0;
}
inline double luasLingkaran(double jariJari) {
return std::numbers::pi * jariJari * jariJari;
}Sesuai prinsip Chapter Header dan Source Files, fungsi inline boleh hidup di header — dan itulah pilihan kita di sini: geometri adalah library header-only, tanpa file .cpp sama sekali. CMake punya kategori khusus untuk library seperti ini, yang akan kita lihat sebentar lagi. Program pemakainya sudah diuji di lingkungan praktikum:
#include <iostream>
#include "geometri.h"
int main() {
std::cout << "Luas persegi sisi 7 : " << luasPersegi(7.0) << "\n";
std::cout << "Luas segitiga 6 x 4 : " << luasSegitiga(6.0, 4.0) << "\n";
std::cout << "Luas lingkaran r=7 : " << luasLingkaran(7.0) << "\n";
return 0;
}Output yang Dihasilkan:
Luas persegi sisi 7 : 49
Luas segitiga 6 x 4 : 12
Luas lingkaran r=7 : 153.938add_executable dan add_library #
Berikut CMakeLists.txt proyek kita — empat perintah inti muncul sekali masing-masing:
cmake_minimum_required(VERSION 3.16)
project(Kalkulator LANGUAGES CXX)
## Library header-only: tanpa file .cpp, cukup tahu folder include-nya
add_library(geometri INTERFACE)
target_include_directories(geometri INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
add_executable(kalkulator kalkulator.cpp)
target_link_libraries(kalkulator PRIVATE geometri)
## Properti modern: fitur bahasa dinyatakan per target
target_compile_features(kalkulator PRIVATE cxx_std_23)add_executable(kalkulator kalkulator.cpp) mendeklarasikan target executable beserta source-nya. add_library mendeklarasikan target library — dan jenisnya menentukan bentuk hasil build:
Jenis add_library | Hasil build | Analogi |
|---|---|---|
STATIC | libgeometri.a | Static library (ar) — Chapter Static dan Dynamic Libraries |
SHARED | libgeometri.so | Dynamic library (-shared) |
MODULE | .so yang dimuat manual (plugin) | dlopen, di luar scope course ini |
INTERFACE | Tidak dibangun — hanya antarmuka | Pilihan proyek kita: header-only |
Karena geometri tidak punya file .cpp, kita memilih INTERFACE: CMake tidak mengkompilasi apa pun untuk target ini, ia hanya membawa informasi — folder include — yang diteruskan ke pemakainya.
target_include_directories dan target_link_libraries #
Dua perintah sisanya mengatur hubungan antar target, dan keduanya memakai satu kosa kata penting: PRIVATE / PUBLIC / INTERFACE — untuk siapa properti ini berlaku.
| Keyword | Target itu sendiri | Yang me-link kepadanya |
|---|---|---|
PRIVATE | Ya | Tidak |
PUBLIC | Ya | Ya |
INTERFACE | Tidak (tak punya kode) | Ya |
Dengan tabel itu, seluruh CMakeLists.txt kita bisa dibaca seperti kalimat. target_include_directories(geometri INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) berarti “yang me-link ke geometri boleh meng-include dari folder proyek ini” — persis itulah yang membuat #include "geometri.h" di kalkulator.cpp ditemukan compiler. target_link_libraries(kalkulator PRIVATE geometri) berarti “executable kalkulator butuh geometri untuk dirinya sendiri” — PRIVATE karena tidak ada yang me-link ke executable lagi. Di balik layar, perintah ini yang kelak menyusun flag -I dan -l yang dulu kita tulis manual, dengan urutan yang benar.
target_compile_features(kalkulator PRIVATE cxx_std_23) adalah contoh target property modern: fitur bahasa dinyatakan pada target, bukan lewat flag global. CMake yang menerjemahkannya ke flag compiler yang tepat (-std=c++23 untuk GCC dan Clang, /std:c++latest untuk MSVC) — satu langkah lagi portabilitas yang tidak kita bayar.
Membangun dan Menjalankan #
Alurnya sama persis dengan Chapter CMake — konfigurasi, build, jalankan — karena CMake yang kini menyusun urutan kompilasi dua target secara benar (library dulu, baru executable):
cmake -B build
cmake --build build
./build/kalkulatorPerintah pertama dan kedua dikerjakan CMake; keluaran programnya sudah kita verifikasi di atas. Bila Anda menambah file baru ke library — katakanlah geometri2.h — satu-satunya perubahan yang dibutuhkan adalah menambahkannya ke deklarasi target yang relevan, dan seluruh rantai include serta urutan build tersusun ulang otomatis.
Target dari source sendiri sudah rapi. Persoalan berikutnya: bagaimana bila library yang dibutuhkan bukan milik kita — ada di repositori orang lain, atau terpasang di sistem? Chapter berikutnya membahas tiga jalur resmi CMake untuk menarik dependensi: add_subdirectory, find_package, dan FetchContent.
Referensi: add_executable , add_library , target_link_libraries .