Cross-Compilation & Toolchain
TEKNİK REHBER CROSS-COMPILATION CMAKE 2026

CMake —
toolchain dosyası ile cross-compile.

CMAKE_SYSTEM_NAME'den CMAKE_FIND_ROOT_PATH'e — ARM Cortex-A53 için eksiksiz toolchain.cmake. ExternalProject, DESTDIR install ve Hunter/Conan bağımlılık yönetimi.

00 CMake cross-compile mimarisi

CMake'in cross-compile desteği, toolchain dosyası adı verilen özel bir CMake scripti üzerinden çalışır. Bu dosya cmake konfigürasyonu başlamadan önce okunur ve tüm compiler/linker ayarlarını belirler.

Akış

  cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake ..
         │
         ↓
  toolchain.cmake yüklenir
  ┌────────────────────────────────────────────────┐
  │  CMAKE_SYSTEM_NAME = Linux                     │
  │  CMAKE_SYSTEM_PROCESSOR = arm                  │
  │  CMAKE_C_COMPILER = arm-...-gcc                │
  │  CMAKE_SYSROOT = /path/to/sysroot              │
  │  CMAKE_FIND_ROOT_PATH = ...                    │
  └────────────────────────────────────────────────┘
         │
         ↓
  CMakeLists.txt okunur
  Compiler testi (CMakeCCompiler.cmake)
  find_package() / find_library() çağrıları →
      FIND_ROOT_PATH içinde arar
         │
         ↓
  Makefile / Ninja dosyaları üretilir
    

CMake'in tespit ettiği değişkenler

bash
# cmake konfigürasyon sonrası kontrol et
cmake --build . --verbose 2>&1 | head -5

# ya da
cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
      -DCMAKE_VERBOSE_MAKEFILE=ON \
      ..

# cache'e yazılan değerleri göster
cmake -L .. | grep CMAKE_C_COMPILER
# CMAKE_C_COMPILER:FILEPATH=/home/.../arm-unknown-linux-gnueabihf-gcc

01 toolchain.cmake — temel değişkenler

Toolchain dosyasının çekirdeği birkaç zorunlu değişkenden oluşur. Bunlar cmake'e hedef sistem ve derleyici hakkında bilgi verir.

Minimal toolchain.cmake

toolchain.cmake
# ─── Hedef sistem ─────────────────────────────────────────────
# CMAKE_SYSTEM_NAME: çapraz derleme hedefinin OS adı
# Linux, Windows, Darwin, Android, iOS, Generic (bare-metal)
set(CMAKE_SYSTEM_NAME Linux)

# CMAKE_SYSTEM_PROCESSOR: hedef CPU mimarisi
# arm, aarch64, riscv64, x86_64
set(CMAKE_SYSTEM_PROCESSOR arm)

# ─── Derleyiciler ─────────────────────────────────────────────
set(CROSS_TRIPLE "arm-unknown-linux-gnueabihf")
set(TOOLCHAIN_BIN "$ENV{HOME}/x-tools/${CROSS_TRIPLE}/bin")

set(CMAKE_C_COMPILER   "${TOOLCHAIN_BIN}/${CROSS_TRIPLE}-gcc")
set(CMAKE_CXX_COMPILER "${TOOLCHAIN_BIN}/${CROSS_TRIPLE}-g++")
set(CMAKE_ASM_COMPILER "${TOOLCHAIN_BIN}/${CROSS_TRIPLE}-as")

# ─── Araçlar ──────────────────────────────────────────────────
set(CMAKE_AR      "${TOOLCHAIN_BIN}/${CROSS_TRIPLE}-ar"      CACHE FILEPATH "" FORCE)
set(CMAKE_RANLIB  "${TOOLCHAIN_BIN}/${CROSS_TRIPLE}-ranlib"  CACHE FILEPATH "" FORCE)
set(CMAKE_STRIP   "${TOOLCHAIN_BIN}/${CROSS_TRIPLE}-strip"   CACHE FILEPATH "" FORCE)
set(CMAKE_OBJCOPY "${TOOLCHAIN_BIN}/${CROSS_TRIPLE}-objcopy" CACHE FILEPATH "" FORCE)
CMAKE_SYSTEM_NAME ÖNEMI

