Metin2 Projelerinde CMake

  • Konuyu açan Konuyu açan zodiac160
  • Açılış Tarihi Açılış Tarihi
  • Yanıt Yanıt 0
  • Gösterim Gösterim 64

zodiac160

MT Üye
MT Üye
Mesaj
151
Çözümler
7
Beğeni
59
Puan
454
Ticaret Puanı
0
Merhaba arkadaşlar windowsda vs studio freebsdde GNU yerine tek bir yerden proje yönetimi yapmayı planlayan arkadaşlar için ufak bir başlangıç yapmayı planlıyorum. Konunun fazla uzamaması için sizlere genel hatlarıyla anlatacağım. Eğer hatam varsa eksik yerler varsa eklerseniz sevinirim.

Öncelikle ihtiyacımız olan araçlar

CMAKE -
Linkleri görebilmek için giriş yap veya kayıt ol.

GCC (isteğe bağlı) -
Linkleri görebilmek için giriş yap veya kayıt ol.

LLVM (isteğe bağlı) -
Linkleri görebilmek için giriş yap veya kayıt ol.

Windows Build için VS 2022 yoksa Windows SDK kurulmalı
Ninja (isteğe bağlı) -
Linkleri görebilmek için giriş yap veya kayıt ol.


Ninja bir derleme aracıdır hızlı build almak için kullanıyoruz.

Oluşturacağımız örnek dosya yapısı:
Kod:
Genişlet Daralt Kopyala
metin2-src/
  └──Srcs/
      ├── cmake/
      ├── Extern/
      ├     ├── include/
      ├     └── lib/
      └── Server/
            ├── common/
            ├── db/
            ├    ├── src/
            ├    └── CMakeLists.txt
            ├── game/
            ├    ├── src/
            ├    └── CMakeLists.txt
            ├── libgame/
            ├    ├── include/
            ├    ├── src/
            ├    └── CMakeLists.txt
            ├── liblua/
            ├    ├── include/
            ├    ├── src/
            ├    └── CMakeLists.txt
            ├── libpoly/
            ├    ├── include/
            ├    ├── src/
            ├    └── CMakeLists.txt
            ├── libsql/
            ├    ├── include/
            ├    ├── src/
            ├    └── CMakeLists.txt
            ├── libthecore/
            ├    ├── include/
            ├    ├── src/
            ├    └── CMakeLists.txt
            ├── CMakeLists.txt
            └── CMakePresets.json

Arkadaşlar öncelikle Server klasörü içine main bir CMakeLists.txt oluşturmakla başlayalım burası bizim Merkez yapılandırma alanımız olacak. Ayrıca cmake klasörü içerisine ise özel makroları ve platforma özgü ayarları yapacağımız alanımız olacak. Bazı flaglar sadece FreeBSD'ye özgü olabiliyor ve ya Windows için özel tanımları birbirinden ayırmak ve projedeki karmaşıklığı azaltmak için kullanıyoruz.

CMakePresets.json = Bu dosya bizim build komutlarını uzunca yazmak yerine kısa ve öz biçimde yazmamızı ve build ayarlarını rahatlıkla yapmamızı sağlayan dosyamız.

Örnek olması için kendi kullandığım CMakePresets.json

