Files
MMPS_DZ_1/CMakeLists.txt
2026-09-23 18:10:38 +03:00

100 lines
4.6 KiB
CMake
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Требуем CMake не старее версии 3.20.
cmake_minimum_required(VERSION 3.20)
# Создаём проект на языке C++.
project(mmps_homework_1 LANGUAGES CXX)
# Используем стандарт C++17. Он нужен хосту для std::filesystem.
set(CMAKE_CXX_STANDARD 17)
# Запрещаем CMake использовать более старый стандарт.
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Отключаем нестандартные расширения конкретного компилятора.
set(CMAKE_CXX_EXTENSIONS OFF)
# Создаём основную программу. Она ищет и загружает плагины во время выполнения.
add_executable(mmps_host src/main.cpp)
# Позволяем подключать общий интерфейс как #include "api.hpp".
target_include_directories(mmps_host PRIVATE include)
# В Linux функции dlopen, dlsym и dlclose могут требовать библиотеку libdl.
# В Windows LoadLibraryW/GetProcAddress предоставляются системой, поэтому
# дополнительная библиотека для компоновки не нужна.
if(UNIX AND NOT APPLE)
target_link_libraries(mmps_host PRIVATE ${CMAKE_DL_LIBS})
endif()
# Складываем исполняемый файл в build/bin.
set_target_properties(mmps_host PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
# Функция создаёт один плагин из переданного исходного файла.
function(add_mmps_plugin target source)
# MODULE означает динамически загружаемый модуль:
# DLL в Windows, SO в Linux и DYLIB в macOS.
add_library(${target} MODULE ${source})
# Плагину доступны общие структуры, типы функций и имена символов из api.hpp,
# а также вспомогательные функции численных методов из state.hpp.
target_include_directories(${target} PRIVATE include)
# PLUGIN_BUILD включает __declspec(dllexport) при сборке DLL в Windows.
# Определение PRIVATE и потому не передаётся другим целям.
target_compile_definitions(${target} PRIVATE PLUGIN_BUILD)
# PREFIX "" убирает стандартный префикс lib у имени плагина.
# Все плагины складываются в общий каталог build/plugins.
set_target_properties(${target} PROPERTIES
PREFIX ""
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/plugins"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/plugins"
)
endfunction()
# Каждый решатель и способ вывода собирается в отдельную библиотеку.
add_mmps_plugin(
runge_kutta_plugin
plugins/runge_kutta_plugin.cpp
)
add_mmps_plugin(
adams_bashforth_plugin
plugins/adams_bashforth_plugin.cpp
)
add_mmps_plugin(
console_output_plugin
plugins/console_output_plugin.cpp
)
add_mmps_plugin(
csv_output_plugin
plugins/csv_output_plugin.cpp
)
# ЧТО ПРОИСХОДИТ ПРИ СБОРКЕ
# src/main.cpp -> mmps_host.exe
# plugins/runge_kutta_plugin.cpp -> runge_kutta_plugin.dll
# plugins/adams_bashforth_plugin.cpp -> adams_bashforth_plugin.dll
# plugins/console_output_plugin.cpp -> console_output_plugin.dll
# plugins/csv_output_plugin.cpp -> csv_output_plugin.dll
#
# Хост и плагины собираются независимо. Здесь намеренно нет команд:
# target_link_libraries(mmps_host PRIVATE runge_kutta_plugin)
# target_link_libraries(mmps_host PRIVATE adams_bashforth_plugin)
#
# Поэтому в mmps_host не записываются обязательные зависимости от конкретных
# решателей. При запуске хост просматривает заданный каталог, загружает каждый
# подходящий файл через LoadLibraryW/dlopen и ищет функции по контракту api.hpp.
# Добавление ещё одного совместимого решателя не требует изменения main.cpp.
#
# ПРИМЕР СБОРКИ
# cmake -S . -B build
# cmake --build build --config Release
#
# ПРИМЕР ЗАПУСКА ИЗ КАТАЛОГА build
# bin/Release/mmps_host.exe (Visual Studio)
# bin/mmps_host (Linux/Makefiles)