CMAKE_SYSTEM_NAME'i ayarlamak cmake'e cross-compile modunda olduğunu söyler. Bu değişken ayarlandığında CMAKE_CROSSCOMPILING otomatik olarak TRUE olur. Bunu CMakeLists.txt'te kontrol ederek platform-spesifik kod dalları oluşturabilirsin.

02 CMAKE_SYSROOT ve CMAKE_FIND_ROOT_PATH

Bu iki değişken, cmake'in hedef sisteme ait başlık ve kütüphaneleri nerede arayacağını belirler.

CMAKE_SYSROOT
Derleyiciye --sysroot bayrağı olarak geçirilir. Hem derleme hem link aşamasını etkiler. find_library() ve find_path() bu kök altında arar.
CMAKE_FIND_ROOT_PATH
find_*() komutlarının arayacağı ek kök dizinlerin listesi. Sysroot'a ek olarak başka dizinler de belirtmek için kullanılır. Liste formatında birden fazla yol girilir.
CMAKE_STAGING_PREFIX
Cross-compiled kütüphanelerin kurulduğu geçici dizin. CMAKE_FIND_ROOT_PATH'e otomatik eklenir — cross-derlenen bağımlılıkları bulur.
toolchain.cmake — sysroot bölümü
set(CROSS_TRIPLE "arm-unknown-linux-gnueabihf")
set(SYSROOT "$ENV{HOME}/x-tools/${CROSS_TRIPLE}/${CROSS_TRIPLE}/sysroot")

# --sysroot derleyici bayrağı
set(CMAKE_SYSROOT "${SYSROOT}")

# find_*() için kök dizinler
set(CMAKE_FIND_ROOT_PATH
    "${SYSROOT}"
    "${SYSROOT}/usr"
)

# staging: cross-derlenen kütüphanelerin geçici kurulum yeri
set(CMAKE_STAGING_PREFIX "$ENV{HOME}/staging/arm-cortex-a53")

03 FIND_ROOT_PATH_MODE — arama politikası

Cross-compile'da cmake'e bazı şeylerin host'ta, bazılarının target'ta aranması gerektiğini söylemek gerekir. FIND_ROOT_PATH_MODE değişkenleri bunu kontrol eder.

CMAKE_FIND_ROOT_PATH_MODE_PROGRAM
NEVER: çalıştırılabilir araçları (gcc, python vb.) HOST'ta ara. Cross ortamda standart ayar.
CMAKE_FIND_ROOT_PATH_MODE_LIBRARY
ONLY: kütüphaneleri yalnızca FIND_ROOT_PATH içinde ara. Host kütüphanelerini dışarıda bırakır.
CMAKE_FIND_ROOT_PATH_MODE_INCLUDE
ONLY: başlık dosyalarını yalnızca FIND_ROOT_PATH içinde ara.
CMAKE_FIND_ROOT_PATH_MODE_PACKAGE
ONLY: CMake package config dosyalarını yalnızca FIND_ROOT_PATH içinde ara.
toolchain.cmake — arama politikası
# programlar (araçlar) host'ta aransın
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

# kütüphane ve başlıklar yalnızca target sysroot'ta aransın
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
BOTH MODU

BOTH değeri hem host hem target'ta arar — güvensiz ama bazen host araçlarına hedeften erişim gerektiğinde kullanılır. Genellikle yalnızca PROGRAM için BOTH mantıklıdır.

04 cmake -DCMAKE_TOOLCHAIN_FILE ile geç

Toolchain dosyası cmake komutuna -DCMAKE_TOOLCHAIN_FILE parametresiyle verilir. Bu parametre her zaman ilk cmake çağrısında belirtilmelidir — cache temizlenmeden değiştirilemez.

Kullanım

bash
mkdir -p build-arm && cd build-arm

cmake \
    -DCMAKE_TOOLCHAIN_FILE=../toolchain-arm-cortex-a53.cmake \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX=/usr \
    ..

cmake --build . -- -j$(nproc)

# hangi derleyicinin kullanıldığını doğrula
cmake -L . | grep CMAKE_C_COMPILER
# CMAKE_C_COMPILER:FILEPATH=.../arm-unknown-linux-gnueabihf-gcc

Preset ile toolchain (CMake 3.19+)