Kod:
Genişlet Daralt Kopyala
{
  "version": 3,
  "cmakeMinimumRequired": {
    "major": 3,
    "minor": 31,
    "patch": 0
  },
  "configurePresets": [
    {
      "name": "windows-clang-cl",
      "displayName": "Windows Clang CL Build",
      "description": "Build for Windows using Clang-Cl",
      "generator": "Ninja",
      "binaryDir": "${sourceDir}/build",
      "cacheVariables": {
        "CMAKE_C_COMPILER": "clang-cl",
        "CMAKE_CXX_COMPILER": "clang-cl",
        "CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
      }
    },
    {
      "name": "freebsd-clang",
      "displayName": "FreeBSD Clang Build",
      "description": "Build for FreeBSD using Clang",
      "generator": "Ninja",
      "binaryDir": "${sourceDir}/build",
      "cacheVariables": {
        "CMAKE_C_COMPILER": "/usr/bin/clang",
        "CMAKE_CXX_COMPILER": "/usr/bin/clang++",
        "CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
      }
    }
  ],
  "buildPresets": [
    {
      "name": "debug-windows",
      "configurePreset": "windows-clang-cl",
      "configuration": "Debug"
    },
    {
      "name": "release-windows",
      "configurePreset": "windows-clang-cl",
      "configuration": "Release"
    },
    {
      "name": "release-freebsd",
      "configurePreset": "freebsd-clang",
      "configuration": "Release"
    }
  ]
}

Şimdi gelelim main CMakeLists.txt dosyamıza. Burada projede kullanılacak olan macrolarımızı ve C++ standartlarını tanımladığımız alanımız. Msbuildde .sln dosyası ve ya Makefile kullanırken Ana dizindeki Makefile dosyası olarak düşünebiliriz.

Örnek:

Kod:
Genişlet Daralt Kopyala
cmake_minimum_required(VERSION 3.31)

project("Metin2 Server")

set(CMAKE_CXX_STANDARD 20) # c++20 standardını kullanması için
set(CMAKE_CXX_STANDARD_REQUIRED ON) # c++20 standardına bağlı kalması için
set(CMAKE_CXX_EXTENSIONS OFF) # gnuc++20 yerine hem windowsta hemde freebsdde stdc++20 kullanması için


set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/macros") # cmake klasörü içindeki macros klasörüne eklediğim macrolara cmake'in doğrudan erişim sağlaması için
include(CheckPlatform) # macros klasörüne oluşturmuş olduğum CheckPlatform.cmake dosyam burada platforma özel olarak ayarları include ediyor.

#derleme sırasına göre projenizdeki .vcxprojdan ve ya ana dizindeki Makefile dosyanızdan alabilirsiniz.
add_subdirectory(liblua)
add_subdirectory(libthecore)
add_subdirectory(libpoly)
add_subdirectory(libgame)
add_subdirectory(libsql)
add_subdirectory(game)
add_subdirectory(db)

Ana dizinimizdeki CMakeLists için örnek yapımız bu şekildeydi
- cmake_minimum_required(VERSION 3.31) = projenizde kullanılacak minimum cmake versiyonu belirtmelisiniz.
- project("Metin2 Server") = her bir projenize isim vermelisiniz. örneğin project(libgame LANGUAGES CXX) libgameyi c++ ile derlemesini belirtiyoruz bunu neye göre belirlediğimizi de öğrenmek için her bir projenin makefile dosyasını açtığınızda CXX = clang++/ CC = clang tanımlarına göre belirtiyoruz. Buraya kadar ana hatlarıyla tamam.

Her bir projede kullanılan kütüphaneler bağımlılıklar. derleme için flag ve opsiyonları tespit etmek için dikkat etmemiz gereken hususlar:

1- Kütüphane Header:
Makefile içerisinde "INCDIR" olarak tanımlanmıştır ve tanımlanırken "-I" kullanılır -I/usr/local/include gibi
vcxproj içerisinde ise AdditionalIncludeDirectories olarak tanımlanmıştır
Bunlar cmakede include_directories() ya da target_include_directories() ile tanımlanır.

2- Macrolar:
Makefile içerisinde macro tanımlı değildir. Genelde Windowsta derleme için bazı macrolar kullanılıyor.
vcxproj içerisinde PreprocessorDefinitions olarak tanımlanmıştır.
Bunlar cmakede add_definitions() veya target_compile_definitions() ile tanımlanır.

