Я работаю в проекте кода FORTRAN, где решения по сборке принимаются в двух файлах: файл заголовка (definitions.h
), который входит в соответствующие файлы FORTRAN, и makefile
. Например, в makefile
выбраны компилятор, несколько наборов библиотек и разрешенная параллелизация (MPI, OpenMP или none), а включение некоторых частей кода контролируется директивами #define
в заголовке.Сосуществование параметров Makefile и заголовков
Мне не нравится редактировать два разных файла для настройки компиляции. Есть ли лучший подход?
Кроме того, как файлы
makefile
, так и файлыdefinitions.h
находятся под контролем редакции. Это означает, что мои неосторожные разработчики фиксируют и нажимают новые версии обоих файлов, где они только меняют параметры компиляции, поэтому загрязняют историю контроля версий. В идеале, по крайней мере, самый большой файл (makefile
) не нужно будет редактировать, чтобы задать параметры компиляции.В некоторых случаях возникают несоответствия. Как правило, некоторые комбинации библиотек, выбранные в
makefile
, несовместимы с некоторыми разделами кода, выбранными директивами#define
. Есть ли способ проверить это правильно?Например, для того, чтобы остановить компиляцию, если
LIB1=LIBFOO
(вmakefile
) иbar
определяется1
(в заголовках файлов), я пытался следующий фрагмент кода вmakefile
ifeq ($(LIB1), LIBFOO) bar_status:=`grep -i '^[[:space:]]*\#define[[:space:]]*bar[[:space:]]*[[:digit:]]' definitions.h | tail -n1 | grep -ic '^[[:space:]]*#define[[:space:]]*bar[[:space:]]*1[[:space:]]*'` ifeq ($(bar_status), 1) $(error ERROR: You are trying to compile the code with bar enabled in definitions.h, but this is incompatible with the library LIBFOO selected in the makefile) endif endif
но (а) это крайне уродливо, и (б) очевидно, что он вообще не работает. Как это можно зафиксировать?
Я работал на 3., и я думаю, что-то есть ответ на это: добавить новую .PHONY
цель, ini_check
, что является необходимым условием для других соответствующих целей, и читает
ifeq ($(LIB1), LIBFOO)
bar_value:=$(shell echo bar | cat definitions.h - | gcc -E -undef - 2>/dev/null | tail -n1)
endif
ini_check:
ifeq ($(LIB1), LIBFOO)
ifeq ($(bar_value), 1)
$(error ERROR: You are trying to compile the code with bar enabled in definitions.h, but this is incompatible with the library LIBFOO selected in the makefile)
endif
endif
@echo "Done with the initial check, starting compilation..."
Обратите внимание, что теперь я использую препроцессор C, чтобы получить значение переменной bar
после разбора заголовка.
Я не знаю Фортран, поэтому я просто прокомментирую. Make может принимать параметры командной строки, чтобы определить некоторые из этих вариантов (или использовать наиболее часто используемые параметры по умолчанию). Если директивы '# define' несовместимы с некоторыми библиотеками, вы должны получить ошибки компилятора; если вы этого не сделаете, вы должны отредактировать библиотеки до тех пор, пока не сделаете это. – Beta
Следует избегать вариантов командной строки, все входы должны поступать из файлов. Что касается ваших желаемых ошибок компилятора, я их не получаю, и я не могу изменять библиотеки. Кроме того, если они появятся вообще, они сделают это через несколько минут после начала компиляции. Я хотел бы реализовать вышеупомянутую проверку, чтобы компиляция как можно скорее прекратилась, если обнаружены несоответствия. – ripero