CMakePresets.json
{
  "version": 3,
  "configurePresets": [
    {
      "name": "arm-cortex-a53",
      "displayName": "ARM Cortex-A53 Cross Compile",
      "description": "arm-unknown-linux-gnueabihf cross compilation",
      "toolchainFile": "${sourceDir}/cmake/toolchain-arm-cortex-a53.cmake",
      "binaryDir": "${sourceDir}/build-arm",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Release",
        "CMAKE_INSTALL_PREFIX": "/usr"
      }
    },
    {
      "name": "riscv64",
      "displayName": "RISC-V 64-bit Cross Compile",
      "toolchainFile": "${sourceDir}/cmake/toolchain-riscv64.cmake",
      "binaryDir": "${sourceDir}/build-riscv64"
    }
  ]
}
bash
# preset ile kullanım
cmake --preset arm-cortex-a53
cmake --build --preset arm-cortex-a53

05 ExternalProject_Add ile bağımlılık

ExternalProject_Add, bağımlı projeyi cross toolchain ile indirip derler. Cross-compiled bağımlılıkları staging prefix'e kurarak ana projenin bulmasını sağlar.

CMakeLists.txt — ExternalProject
include(ExternalProject)

set(STAGING_DIR "$ENV{HOME}/staging/arm-cortex-a53")

# zlib'i cross-compile et
ExternalProject_Add(zlib_cross
    URL         https://zlib.net/zlib-1.3.1.tar.gz
    URL_HASH    SHA256=9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23

    CMAKE_ARGS
        -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
        -DCMAKE_INSTALL_PREFIX=${STAGING_DIR}
        -DCMAKE_BUILD_TYPE=Release

    BUILD_BYPRODUCTS
        ${STAGING_DIR}/lib/libz.a
)

# ana proje zlib'e bağımlı olsun
add_executable(myapp main.c)
add_dependencies(myapp zlib_cross)

target_include_directories(myapp PRIVATE ${STAGING_DIR}/include)
target_link_libraries(myapp PRIVATE ${STAGING_DIR}/lib/libz.a)

FetchContent ile alternatif

CMakeLists.txt — FetchContent
include(FetchContent)

FetchContent_Declare(
    zlib
    URL      https://zlib.net/zlib-1.3.1.tar.gz
    URL_HASH SHA256=9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23
)

FetchContent_MakeAvailable(zlib)

add_executable(myapp main.c)
# zlib CMakeLists.txt'i otomatik bulunur — cross toolchain ile derlenir
target_link_libraries(myapp PRIVATE zlibstatic)
FETCHCONTENT vs EXTERNALPROJECT

FetchContent, bağımlılığı ana projeye dahil eder (configure zamanında). ExternalProject bağımsız bir build oluşturur (build zamanında). Cross-compile için ExternalProject daha güvenlidir — bağımlılık kesinlikle aynı toolchain ile derlenir.

06 Cross install — DESTDIR

DESTDIR, install prefix'inin önüne geçici bir kök dizin ekler. Hedef dosya sistemine veya sysroot'a kurmak için kullanılır.

DESTDIR ile install

bash
SYSROOT="${HOME}/x-tools/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/sysroot"

# cmake ile install prefix /usr, DESTDIR ile sysroot altına kurulur
cmake \
    -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
    -DCMAKE_INSTALL_PREFIX=/usr \
    -DCMAKE_BUILD_TYPE=Release \
    ..

cmake --build . -- -j$(nproc)

# DESTDIR: dosyalar ${DESTDIR}/${CMAKE_INSTALL_PREFIX} altına gider
DESTDIR="${SYSROOT}" cmake --install .

# sonuç: dosyalar ${SYSROOT}/usr/lib, ${SYSROOT}/usr/include altında
ls ${SYSROOT}/usr/lib/libmylib.a

Makefile ile DESTDIR

bash
# autotools ile DESTDIR kullanımı da aynı
make DESTDIR="${SYSROOT}" install

# meson ile
DESTDIR="${SYSROOT}" ninja install

07 Pratik: ARM Cortex-A53 tam toolchain.cmake

Gerçek dünya kullanımı için eksiksiz toolchain.cmake dosyası — pkg-config, CPU bayrakları ve install prefix dahil.

cmake/toolchain-arm-cortex-a53.cmake
# ════════════════════════════════════════════════════════════
# ARM Cortex-A53 Cross-Compile Toolchain
# Kullanım: cmake -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm-cortex-a53.cmake ..
# ════════════════════════════════════════════════════════════

