Параллельная сборка CMake для Fortran-90+ с модулями

У меня проблема с созданием нескольких исполняемых целей Fortran-90+ с использованием CMake, когда я использую модули Fortran, которые являются общими для всех исполняемых файлов, и строю параллельно, используя make -j, Кажется, проблема в том, что скомпилированные объектные файлы размещаются в разных подкаталогах для каждой цели, CMakeFiles/targetName.dir/src/file.f90.o, в то время как файлы модуля находятся в одном каталоге для каждой цели (я могу изменить этот каталог, установив Fortran_MODULE_DIRECTORY, но это будет все тот же каталог для всех файлов модуля). Проблема в том, что все цели начинают записывать эти файлы модулей параллельно, и я получаюFatal Error: Can't rename module file 'module.mod0' to 'module.mod': No such file or directoryпри использовании gfortran (который, очевидно, создает файл.mod0, а затем переименовывает его в.mod). Проблема не возникает, когда я запускаю команду make без опции -j (серийная сборка).

Я вижу два решения, но я не знаю, как их реализовать. Во-первых, поместите объектные файлы для всех целей в одном и том же каталоге, а не в каталогах для конкретных целей. Это может быть предпочтительным вариантом, так как мне не придется компилировать совместно используемые исходные файлы N раз для N целей. Процесс make затем распознает, что объектные файлы существуют, и не скомпилирует соответствующие исходные файлы снова, следовательно, не затрагивая файлы.mod(0) снова (мне может понадобиться, чтобы все следующие цели зависели от первой).

Второе решение - поместить файлы.mod(0) в директории, предназначенные для конкретных целей, чтобы они не перезаписывались и не удалялись другими целями. Это решило бы мою проблему, даже если это потребовало бы больше компиляции, чем необходимо. Я понятия не имею, как выполнить какой-либо из вариантов, поэтому приветствуется любая подсказка или альтернативное решение.

1 ответ

Решение

Ответ, который я искал, был предоставлен в комментариях к вопросу @RaulLaasner:

Я хотел бы создать дополнительную цель в виде основной библиотеки соответствующих исходных файлов, которая затем может быть связана со всеми исполняемыми файлами. Это должно работать параллельно. Файлы модов все еще могут быть помещены в один каталог.

я использовал add_library() а также target_link_libraries() для достижения этой цели.

Обратите внимание, что, например, сценарии Gentoo ebuild добавляют --as-needed на компоновщик, который может вызвать неопределенные ссылки в вашей основной библиотеке, когда вы связываете его и внешние библиотеки для формирования исполняемого файла. Чтобы предотвратить это, убедитесь, что вы сначала связали внешние библиотеки с вашей основной библиотекой. Для этого мой CMakeListst.txt содержит:

add_library( "Core" STATIC src/functions.f90 src/routines.f90 )  # creates libCore.a
target_link_libraries( Core ${EXTERNAL_LIBRARIES} )              # link external libraries to libCore.a
...
add_executable( myProgram1 src/myProgram1.f90 )                  # creates the first executable
target_link_libraries( myProgram1 Core )                         # links libCore.a to myProgram1 

Последние две строки могут повторяться для построения других исполняемых файлов (например, с помощью foreach()).

Другие вопросы по тегам