Cmake/Простейший CMakeLists

Прежде чем рассматривать все возможности, которые предоставляет cmake, неплохо бы для начала рассмотреть его структуру и основные команды на примере простого CMakeLists.txt. Представим, что у нас есть проект на С++, содержащий исходники в папке src, заголовочные файлы - в папке include, при этом еще есть платформозависимый код в папках src/arm и src/openrisc. Пусть еще наша программа использует библиотеку pthread.

По "традиции", в корневой папке проекта, где лежат src, include, и прочие файлы, лежит также и корневой CMakeLists.txt, который ссылается на другие CMakeLists.txt, лежащие в других папках. Ниже приведен код корневого CMakeLists.txt с комментариями:

message ("Start") #Выводит сообщение "Start"

cmake_minimum_required (VERSION 2.6) #Проверка версии Cmake

# Папка с заголовочными файлами. Как можно понять. команда set 
# присваивает значение переменной.
set (CMAKE_INCLUDE_PATH include) 
set (PROJECT supertool)

if ( CMAKE_COMPILER_IS_GNUCXX ) 
    set (CMAKE_CXX_FLAGS "-Wall -Os -L/usr/local/lib") 
else ()
    message (FATAL_ERROR "I can't find G++!")
endif ()

# Передаем управление другому CMakeLists.txt,
# который лежит в папке src
add_subdirectory (src) 

Как можно увидеть, в CMake используются много переменных и команд, все они будут рассмотрены в соответствующих разделах этого викиучебника. CMake часто ругают за сложность языка, но возможностей у него достаточно много. Пока что главная задача - понять, как вообще выглядит cmake-файл.

Теперь рассмотрим CMakeLists.txt в папке src:

# На самом деле имена всех нужных cpp файлов можно выписать руками, используя
# конструкцию set (SRC name.cpp name1.cpp ... ), но что, если у нас 300 файлов? Мы
# рассмотрим чуть более простой метод. Но на самом деле первый способ лучше. А
# список файлов может сгенерировать простой скрипт.

# Объявим переменную COMMON_SRC, которая содержит файлы с платформонезависимым кодом.
# file () будет рассмотрен позже, в соответствующих разделах.
file (GLOB COMMON_SRC *.cpp)
set (SOURCE ${COMMON_SRC})

file (GLOB ARM_SRC arm/*.cpp)
file (GLOB OPENRISC_SRC openrisc/*.cpp)

# Платформозависимые исходники
EXECUTE_PROCESS( COMMAND uname -m COMMAND tr -d '\n' OUTPUT_VARIABLE ARCH )

if (ARCH STREQUAL "arm")
    set (SOURCE "${SOURCE} ${ARM_SRC}")
elseif (ARCH STREQUAL "openrisc")
    set (SOURCE "${SOURCE} ${OPENRISC_SRC}")
endif()

#Финальный штрих и сборка.
add_executable(${PROJECT} ${SOURCE}) 
target_link_libraries (${PROJECT} pthread)