# ─── Hedef sistem ─────────────────────────────────────────────
set(CMAKE_SYSTEM_NAME    Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

# ─── Toolchain yolu ───────────────────────────────────────────
set(CROSS_TRIPLE "arm-unknown-linux-gnueabihf")
set(TOOLCHAIN_ROOT "$ENV{HOME}/x-tools/${CROSS_TRIPLE}")
set(TOOLCHAIN_BIN  "${TOOLCHAIN_ROOT}/bin")
set(SYSROOT        "${TOOLCHAIN_ROOT}/${CROSS_TRIPLE}/sysroot")

# ─── Derleyiciler ─────────────────────────────────────────────
set(CMAKE_C_COMPILER   "${TOOLCHAIN_BIN}/${CROSS_TRIPLE}-gcc")
set(CMAKE_CXX_COMPILER "${TOOLCHAIN_BIN}/${CROSS_TRIPLE}-g++")
set(CMAKE_ASM_COMPILER "${TOOLCHAIN_BIN}/${CROSS_TRIPLE}-gcc")

# ─── Araçlar ──────────────────────────────────────────────────
set(CMAKE_AR      "${TOOLCHAIN_BIN}/${CROSS_TRIPLE}-ar"      CACHE FILEPATH "" FORCE)
set(CMAKE_RANLIB  "${TOOLCHAIN_BIN}/${CROSS_TRIPLE}-ranlib"  CACHE FILEPATH "" FORCE)
set(CMAKE_STRIP   "${TOOLCHAIN_BIN}/${CROSS_TRIPLE}-strip"   CACHE FILEPATH "" FORCE)
set(CMAKE_OBJCOPY "${TOOLCHAIN_BIN}/${CROSS_TRIPLE}-objcopy" CACHE FILEPATH "" FORCE)
set(CMAKE_OBJDUMP "${TOOLCHAIN_BIN}/${CROSS_TRIPLE}-objdump" CACHE FILEPATH "" FORCE)

# ─── CPU bayrakları ───────────────────────────────────────────
set(CPU_FLAGS "-march=armv8-a -mcpu=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard")

set(CMAKE_C_FLAGS_INIT   "${CPU_FLAGS}")
set(CMAKE_CXX_FLAGS_INIT "${CPU_FLAGS}")

# ─── Sysroot ──────────────────────────────────────────────────
set(CMAKE_SYSROOT "${SYSROOT}")

set(CMAKE_FIND_ROOT_PATH
    "${SYSROOT}"
    "${SYSROOT}/usr"
    "$ENV{HOME}/staging/arm-cortex-a53"
)

# ─── Arama politikası ─────────────────────────────────────────
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

# ─── pkg-config ───────────────────────────────────────────────
set(PKG_CONFIG_EXECUTABLE "$ENV{HOME}/bin/arm-linux-gnueabihf-pkg-config"
    CACHE STRING "" FORCE)

set(ENV{PKG_CONFIG_SYSROOT_DIR} "${SYSROOT}")
set(ENV{PKG_CONFIG_LIBDIR}
    "${SYSROOT}/usr/lib/pkgconfig:${SYSROOT}/usr/share/pkgconfig")
set(ENV{PKG_CONFIG_PATH} "")

# ─── Staging prefix ───────────────────────────────────────────
set(CMAKE_STAGING_PREFIX "$ENV{HOME}/staging/arm-cortex-a53")

Kullanım

bash
mkdir build-arm && cd build-arm

cmake \
    -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchain-arm-cortex-a53.cmake \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX=/usr \
    ..

cmake --build . -j$(nproc)

# sysroot'a kur
DESTDIR="${HOME}/x-tools/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/sysroot" \
    cmake --install .

08 Qt cross-compile ipuçları

Qt 6 cross-compile için cmake tabanlı yeni sistemin birkaç ek değişkeni vardır. Qt 5'ten farklı olarak ayrı host Qt kurulumu gerektirir.

Qt6 cross-compile ön koşulları

bash
# 1. Host Qt kurulumu (moc, rcc, uic araçları için)
sudo apt install qt6-base-dev qt6-tools-dev

# 2. Hedef sysroot'ta Qt kütüphaneleri (RPi rootfs'ten kopyala)
rsync -avz pi@rpi:/usr/lib/aarch64-linux-gnu/libQt6*.so* \
    ${SYSROOT}/usr/lib/

rsync -avz pi@rpi:/usr/include/aarch64-linux-gnu/qt6/ \
    ${SYSROOT}/usr/include/qt6/

Qt6 toolchain.cmake eklentisi

toolchain-qt6-arm.cmake
# Qt6 cross-compile için ek değişkenler
# Üst toolchain dosyasını dahil et
include("${CMAKE_CURRENT_LIST_DIR}/toolchain-arm-cortex-a53.cmake")

# Host Qt araçlarını belirt
set(QT_HOST_PATH "/usr" CACHE PATH "Host Qt installation")
set(QT_HOST_PATH_CMAKE_DIR "${QT_HOST_PATH}/lib/cmake")

# Qt'un platform plugin'ini belirt
set(QT_QMAKE_TARGET_MKSPEC "linux-aarch64-gnu-g++")
bash
# Qt6 projesini cross-compile et
cmake \
    -DCMAKE_TOOLCHAIN_FILE=toolchain-qt6-arm.cmake \
    -DQT_HOST_PATH=/usr \
    -DCMAKE_BUILD_TYPE=Release \
    ..

cmake --build . -j$(nproc)

09 Hunter ve Conan ile cross bağımlılık yönetimi

Hunter ve Conan, CMake projelerinde bağımlılık yönetimini otomatikleştiren araçlardır. Her ikisi de cross-compile desteği sunar ancak yaklaşımları farklıdır.

Hunter ile cross-compile

CMakeLists.txt — Hunter
cmake_minimum_required(VERSION 3.20)

# Hunter bootstrap
include("cmake/HunterGate.cmake")
HunterGate(
    URL  "https://github.com/cpp-pm/hunter/archive/v0.24.18.tar.gz"
    SHA1 "1292e4d661e1770d6d6ca08c12c722a83b58eac2"
)

project(myapp C CXX)

# Hunter paketi iste — cross toolchain ile otomatik derlenir
hunter_add_package(OpenSSL)
hunter_add_package(ZLIB)

find_package(OpenSSL REQUIRED)
find_package(ZLIB REQUIRED)

add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE OpenSSL::SSL ZLIB::ZLIB)
bash
# Hunter, toolchain dosyasını otomatik propagate eder
cmake \
    -DCMAKE_TOOLCHAIN_FILE=toolchain-arm-cortex-a53.cmake \
    -DCMAKE_BUILD_TYPE=Release \
    ..