3- Kütüphane Lib:
Makefile içerisinde LIBS olarak tanımlanmıştır ve tanımlanırken "-l" kullanılır -lthecore gibi
vcxproj içerisinde ise AdditionalDependencies olarak tanımlanmıştır.
Bunlar cmakede target_link_libraries() ile tanımlanır.

4- Kütüphane Lib dizinleri:
Makefile içerisinde LIBDIR olarak tanımlanmıştır ve tanımlanırken -L kullanılır -L /usr/local/lib/mysql gibi
vcxproj içerisinde ise AdditionalLibraryDirectories olarak tanımlanmıştır.
Bunlar cmakede link_directories() ile tanımlanabilir ama genellikle target_link_libraries() yolu tercih edilir.

5- Flag
MakeFile içerisinde CFLAGS olarak tanımlanmıştır. Çoğu flaglar hem freebsd hemde windowsta kullanılıyor ama istisnai durumlar olabilir bunu tespit etmek için clang++ --help komutunu kullanın.
vcxproj içerisinde ise ClCompile tanımı içerisinde RuntimeLibrary WarningLevel = /W3 olarak tanımlanmıştır..
Not: eğer windowsta build almak için Clang-Cl kullanacaksanız vcxproj ayarlarına göre Windows ayarını macro ile yapmalısınız. Örneğin Windows.cmake platforma özel olarak ayarladığım cmake dosyam.

Kod:
Genişlet Daralt Kopyala
add_compile_definitions(
        $<$<CONFIG:Debug>:_DEBUG>
        $<$<CONFIG:Release>:NDEBUG>
        WIN32
        _WIN32
        __WIN32__
        NOMINMAX
        _USE_32BIT_TIME_T
        _SILENCE_ALL_CXX20_DEPRECATION_WARNINGS
        _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
        _CRT_SECURE_NO_DEPRECATE
)

add_compile_options(
        /W3
        /Zi
        /EHsc
        -fms-compatibility
)

set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

Sizlere örnek olması açısından kendi cmake dosyamı paylaşıyorum.

Kod:
Genişlet Daralt Kopyala
cmake_minimum_required(VERSION 3.31)

project(libgame LANGUAGES CXX)

file(GLOB_RECURSE GAME_SOURCES
        ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cc
)

add_library(libgame STATIC ${GAME_SOURCES})

target_include_directories(libgame PUBLIC
        ${CMAKE_CURRENT_SOURCE_DIR}/include
        ${EXTERN}/include
)

target_compile_definitions(libgame PRIVATE
        $<$<PLATFORM_ID:Windows>:_LIB>
)

target_compile_options(libgame PRIVATE
        -m32
        -O2

        # FreeBSD
        $<$<PLATFORM_ID:FreeBSD>:-fno-exceptions>


)

if (FREEBSD)
    set_target_properties(libgame PROPERTIES OUTPUT_NAME "game")
endif ()


set_target_properties(libgame PROPERTIES
        DEBUG_POSTFIX "_d"
        ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib
)

Son olarak static lib olarak terleme yaptığınızda FreeBSD dosya çıktı adına otomatiken "lib" ekliyor libgame gibi bu yüzden OUTPUT_NAME çıktısınız FreeBSD için game olarak veriyorum libgame olarak çıktı verecektir. Windows için lib tanımı yaparken libmysql olarak tanımlarken freebsd için sadece mysql olarak tanımlıyoruz çünkü FreeBSD libmyql olarak tanımladığınızda liblibmysql olarak arama yapacaktır. Örnek olarak game için libleri paylaştım

Kod:
Genişlet Daralt Kopyala
metin2_add_libraries(m2_game Windows Release liblua libthecore libsql libpoly libgame DevIL-1.7.8 DevILU-1.7.8 DevILUT-1.7.8 cryptlib-Release fmt)

#FreeBSD
metin2_add_libraries(m2_game FreeBSD "" lua thecore sql poly game mysqlclient ssl crypto IL cryptopp m md z pthread fmt)
 
Geri
Üst