100 lines
4.6 KiB
CMake
100 lines
4.6 KiB
CMake
# Требуем 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)
|