# Hunter, OpenSSL ve ZLIB'i ARM için otomatik derler

Conan ile cross-compile

conanfile.txt
[requires]
openssl/3.1.3
zlib/1.3.1
libcurl/8.4.0

[generators]
CMakeToolchain
CMakeDeps

[settings]
os=Linux
arch=armv8
compiler=gcc
compiler.version=13
compiler.libcxx=libstdc++11
build_type=Release
bash
# cross-compile profili oluştur
mkdir -p ~/.conan2/profiles
cat > ~/.conan2/profiles/arm-cortex-a53 <<'EOF'
[settings]
os=Linux
arch=armv8
compiler=gcc
compiler.version=13
compiler.libcxx=libstdc++11
build_type=Release

[env]
CC=arm-unknown-linux-gnueabihf-gcc
CXX=arm-unknown-linux-gnueabihf-g++
CFLAGS=-mcpu=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard
CXXFLAGS=-mcpu=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard
EOF

# bağımlılıkları derle
conan install . \
    --profile:host=arm-cortex-a53 \
    --profile:build=default \
    --output-folder=build-arm \
    --build=missing

# cmake ile derle
cd build-arm
cmake \
    -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake \
    -DCMAKE_BUILD_TYPE=Release \
    ..
cmake --build . -j$(nproc)
HUNTER vs CONAN

Hunter tamamen CMake tabanlıdır, ek araç gerektirmez. Conan daha geniş paket ekosistemi sunar ve profesyonel ortamlarda yaygındır. Küçük projeler için Hunter, büyük organizasyonlarda Conan tercih edilir. Her ikisi de cross-compile toolchain'ini doğru kullandığınızda bağımlılıkları hedef mimari için derler.