Skip to content

CMake: раздельная сборка OBL executable и INMCM-библиотеки; cmake пресеты сборки; ctest для пресетов; фиксы интеграции SFX; обновлён README

Кратко

  • Добавлены флаги сборки:

    • BUILD_OBL_MAIN (стандартно ON) — сборка standalone‑исполняемого файла obl;
    • BUILD_OBL_INMCM_LIB (стандартно OFF) — сборка библиотеки obl_inmcm_lib для связи с INMCM.
  • Введен унифицированный CMakePresets.json для GNU/Intel (Release/Debug, c NetCDF/без), а также пресеты для сборки библиотеки.

  • Добавлены ctest‑тесты, автоматически прогоняющие конфигурацию и сборку по пресетам (tests/build_preset.cmake).

  • Исправлена интеграция SFX: раздельные каталоги .mod, отключена сборка лишнего sfx‑executаble, добавлен корректный include для модулей.

  • Обновлён README с инструкциями по пресетам и тестам.

Изменения сохраняют обратную совместимость: по умолчанию, как и раньше, собирается obl (standalone).


Мотивация

  1. Разделить две линии использования кода:

    • самостоятельная модель OBL (исполняемый файл),
    • подключение к INMCM как библиотеки (без лишних зависимостей и артефактов).
  2. Сделать сборку воспроизводимой и стандартизованной (через пресеты CMake).

  3. Автоматизировать проверку конфигураций сборки (ctest по пресетам).

  4. Устранить проблемы с интеграцией SFX:

    • коллизии .mod при совместной сборке,
    • нежелательная сборка sfx‑executаble в составе проекта.

Что конкретно изменилось

1) CMakeLists.txt

  • Новые опции:

    • BUILD_OBL_MAIN (ON) — собирает исполняемый obl из полного набора SOURCES.
    • BUILD_OBL_INMCM_LIB (OFF) — собирает obl_inmcm_lib из подмножества (OBL_INMCM_LIB_SOURCES), без зависимостей на ввод/вывод и main‑часть.
  • Флаги компиляции разделены для Intel/GNU (Release/Debug), добавлен -ffree-line-length-none для gfortran.

  • SFX fix:

    • создаются отдельные каталоги модулей: ${binary}/modules/sfx и ${binary}/modules/sfx_lib;
    • sfx помечен EXCLUDE_FROM_ALL ON (не тянуть лишний executable);
    • у sfx_lib явно задан Fortran_MODULE_DIRECTORY, а его путь прокидывается в target_include_directories(obl ...).
  • Поддержка NetCDF оставлена в прежнем стиле (через nc-config/nf-config), только чуть упорядочена.

2) CMakePresets.json

  • Набор пресетов для GNU, Intel oneAPI и Intel Classic:

    • *-release, *-debug;
    • варианты *-ncdf (включают USE_NETCDF=ON);
    • варианты *-inmcm-lib (BUILD_OBL_MAIN=OFF, BUILD_OBL_INMCM_LIB=ON).
  • Отдельный пресет doc для сборки документации (BUILD_DOC=ON).

3) tests/build_preset.cmake + enable_testing()

  • include(CTest) в CMakeLists.txt и опция BUILD_TESTING.

  • Скрипт теста читает CMakePresets.json, для каждого buildPreset:

    1. выполняет cmake --preset <cfg>,
    2. выполняет cmake --build --preset <bld>.
  • На выходе ctest даёт зелёный/красный статус по каждому пресету («собирается ли проект под данной конфигурацией»).

Примечание: папка tests/ добавлена в репозиторий (раньше игнорировалась — убрано test исключение в .gitignore).

4) README

  • Добавлены инструкции по сборке с пресетами, по прогону ctest, и краткое описание новых опций.

5) obl_main.f90

  • Заменены все некорректные для PROGRAM операторы RETURN на стандартные варианты завершения:

    • STOP 0 — для штатного выхода (например, при --help);
    • ERROR STOP "<сообщение>" — для завершения по ошибке, с выводом причины.
  • Лишние write(*,*) перед аварийным выходом удалены, так как ERROR STOP сам печатает сообщение.

  • Причина изменения:

    • По стандарту Fortran RETURN допустим только в процедурах и функциях, но не в главной программе.
    • GNU Fortran допускал это как расширение, Intel Fortran выдавал ошибку при компиляции.
    • STOP/ERROR STOP — корректный по стандарту способ завершения выполнения программы.

Как воспроизвести

Сборка происходит в два этапа: Конфигурация -> сборка

Список пресетов можно посмотреть:

cmake --list-presets=configure
cmake --list-presets=build

Сборка исполняемого файла (GNU, Release)

cmake --preset gnu-release
cmake --build --preset build-gnu -j 8

Сборка библиотеки для INMCM (GNU, Release)

cmake --preset gnu-release-inmcm-lib
cmake --build --preset build-gnu-inmcm-lib -j 8

Вариант с NetCDF (Intel OneAPI) на кластере ИВМ РАН

module load intel impi
module load netcdf netcdf-fortran
# Установленные на кластере ИВМ РАН библиотеки NetCDF работают только с Intel.
# Также они собраны с -lcurl, т.е. просят библиотеку curl, которая в системе отсутствует. Собранные есть у меня, нужно добавить в системные переменные:
export LIBRARY_PATH=/home/data/ahtamyanov/lib/curl/8.15.0/lib64:$LIBRARY_PATH
export LD_LIBRARY_PATH=/home/data/ahtamyanov/lib/curl/8.15.0/lib64:$LD_LIBRARY_PATH
cmake --preset intel-oneapi-release-ncdf
cmake --build --preset build-intel-oneapi-ncdf -j 8

Тест пресетов (ctest)

Не забудьте импортировать модули для Intel. Чтобы тестировать сборку с NetCDF на кластере ИВМ, импортируйте модуль и пути к библиотеке curl. На локальной машине при установленном netcdf, должно подтянуться автоматически при наличии nf-config

cmake -S . -B build-tests -DBUILD_TESTING=ON
cmake --build build-tests -j
ctest --test-dir build-tests

В build-tests/Testing/Temporary/LastTest.log будут лежать подробные логи по сборке каждой конфигурации

Каждый тест называется preset:<имя buildPreset> и внутри сам прогоняет configure+build по соответствующему пресету.


Детали по SFX @debol

Сейчас в проект подтягивается sfx через FetchContent. В типичном состоянии CMake одновременно делает и библиотеку, и executable, и складывает .mod в один каталог. Обе цели содержат одни и те же Fortran-файлы с модулями (.f90) и используют один и тот же каталог для .mod файлов. Из-за этого при параллельной сборке компиляторы могут конфликтовать при записи .mod — иногда сборка проходит, иногда падает с ошибкой вида:

Error copying Fortran module "modules/sfx_data.mod"

Полагаю в этом проекте executable не нужен, т.е. sfx используется как библиотека. В рамках этого MR:

  • развел каталоги модулей для sfx и sfx_lib,
  • отключил сборку sfx‑executаble (EXCLUDE_FROM_ALL) в составе OVM,
  • прокинул include на .mod от sfx_lib в цель obl.

Рекомендация для проекта SFX: разделить опции сборки на SFX_BUILD_LIB и SFX_BUILD_EXE аналогично тому как это сделано в этом проекте. Накинул черновик для симэйклиста sfx sfx_CMakeLists_draft.txt, можно его доработать и протестить. Сообщи если займешься этим, мне тогда нужно будет здесь временный фикс убрать

Edited by Ramil Ahtamyanov

Merge request reports

Loading