Paket Yönetimi: Conan ve vcpkg
Bir aşçı düşün. Her yemeği sıfırdan yapabilir — unu öğütebilir, domatesi tarladan toplayabilir, tuzu denizden çıkarabilir. Ama pratikte kimse bunu yapmaz. Marketten un, domates, tuz alırsın ve asıl işine odaklanırsın: yemek pişirmeye. Yazılım da öyle. JSON parse etmek, HTTP request atmak, log yazmak gibi "temel malzemeleri" her projede sıfırdan yazmak anlamsız. Bunun yerine test edilmiş, olgunlaşmış kütüphaneleri kullanırsın.
Python'da pip install, JavaScript'te npm install, Java'da Maven <dependency> yazarsın ve iş biter. Ama C++ dünyasında bu uzun süre bu kadar kolay olmadı. Standart bir paket yöneticisi yoktu. Kütüphane eklemek, kaynak kodu indirmek, derlemek, bağlamak, header yollarını ayarlamak gibi zahmetli adımlar gerektiriyordu. Bu durum Conan ve vcpkg ile değişti. Bu derste her iki aracı öğrenecek, CMake entegrasyonlarını görecek ve hangisinin ne zaman daha uygun olduğunu tartışacağız.
Neden Paket Yönetimi Lazım?
find_package Yetmez
CMake'in find_package() komutu sisteme kurulu kütüphaneleri bulur:
find_package(Boost REQUIRED COMPONENTS filesystem)
target_link_libraries(myapp Boost::filesystem)Ama sorunlar var:
Kütüphane sisteme kurulu olmalı: Yeni bir geliştirici projeyi klonladığında, önce tüm bağımlılıkları elle kurmalı
Versiyon kontrolü zor: Sistem genelinde tek bir versiyon var. Proje A boost 1.80, Proje B boost 1.82 istiyorsa?
Platform farklılıkları: Ubuntu'da
apt install libboost-dev, macOS'tabrew install boost, Windows'ta... iyi şanslarReproducible build imkansız: "Bende çalışıyor" sendromu
Paket yöneticileri bu sorunları çözer: bağımlılıkları proje seviyesinde tanımlar, otomatik indirir, derler, doğru versiyonu garanti eder ve her platformda aynı şekilde çalışır.
Conan — Decentralized C++ Package Manager
Conan, Python tabanlı, platform bağımsız bir paket yöneticisidir. JFrog tarafından geliştirilir. Kendi sunucunu kurabilir, özel paketler oluşturabilirsin. 2.0 versiyonuyla büyük bir modernizasyon geçirdi.
Kurulum
pip install conan
conan --version # Conan version 2.x.xİlk kullanımda default profile oluştur:
conan profile detect
# Otomatik olarak OS, compiler, arch bilgilerini algılarProfile'ı incelemek için:
conan profile showHost profile:
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=17
compiler.libcxx=libstdc++11
compiler.version=13
os=Linuxconanfile.txt — Basit Bağımlılık Tanımı
Projenin kökünde bir conanfile.txt oluştur:
[requires]
fmt/10.2.1
spdlog/1.13.0
nlohmann_json/3.11.3
[generators]
CMakeDeps
CMakeToolchain
[layout]
cmake_layout[requires]— kullanmak istediğin kütüphaneler ve versiyonları[generators]— CMake entegrasyonu için gerekli dosyaları üretir[layout]— CMake proje yapısıyla uyumlu klasör düzeni
Bağımlılıkları İndir ve Kur
# Proje kökünde çalıştır
conan install . --output-folder=build --build=missing--output-folder=build— üretilen dosyaları build klasörüne koy--build=missing— önceden derlenmiş (prebuilt) binary yoksa kaynak koddan derle
Bu komut:
Conan Center'dan (varsayılan remote) paketleri indirir
Bağımlılık çözümlemesi yapar (dependency resolution)
CMake entegrasyon dosyalarını üretir
CMake Entegrasyonu
# CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(MyApp CXX)
set(CMAKE_CXX_STANDARD 17)
# Conan'ın ürettiği dosyaları bul
find_package(fmt REQUIRED)
find_package(spdlog REQUIRED)
find_package(nlohmann_json REQUIRED)
add_executable(myapp src/main.cpp)
target_link_libraries(myapp
fmt::fmt
spdlog::spdlog
nlohmann_json::nlohmann_json
)Build:
cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build .Anahtar satır: -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake. Bu dosya Conan tarafından üretilir ve CMake'e kütüphanelerin nerede olduğunu söyler.
conanfile.py — İleri Seviye Konfigürasyon
Daha fazla kontrole ihtiyacın varsa conanfile.py kullan:
from conan import ConanFile
from conan.tools.cmake import cmake_layout
class MyAppConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "CMakeDeps", "CMakeToolchain"
def requirements(self):
self.requires("fmt/10.2.1")
self.requires("spdlog/1.13.0")
self.requires("nlohmann_json/3.11.3")
self.requires("boost/1.84.0")
def build_requirements(self):
self.tool_requires("cmake/3.28.1")
def layout(self):
cmake_layout(self)
def configure(self):
# Boost'un sadece ihtiyaç duyduğun modüllerini al
self.options["boost/*"].without_test = True
self.options["boost/*"].without_python = TrueProfile'lar — Farklı Ortamlar
# Debug build için
conan install . --build=missing -s build_type=Debug
# Cross-compile: Linux'ta Windows için
conan install . --build=missing -pr:h windows_profileCustom profile dosyası (~/.conan2/profiles/windows_cross):
[settings]
os=Windows
arch=x86_64
compiler=msvc
compiler.version=193
build_type=Release
[buildenv]
CC=x86_64-w64-mingw32-gcc
CXX=x86_64-w64-mingw32-g++vcpkg — Microsoft'un Paket Yöneticisi
vcpkg, Microsoft tarafından geliştirilen, CMake-native bir paket yöneticisidir. "Kur ve unut" felsefesiyle çalışır — CMake toolchain dosyasını bir kez ayarla, sonra find_package ile kütüphaneleri bul.
Kurulum
# Klonla
git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
# Bootstrap (platforma göre otomatik)
./bootstrap-vcpkg.sh # Linux/macOS
# veya
.\bootstrap-vcpkg.bat # Windows
# Environment variable ayarla (shell config'e ekle)
export VCPKG_ROOT=$HOME/vcpkg
export PATH=$VCPKG_ROOT:$PATHKlasik Mod: Hızlı Başlangıç
# Kütüphane kur
vcpkg install fmt
vcpkg install spdlog
vcpkg install nlohmann-json
# Kurulu kütüphaneleri listele
vcpkg listCMake'de kullanmak için toolchain dosyasını belirt:
cmake -B build -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
cmake --build buildManifest Mode — Proje Bazlı Bağımlılık (Önerilen)
Manifest mode, bağımlılıkları proje içinde tanımlar. Projeyi klonlayan herkes aynı bağımlılıkları otomatik alır.
Proje kökünde vcpkg.json oluştur:
{
"name": "my-app",
"version-string": "1.0.0",
"dependencies": [
"fmt",
"spdlog",
{
"name": "nlohmann-json",
"version>=": "3.11.0"
},
{
"name": "boost-filesystem",
"version>=": "1.83.0"
}
],
"builtin-baseline": "a1a1cbc975068d8eb65187d8ea2248e081e14e42"
}builtin-baseline— vcpkg repository'sinin commit hash'i. Bu sayede herkes aynı versiyonları alır.Version constraint'ler
version>=ile tanımlanır.
CMakeLists.txt aynı kalır:
cmake_minimum_required(VERSION 3.15)
project(MyApp CXX)
set(CMAKE_CXX_STANDARD 17)
find_package(fmt CONFIG REQUIRED)
find_package(spdlog CONFIG REQUIRED)
find_package(nlohmann_json CONFIG REQUIRED)
add_executable(myapp src/main.cpp)
target_link_libraries(myapp
fmt::fmt
spdlog::spdlog
nlohmann_json::nlohmann_json
)Build:
# Manifest mode'da vcpkg otomatik olarak bağımlılıkları indirir ve derler
cmake -B build -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
cmake --build buildvcpkg.json ile Özelleştirme
{
"name": "my-server",
"version-string": "2.0.0",
"dependencies": [
"fmt",
"spdlog",
"nlohmann-json",
{
"name": "openssl",
"platform": "!windows"
},
{
"name": "curl",
"features": ["ssl"],
"platform": "linux | osx"
}
],
"overrides": [
{
"name": "fmt",
"version": "10.2.1"
}
],
"builtin-baseline": "a1a1cbc975068d8eb65187d8ea2248e081e14e42"
}platform— koşullu bağımlılık (OS'e göre)features— kütüphanenin belirli özelliklerini aktifleştiroverrides— versiyon sabitle (dependency resolver'ı override et)
CMake Preset'leri ile Entegrasyon
Modern CMake projeleri CMakePresets.json kullanır. vcpkg bununla mükemmel çalışır:
{
"version": 3,
"configurePresets": [
{
"name": "default",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
"CMAKE_BUILD_TYPE": "Release"
}
},
{
"name": "debug",
"inherits": "default",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
}
]
}cmake --preset default
cmake --build buildConan vs vcpkg Karşılaştırma
| Özellik | Conan | vcpkg |
|---|---|---|
| Geliştirici | JFrog | Microsoft |
| Felsefe | Decentralized, flexible | CMake-native, simple |
| Paket sayısı | ~1700+ (ConanCenter) | ~2300+ (vcpkg registry) |
| Bağımlılık tanımı | conanfile.txt / .py | vcpkg.json |
| Binary caching | Evet (varsayılan) | Evet (NuGet, GCS, S3, dosya) |
| Cross-compile | Profile'larla çok güçlü | Triplet'lerle iyi |
| Özel paket | conanfile.py ile kolay | Port dosyaları ile |
| CMake entegrasyonu | Toolchain dosyası | Toolchain dosyası |
| Öğrenme eğrisi | Daha dik (daha fazla kavram) | Daha düz (basit başlangıç) |
| CI/CD | Remote server ile güçlü | Binary caching ile iyi |
| Kurumsal kullanım | Artifactory entegrasyonu | Azure DevOps, GitHub Actions |
Ne zaman hangisi?
vcpkg seç eğer: Hızlı başlamak istiyorsan, Microsoft ekosistemindeysen (VS, Azure), basit bağımlılık yönetimi yeterliyse
Conan seç eğer: Cross-compile yapıyorsan, özel paket sunucusu lazımsa, karmaşık bağımlılık grafın varsa, Artifactory kullanıyorsan
Pratikte ikisini de öğren — farklı projelerde farklı tercihlerle karşılaşacaksın.
FetchContent — CMake Built-in Alternatif
CMake 3.11'den itibaren FetchContent modülü, dış bağımlılıkları doğrudan CMake içinde indirip ekleyebilir. Ek araç kurulumu gerektirmez.
cmake_minimum_required(VERSION 3.14)
project(MyApp CXX)
set(CMAKE_CXX_STANDARD 17)
include(FetchContent)
# fmt kütüphanesini GitHub'dan indir
FetchContent_Declare(
fmt
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
GIT_TAG 10.2.1
)
# nlohmann/json
FetchContent_Declare(
json
GIT_REPOSITORY https://github.com/nlohmann/json.git
GIT_TAG v3.11.3
)
# Google Test
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.14.0
)
# Hepsini birden indir ve ekle
FetchContent_MakeAvailable(fmt json googletest)
add_executable(myapp src/main.cpp)
target_link_libraries(myapp
fmt::fmt
nlohmann_json::nlohmann_json
)
# Test
enable_testing()
add_executable(tests tests/test.cpp)
target_link_libraries(tests GTest::gtest_main)FetchContent'in Avantajları
Sıfır ek araç: CMake yeterli, pip/vcpkg kurmanın gerek yok
Basitlik: Tek bir CMakeLists.txt'te her şey
Header-only kütüphaneler için ideal: nlohmann/json, Catch2 gibi
FetchContent'in Dezavantajları
Her configure'da indirir (cache yok varsayılanda —
FETCHCONTENT_FULLY_DISCONNECTEDile offline çalışılabilir)Binary caching yok: Her makinede sıfırdan derleme
Versiyon çatışması: İki bağımlılık aynı kütüphanenin farklı versiyonlarını istiyorsa, FetchContent bunu çözemez
Derleme süresi: Her bağımlılık projeyle birlikte derlenir
⚠️ Pratik kural: 1-3 küçük bağımlılık için FetchContent yeterli. 5+ bağımlılık veya büyük kütüphaneler (Boost, OpenCV) için Conan veya vcpkg kullan.
Popüler C++ Kütüphaneleri
İşte her C++ geliştiricisinin bilmesi gereken kütüphaneler ve paket yöneticilerindeki isimleri:
| Kütüphane | Ne yapar | Conan | vcpkg |
|---|---|---|---|
| fmt | Modern string formatting | fmt/10.2.1 | fmt |
| spdlog | Hızlı logging | spdlog/1.13.0 | spdlog |
| nlohmann/json | JSON parse/generate | nlohmann_json/3.11.3 | nlohmann-json |
| Boost | Her şey (filesystem, asio, regex...) | boost/1.84.0 | boost |
| Catch2 | Test framework | catch2/3.5.2 | catch2 |
| Google Test | Test framework | gtest/1.14.0 | gtest |
| OpenSSL | Kriptografi, TLS | openssl/3.2.1 | openssl |
| cURL | HTTP client | libcurl/8.5.0 | curl |
| SQLite | Embedded veritabanı | sqlite3/3.45.0 | sqlite3 |
| Protobuf | Serialization | protobuf/25.2 | protobuf |
Kullanım Örneği
// fmt — modern formatting (C++20 std::format'ın ilham kaynağı)
#include <fmt/core.h>
#include <fmt/color.h>
// spdlog — hızlı ve kolay logging
#include <spdlog/spdlog.h>
// nlohmann/json — JSON kolaylığı
#include <nlohmann/json.hpp>
#include <iostream>
#include <fstream>
int main() {
// fmt ile formatlama
std::string mesaj = fmt::format("Merhaba, {}! Yil: {}", "Tolga", 2025);
fmt::print(fg(fmt::color::green), "{}\n", mesaj);
// spdlog ile loglama
spdlog::info("Uygulama basladi");
spdlog::warn("Bellek kullanimi: {}%", 85);
spdlog::error("Veritabani baglantisi koptu: {}", "timeout");
// nlohmann/json ile JSON
nlohmann::json config = {
{"sunucu", "localhost"},
{"port", 8080},
{"debug", true},
{"ozellikler", {"auth", "logging", "cache"}}
};
// JSON'u dosyaya yaz (pretty-print)
std::ofstream dosya("config.json");
dosya << config.dump(4);
dosya.close();
// JSON'dan oku
std::ifstream girdi("config.json");
nlohmann::json okunan = nlohmann::json::parse(girdi);
fmt::print("Sunucu: {}:{}\n",
okunan["sunucu"].get<std::string>(),
okunan["port"].get<int>());
return 0;
}Gerçek Dünya Örneği: Tam Proje Yapısı
Her şeyi bir araya getiren gerçekçi bir proje yapısı. vcpkg manifest mode kullanıyor:
my-server/
├── CMakeLists.txt
├── CMakePresets.json
├── vcpkg.json
├── include/
│ └── server/
│ ├── config.h
│ └── logger.h
├── src/
│ ├── main.cpp
│ ├── config.cpp
│ └── logger.cpp
└── tests/
├── CMakeLists.txt
└── config_test.cppvcpkg.json:
{
"name": "my-server",
"version-string": "1.0.0",
"dependencies": [
"fmt",
"spdlog",
"nlohmann-json",
"gtest"
],
"builtin-baseline": "a1a1cbc975068d8eb65187d8ea2248e081e14e42"
}CMakeLists.txt (kök):
cmake_minimum_required(VERSION 3.15)
project(MyServer VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Kütüphaneleri bul (vcpkg otomatik sağlar)
find_package(fmt CONFIG REQUIRED)
find_package(spdlog CONFIG REQUIRED)
find_package(nlohmann_json CONFIG REQUIRED)
# Ana kütüphane
add_library(serverlib
src/config.cpp
src/logger.cpp
)
target_include_directories(serverlib PUBLIC include/)
target_link_libraries(serverlib
PUBLIC fmt::fmt spdlog::spdlog nlohmann_json::nlohmann_json
)
# Çalıştırılabilir
add_executable(server src/main.cpp)
target_link_libraries(server PRIVATE serverlib)
# Testler
option(BUILD_TESTS "Build tests" ON)
if(BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif()tests/CMakeLists.txt:
find_package(GTest CONFIG REQUIRED)
add_executable(server_tests config_test.cpp)
target_link_libraries(server_tests
PRIVATE serverlib GTest::gtest_main
)
include(GoogleTest)
gtest_discover_tests(server_tests)Build komutları:
# İlk build
cmake -B build -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
# Derle
cmake --build build
# Test çalıştır
ctest --test-dir build --output-on-failure
# Çalıştır
./build/serverBest Practices
1. Version Pinning
Bağımlılık versiyonlarını sabitle. "En son sürüm" demek, yarın build'in kırılabilir demek.
// vcpkg.json — baseline ile versiyon sabitleme
{
"builtin-baseline": "a1a1cbc975068d8eb65187d8ea2248e081e14e42",
"overrides": [
{ "name": "fmt", "version": "10.2.1" }
]
}# conanfile.txt — kesin versiyon
[requires]
fmt/10.2.1
spdlog/1.13.02. Reproducible Builds
Lock dosyası kullan: Conan'da
conan.lock, vcpkg'devcpkg.json+ baselineLock dosyasını version control'e commit et
CI/CD'de aynı lock dosyasını kullan
3. Binary Caching
Her makinede sıfırdan derleme zaman kaybı. Binary cache kullan:
# Conan — varsayılan olarak yerel cache kullanır
# Remote cache için:
conan remote add myremote https://myserver.com/artifactory/api/conan/conan-local
# vcpkg — binary caching
export VCPKG_BINARY_SOURCES="clear;files,$HOME/.vcpkg-cache,readwrite"
# veya CI'da NuGet:
# export VCPKG_BINARY_SOURCES="clear;nuget,https://pkgs.dev.azure.com/...,readwrite"4. Minimum Bağımlılık
Her bağımlılık bir risk ve bakım yüküdür. Eklenmeden önce sor:
Bu kütüphane olmadan yapabilir miyim?
Standart kütüphanede karşılığı var mı? (C++20
std::format→ fmt gereksiz)Sadece küçük bir özellik için koca kütüphane mi ekliyorum?
💡 Pratik akış: Yeni proje → 1-3 bağımlılık → FetchContent yeterli. 5+ bağımlılık veya Boost gibi büyük kütüphane → vcpkg veya Conan. Cross-compile veya kurumsal → Conan.
Özet
C++'ta paket yönetimi zorunludur — CMake
find_packagetek başına bağımlılık yönetimi sağlamaz. Reproducible build, versiyon kontrolü ve platform bağımsızlığı için paket yöneticisi kullan.Conan decentralized, esnek ve cross-compile'da güçlü.
conanfile.txtveyaconanfile.pyile bağımlılık tanımla,CMakeToolchaingenerator ile CMake'e entegre et.vcpkg CMake-native, basit ve Microsoft ekosistemiyle uyumlu.
vcpkg.jsonmanifest dosyasıyla proje bazlı bağımlılık,CMAKE_TOOLCHAIN_FILEile entegrasyon.FetchContent CMake built-in çözüm. Ek araç gerektirmez, küçük projeler ve header-only kütüphaneler için ideal. Ama binary caching yok ve büyük projelerde yetersiz kalır.
Version pinning kritik — bağımlılık versiyonlarını sabitle, lock dosyalarını commit et, CI/CD'de aynı ortamı garanti et.
Popüler kütüphaneler: fmt (formatting), spdlog (logging), nlohmann/json (JSON), Boost (her şey), Google Test (testing). Bunları paket yöneticisiyle eklemek 1 satır iş.
İkisini de öğren — farklı projelerde farklı tercihlerle karşılaşacaksın. Önemli olan prensipleri anlamak: bağımlılık tanımı, versiyon kontrolü, CMake entegrasyonu ve reproducible builds.
AI Asistan
Sorularını yanıtlamaya hazır