Giriş
Linux'taki bir projeden CMake kullanarak Visual Studio 2012 projesi üretirken aldığım notlar aşağıda. Dizinin şöyle bir yapıda olduğunu varsayalım.
GUI
1. "Browse Source" ile kaynak kodun bulunduğu dizin seçilir. Kaynak kod dizininde CMakeLists.txt dosyası da bulunmalı
2. "Browse Build" ile .sln dosyasının nerede oluşturulacağı seçilir.
3. "Configure" ile generator seçilir. Örneğin Visual Studio 11 seçilir.
4. "Generate" düğmesi ile .sln oluşturulur
Komut Satırı
CMake Komut Satırı yazısına taşıdım.
Metodlar
cmake programlama diliyle o kadar fazla sayıda metod geliyor ki hepsini anlamak ve bilmek kolay değil. Kullandığım bazı metodlar şöyle. Büyük küçük fark etmiyor
cmake sürümü
İstersek en düşük cmake sürümünü belirtebiliriz. Şöyle yaparız.
Projenin adını belirtiriz. Aşağıdaki komut projenin adını atar. MyProject.sln dosyasını oluşturur
Sonra Projede kullanılan dosya isimleri belirlenir.
Örnek
Dosya isimleri mylist adlı listeye doldurmak için şöyle yaparız
Öz yinelemeli olmasın istersek şöyle yaparız. Bu sefer SOURCE adlı listeye doldurulur.
Bazı projeler dosya tiplerine göre listeler oluşturuyor. Bence gereksiz bir hareket.
Dosyalar projeye eklenir. Şöyle yaparız.
Belirtilen kütüphanalerin (.so veya .lib) kurulu olduğunu kontrol eder. Boost için şöyle yaparız.
Şöyle yaparız. Eğer belli bir hedef için kullanmak istersek target_compile_options() ta kullanılabilir.
Örnek
Şöyle yaparız.
Visual Studio'da build sonrasında bazı kopyalama işlemleri için post build copy komutu şöyle yaparız.
Çağırmak için şöyle yaparız.
Açıklaması şöyle. Bu komut ile add_compile_options() hep karışıyor. add_definitions() preprocessor için, diğeri ise derleyiciye seçenek geçmek için.
CMake add_library yazısına taşıdım.
add_subdirectory
İki tane CMakeLists.txt dosyası olsun
Bir başka CMake dosyasını dahil etmek için kullanılır. Dahil edilen CMake içindeki metodlar da çağrılabilir. Şöyle yaparız.
Şöyle yaparız. Bu komut birden fazla kere çağrılabilir.
Şöyle yaparız.
Söz dizimi şöyle
Bir değişkene değer atar. Böylece değişken cmake içinde kullanılabilir. Şöyle yaparız.
set_target_properties
Bazı warningleri şöyle kapatmak için şöyle yaparız.
Şöyle yaparız.
Değişlenlerin sayısı oldukça fazla. Değişkenler şöyle.
Linux'taki bir projeden CMake kullanarak Visual Studio 2012 projesi üretirken aldığım notlar aşağıda. Dizinin şöyle bir yapıda olduğunu varsayalım.
├── MyProject
│ ├── CMakeLists.txt
│ ├── include
│ │ ├── aaa.h
│ │ ├── aaaa.h
│ └── src
│ ├── aaa.cpp
│ ├── aaaa.cpp
Bazı projelerde özel bir build dizini açılıyor. En üstteki CMakeLists.txt mi yoksa bu yapı mı daha iyi emin değilim.|_MyProject
|_build
|_src
|_inc
GUI
1. "Browse Source" ile kaynak kodun bulunduğu dizin seçilir. Kaynak kod dizininde CMakeLists.txt dosyası da bulunmalı
2. "Browse Build" ile .sln dosyasının nerede oluşturulacağı seçilir.
3. "Configure" ile generator seçilir. Örneğin Visual Studio 11 seçilir.
4. "Generate" düğmesi ile .sln oluşturulur
Komut Satırı
CMake Komut Satırı yazısına taşıdım.
Metodlar
cmake programlama diliyle o kadar fazla sayıda metod geliyor ki hepsini anlamak ve bilmek kolay değil. Kullandığım bazı metodlar şöyle. Büyük küçük fark etmiyor
cmake sürümü
İstersek en düşük cmake sürümünü belirtebiliriz. Şöyle yaparız.
CMAKE_MINIMUM_REQUIRED(VERSION 3.4.1)
projectProjenin adını belirtiriz. Aşağıdaki komut projenin adını atar. MyProject.sln dosyasını oluşturur
PROJECT( MyProject )
fileSonra Projede kullanılan dosya isimleri belirlenir.
Örnek
Dosya isimleri mylist adlı listeye doldurmak için şöyle yaparız
file(GLOB_RECURSE mylist "./*.cpp" "./*.h")
ÖrnekÖz yinelemeli olmasın istersek şöyle yaparız. Bu sefer SOURCE adlı listeye doldurulur.
file(GLOB SOURCES *.cpp)
ÖrnekBazı projeler dosya tiplerine göre listeler oluşturuyor. Bence gereksiz bir hareket.
file(GLOB_RECURSE CXX_SRCS src/*.cpp)
file(GLOB_RECURSE C_SRCS src/*.c)
file(GLOB_RECURSE HPP_HDRS src/*.hpp)
file(GLOB_RECURSE H_HDRS src/*.h)
ÖrnekDosyalar projeye eklenir. Şöyle yaparız.
# Configure source files for production code
file(GLOB SOURCES ../../sources/*.cpp)
# Tell the cmake what needs to be builded
add_executable( myProject ${SOURCES} )
find packageBelirtilen kütüphanalerin (.so veya .lib) kurulu olduğunu kontrol eder. Boost için şöyle yaparız.
FIND_PACKAGE(Boost 1.59.0 REQUIRED COMPONENTS system thread filesystem)
Çıktı olarak şunu görürüz.-- Boost version: 1.59.0
-- Found the following Boost libraries:
-- system
-- thread
-- filesystem
Eğer sadece belli bir paketin kurulu olduğunu kontrol etmek istersek şöyle yaparız. Bu durum örneğin header only bir kütüphaneyi kullanacaksak işe yarar.find_package(Boost REQUIRED)
İstersek sürüm numarası da verebiliriz.find_package(Boost 1.58.0 REQUIRED)
add_compile_optionsŞöyle yaparız. Eğer belli bir hedef için kullanmak istersek target_compile_options() ta kullanılabilir.
add_compile_options(-fno-rtti)
add_custom_commandÖrnek
Şöyle yaparız.
add_custom_command(TARGET MyProject
POST_BUILD
COMMAND cp foo.h ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
)
ÖrnekVisual Studio'da build sonrasında bazı kopyalama işlemleri için post build copy komutu şöyle yaparız.
ADD_CUSTOM_COMMAND(TARGET MyProject
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/*.ini ${PROJECT_BINARY_DIR}
)
add_custom_targetÇağırmak için şöyle yaparız.
cmake --build /path/to/build/directory --target copy_all
Şöyle yaparız.add_custom_target (copy_all
COMMAND ${CMAKE_SOURCE_DIR}/copy.sh ${files}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
add_definitionsAçıklaması şöyle. Bu komut ile add_compile_options() hep karışıyor. add_definitions() preprocessor için, diğeri ise derleyiciye seçenek geçmek için.
add_definitions is meant to add preprocessor definitions.Eğer lazımsa -D ile başlayan preprocessor seçeneklerini belirlenir.
ADD_DEFINITIONS(-D_WIN32_WINNT=0X600)
Şöyle yaparız.add_definitions(-DBOOST_LOG_DYN_LINK)
add_executable
Kaynak kodlar bir set içinde toplanır. Sonra verilen kaynak kodları derlemek ve bir uygulama üretmek için şöyle yaparız.set(SOURCES
src/p2.c
src/p1.h
src/p1.c)
add_executable(myexe ${SOURCES})
Set'i oluşturmak için glob yapılabilir.file(GLOB_RECURSE CXX_SRCS src/*.cpp)
file(GLOB_RECURSE C_SRCS src/*.c)
file(GLOB_RECURSE HPP_HDRS src/*.hpp)
file(GLOB_RECURSE H_HDRS src/*.h)
set(SRCS "${C_SRCS};${CXX_SRCS}")
set(HDRS "${H_HDRS};${HPP_HDRS}")
add_executable(monoRenderer ${SRCS} ${HDRS})
Eğer istersek kaynak dosyaları teker teker de elle yazabiliriz.ADD_EXECUTABLE(myexe src/mangaMe.cpp)
add_libraryCMake add_library yazısına taşıdım.
add_subdirectory
İki tane CMakeLists.txt dosyası olsun
CMakeLists.txt
src/
CMakeLists.txt
main.cpp
build/
src içindeki ikinci CMakeLists.txt dosyasının tetiklenmesi için şöyle yaparız.#tell CMake that we have some source files located in the src directory
add_subdirectory(src)
includeBir başka CMake dosyasını dahil etmek için kullanılır. Dahil edilen CMake içindeki metodlar da çağrılabilir. Şöyle yaparız.
# Conan setup
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
include_directoriesŞöyle yaparız. Bu komut birden fazla kere çağrılabilir.
INCLUDE_DIRECTORIES(includes)
Bir değişkene atanan değeri kullanmak için şöyle yaparız.set(BOOST_ROOT "C:/dev/tools/boost_1_60_0")
include_directories(${INCLUDE_DIRECTORIES} ${BOOST_ROOT} include)
install - TargetŞöyle yaparız.
install(TARGETS helloworld
RUNTIME DESTINATION ../build)
install - CustomSöz dizimi şöyle
install([[SCRIPT <file>] [CODE <code>]]
[COMPONENT <component>] [...])
Açıklaması şöyleThe SCRIPT form will invoke the given CMake script files during installation. If the script file name is a relative path it will be interpreted with respect to the current source directory. The CODE form will invoke the given CMake code during installation. Code is specified as a single argument inside a double-quoted string.Code içinde mesaj vermek için şöyle yaparız.
install(CODE "MESSAGE(\"Sample install message.\")")
Code içinde script çalıştırmak için şöyle yaparız.install(CODE "execute_process(COMMAND my_script.sh)")
setBir değişkene değer atar. Böylece değişken cmake içinde kullanılabilir. Şöyle yaparız.
SET(BOOST_DIR $ENV{PATH})
Derleyici sürümü seçmek için CMAKE_CXX_FLAGS yazısına bakınız.set_target_properties
Bazı warningleri şöyle kapatmak için şöyle yaparız.
set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "/wd4819")
Derleyici sürümü seçmek için şöyle yaparız.
Target'ımız ile linklemek istediğimiz lib isimlerini yazarız. Açıklaması şöyleadd_executable(Randomshitprogram ${SOURCE_FILES})
set_target_properties(Randomshitprogram
PROPERTIES
CXX_STANDARD 11
CXX_STANDARD_REQUIRED ON
)
Çıktı dosya ismini değiştirmek için şöyle yaparız.# Adds 'd' onto artifacts - does NOT apply to executables.
# For executables, this needs to be done an exec-by-exec
# basis.
set(CMAKE_DEBUG_POSTFIX "d")
# Add postfix onto executable debug filename
set_target_properties(myapp PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
target_compile_options
Şöyle yaparız.
Şöyle yaparız.
target_compile_options(foo PUBLIC -fno-rtti)
target_link_librariestarget_link_libraries works on targets created with add_library and add_executable.Şöyle yaparız. Bu komut birden fazla kere çağrılabilir.
target_link_libraries(wpcaplib.lib)
WriteCompilerDetectionHeaderŞöyle yaparız.
include(WriteCompilerDetectionHeader)
write_compiler_detection_header(
FILE foo_compiler_detection.h
PREFIX foo
COMPILERS GNU
FEATURES cxx_attribute_deprecated
)
CMake DeğişkenleriDeğişlenlerin sayısı oldukça fazla. Değişkenler şöyle.
Hazır Macrolar
CMAKE_SYSTEM_NAME
CMake System Variables yazısına taşıdım.
Dizinlerle İlgili Hazır Macrolar
PROJECT_SOURCE_DIR
CMakeLists.txt dosyasının bulunduğu dizin
CMAKE_BINARY_DIR
Çıktının konulacağı dizin. Visual Studio için .sln dosyasının oluşturulacağı yer.
CMAKE_CURRENT_SOURCE_DIR
Tam ne işe yaradığını anlamadım.
Derleyiciyle İlgili Hazır Macrolar
CMAKE_ARCHIVE_OUTPUT_DIRECTORY
Statitic kütüphanenin nerede oluşturulacağını belirtir. Şöyle yaparız.
Şöyle yaparız.
Şöyle yaparız.
Derleyicinin ismini şöyle öğreniriz.
If/Else gibi düşünülebilir. Bir sonuç dönerler. İki noktanın solundaki değişken sağdaki değere eşitse ikinci ifade 'nin değeri dönülür. Eğer Config değişkeni Debug ise sonuç Release'dir., Config değişkeni Debug değilse boş string döner.
Filtre
Visual Studio, Eclipse gibi dosya sistemi ile çalışmıyor. Kendi dosya/filtre sistemi var. Bu filtre sistemin dosya yolları ile aynı olacak şekilde üretmek için şöyle yaptım.
CMAKE_SYSTEM_NAME
CMake System Variables yazısına taşıdım.
Dizinlerle İlgili Hazır Macrolar
PROJECT_SOURCE_DIR
CMakeLists.txt dosyasının bulunduğu dizin
CMAKE_BINARY_DIR
Çıktının konulacağı dizin. Visual Studio için .sln dosyasının oluşturulacağı yer.
CMAKE_CURRENT_SOURCE_DIR
Tam ne işe yaradığını anlamadım.
Derleyiciyle İlgili Hazır Macrolar
CMAKE_ARCHIVE_OUTPUT_DIRECTORY
Statitic kütüphanenin nerede oluşturulacağını belirtir. Şöyle yaparız.
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin)
CMAKE_BUILD_TYPEŞöyle yaparız.
set(CMAKE_BUILD_TYPE Release)
CMAKE_COMPILER_IS_GNUCCŞöyle yaparız.
if (WIN32)
if (CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--stack,4194304 -fpermissive")
elseif(MSVC)
# add options for Visual C/C++ Compiler here
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /F 4194304")
endif()
endif()
CMAKE_CXX_COMPILERDerleyicinin ismini şöyle öğreniriz.
cmake_minimum_required (VERSION 2.8.11)
MESSAGE( STATUS "Compiler: " ${CMAKE_CXX_COMPILER} )
Çıktı olarak şunu alırız.-- Compiler: /usr/bin/c++
Generator ExpressionIf/Else gibi düşünülebilir. Bir sonuç dönerler. İki noktanın solundaki değişken sağdaki değere eşitse ikinci ifade 'nin değeri dönülür. Eğer Config değişkeni Debug ise sonuç Release'dir., Config değişkeni Debug değilse boş string döner.
$<$<CONFIG:Debug>:Release>
Filtre
Visual Studio, Eclipse gibi dosya sistemi ile çalışmıyor. Kendi dosya/filtre sistemi var. Bu filtre sistemin dosya yolları ile aynı olacak şekilde üretmek için şöyle yaptım.
macro(GroupSources curdir)
file(GLOB children RELATIVE ${PROJECT_SOURCE_DIR}/${curdir} ${PROJECT_SOURCE_DIR}/${curdir}/*)
foreach(child ${children})
if(IS_DIRECTORY ${PROJECT_SOURCE_DIR}/${curdir}/${child})
GroupSources(${curdir}/${child})
else()
string(REPLACE "/" "\\" groupname ${curdir})
# I would like to call the src root folder in a different name, only in visual studio (not mandatory requirement)
string(REPLACE "src" "Common" groupname ${groupname})
source_group(${groupname} FILES ${PROJECT_SOURCE_DIR}/${curdir}/${child})
endif()
endforeach()
endmacro()
# Execute the macro
GroupSources(src)
Hiç yorum yok:
Yorum Gönder