← Kursa Dön
📄 Text · 15 min

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:

  1. Kütüphane sisteme kurulu olmalı: Yeni bir geliştirici projeyi klonladığında, önce tüm bağımlılıkları elle kurmalı

  2. Versiyon kontrolü zor: Sistem genelinde tek bir versiyon var. Proje A boost 1.80, Proje B boost 1.82 istiyorsa?

  3. Platform farklılıkları: Ubuntu'da apt install libboost-dev, macOS'ta brew install boost, Windows'ta... iyi şanslar

  4. Reproducible 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ılar

Profile'ı incelemek için:

conan profile show
Host profile:
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=17
compiler.libcxx=libstdc++11
compiler.version=13
os=Linux

conanfile.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:

  1. Conan Center'dan (varsayılan remote) paketleri indirir

  2. Bağımlılık çözümlemesi yapar (dependency resolution)

  3. 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 = True

Profile'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_profile

Custom 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:$PATH

Klasik 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 list

CMake'de kullanmak için toolchain dosyasını belirt:

cmake -B build -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
cmake --build build

Manifest 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 build

vcpkg.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ştir

  • overrides — 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 build

Conan vs vcpkg Karşılaştırma

ÖzellikConanvcpkg
GeliştiriciJFrogMicrosoft
FelsefeDecentralized, flexibleCMake-native, simple
Paket sayısı~1700+ (ConanCenter)~2300+ (vcpkg registry)
Bağımlılık tanımıconanfile.txt / .pyvcpkg.json
Binary cachingEvet (varsayılan)Evet (NuGet, GCS, S3, dosya)
Cross-compileProfile'larla çok güçlüTriplet'lerle iyi
Özel paketconanfile.py ile kolayPort dosyaları ile
CMake entegrasyonuToolchain dosyasıToolchain dosyası
Öğrenme eğrisiDaha dik (daha fazla kavram)Daha düz (basit başlangıç)
CI/CDRemote server ile güçlüBinary caching ile iyi
Kurumsal kullanımArtifactory entegrasyonuAzure 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_DISCONNECTED ile 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üphaneNe yaparConanvcpkg
fmtModern string formattingfmt/10.2.1fmt
spdlogHızlı loggingspdlog/1.13.0spdlog
nlohmann/jsonJSON parse/generatenlohmann_json/3.11.3nlohmann-json
BoostHer şey (filesystem, asio, regex...)boost/1.84.0boost
Catch2Test frameworkcatch2/3.5.2catch2
Google TestTest frameworkgtest/1.14.0gtest
OpenSSLKriptografi, TLSopenssl/3.2.1openssl
cURLHTTP clientlibcurl/8.5.0curl
SQLiteEmbedded veritabanısqlite3/3.45.0sqlite3
ProtobufSerializationprotobuf/25.2protobuf

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.cpp

vcpkg.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/server

Best 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.0

2. Reproducible Builds

  • Lock dosyası kullan: Conan'da conan.lock, vcpkg'de vcpkg.json + baseline

  • Lock 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_package tek 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.txt veya conanfile.py ile bağımlılık tanımla, CMakeToolchain generator ile CMake'e entegre et.

  • vcpkg CMake-native, basit ve Microsoft ekosistemiyle uyumlu. vcpkg.json manifest dosyasıyla proje bazlı bağımlılık, CMAKE_TOOLCHAIN_FILE ile 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.