# Система сборки cmake

Итак, чтобы не компилировать каждый файл по отдельности и потом вручную не собирать их в одну программу, люди сделали набор инструментов делающих это автоматически. В частности для сборки проектов на C/C++ в linux принято использовать набор утилит autotools, главная из которых `make`. Эта программа вызывается из командной строки, и вызванная без аргументов ищет makefile - файл содержащий инструкции по сборке проекта. Однако оказалось, что процесс написания этого makefile тоже можно автоматизировать, и люди создали cmake - утилиту генерирующую makefile, по более упрощенному описанию. Таким образом сборка происходит в два этапа, сначала cmake генерирует makefile, затем make собирает программу. Сборка происходит обычно следующим образом. Мы создаем директорию (обычно с именем `build`) для того, чтобы потом можно было одним движение удалить весь мусор остающийся после сборки, и в этой директори вызываем `cmake`, в качестве аргумента передав путь до файла `CMakeLists.txt`:

```bash
cmake path/to/CMakeLists.txt
```

Также мы можем вызвать команду `ccmake` и произвести настройку сборки, как мы это делали, когда устанавливали GEANT4. После того, как был удачно сгенерирован makefile, мы вызываем `make` и смотрим как собирается наша программа.

Теперь рассмотрим содержимое файла `CMakeLists.txt`

```
# Задаем минимальныю версию cmake
CMAKE_MINIMUM_REQUIRED(VERSION 2.6 FATAL_ERROR)
# Задаем имя проекта
PROJECT(lesson02)

# Будет успешно если путь к cmake модулям GEANT4 будет в переменных окружения системы
# Данная команда позвляет автоматически подключать билиотеки установденные в систему, их разработчки предусмотрел такую возможность
FIND_PACKAGE(Geant4 REQUIRED ui_all vis_all)

# Эпик фейл если GEANT4 не найден
# Так же это пример, как можно использовать условные операторы при сборке
IF(NOT Geant4_FOUND)
    MESSAGE(FATAL_ERROR "Geant4 not found!")
ENDIF(NOT Geant4_FOUND)

# Подключаем заголовочные файлы GEANT4
INCLUDE(${Geant4_USE_FILE})
# Подключаем заголовочные файлы нашего проекта
# ${PROJECT_SOURCE_DIR} - обращение к переменной cmake, содержащей путь до
# файла CMakeLists.txt
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)

#Cоздаем переменную содержащую пути к исходним файлам
FILE(GLOB sources ${PROJECT_SOURCE_DIR}/src/*.cc)

# Создаем исполняемый файл
ADD_EXECUTABLE(lesson02.exe lesson02.cc ${sources})

# Линкуем исполняемый файл и внешние билиотеки
TARGET_LINK_LIBRARIES(lesson02.exe ${Geant4_LIBRARIES})

# Копируем необходимые нам файлы из папки проекта в папку где происходит сборка
# Для этого мы создаем переменную хранящую один или несколко файлов
set( GEANT4_SCRIPTS init_vis.mac)
# И с помощью цикла копируем каждый файл
foreach(_script ${GEANT4_SCRIPTS})
    configure_file(
            ${PROJECT_SOURCE_DIR}/${_script}
            ${PROJECT_BINARY_DIR}/${_script}
            COPYONLY
    )
endforeach()

# Описываем поведение для команды make install
install(TARGETS lesson02.exe DESTINATION bin)
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mipt-npm.gitbook.io/geant4-education/ru/lesson-run-and-cmake/cmake.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
