Make: переопределить флаг

Я был немного смущен с ответами на Быстрый способ переопределить флаг ошибки?

Поэтому я задаю свой конкретный вопрос здесь.

У меня есть несколько Makefiles, работающих вместе, и CFLAGS был установлен по пути (-Werror -Wall .. и многие другие)

Но в одном из файлов Makefile я хотел бы, чтобы ошибки не рассматривались как предупреждения, и поэтому я хотел бы удалить флаг -Werror.

Каков наилучший способ добиться этого, чтобы только для этого файла Makefile был удален флаг -Werror, а для остальных - нормальное выполнение?

Спасибо солнышко

2 ответа

Решение

Более простой способ

Похоже, вы можете вызвать

gcc -c ... -Werror ... -Wno-error ...

без жалоб GCC (GCC 4.7.1). Итак, вы можете добавить -Wno-error к CFLAGS, установленным в другом месте в одном make-файле, где вам это нужно. Если вы используете GNU makeВ одном make-файле вы можете добавить:

CFLAGS += -Wno-error

возможно только для единственной цели, которая нуждается в этом.

Труднее путь

В противном случае вам понадобится система для сборки CFLAGS из компонентов. В тестовом файле, который я использую для тестирования ответов на вопросы по SO, я использую:

WFLAG1 = -Wall 
WFLAG2 = -Wextra
WFLAG3 = -Wmissing-prototypes 
WFLAG4 = -Wstrict-prototypes 
WFLAG5 = -Wold-style-definition
WFLAG6 =
WFLAGS = ${WFLAG1} ${WFLAG2} ${WFLAG3} ${WFLAG4} ${WFLAG5} ${WFLAG6} 
SFLAGS = -std=c99
GFLAGS = -g
OFLAGS = -O3
UFLAGS =
IFLAG1 = -I${HOME}/inc
IFLAGS = # ${IFLAG1}

CFLAGS   = ${OFLAGS} ${GFLAGS} ${IFLAGS} ${SFLAGS} ${WFLAGS} ${UFLAGS}

Суть в том, что каждый флаг настраивается независимо; Я могу контролировать флаги предупреждения, установив любой из ${WFLAG1} в ${WFLAG6}или настройкой ${WFLAGS} оптовая продажа в командной строке или (действительно) путем установки ${CFLAGS}, Но поскольку каждый из них настраивается индивидуально и может относительно легко настраивать предупреждения (основная проблема заключается в определении того, какой WFLAGn нуждается в залипании).

UFLAGS - это "пользовательские флаги", и он устанавливается только в командной строке; Я могу добавить больше флагов в мою командную строку, установив его.

Этот способ "сложнее", потому что он требует от вас изменения центральной части вашей системы makefile, в которой вы устанавливаете CFLAGS. Это также с меньшей вероятностью будет понято вашими коллегами с первого взгляда.

Правильный способ сделать это с filter-out функция

Положил

CFLAGS := $(filter-out -Werror,$(CFLAGS))

в Makefile, где вы хотите переопределить это, и -Werror часть CFLAGS будет удален в этом Makefile.

Вы даже можете использовать это, чтобы переопределить флаги для единственной цели, используя значения переменных для конкретной цели:

CFLAGS = -Werror

all: foo bar

foo:
        echo cc $(CFLAGS) -o $@

bar: CFLAGS := $(filter-out -Werror,$(CFLAGS))

bar:
        echo cc $(CFLAGS) -o $@

foo будет построен по умолчанию CFLAGS содержащий -Werror, но bar будет построен без.

Это универсальное решение, которое работает для всех аргументов всех программ, вместо того, чтобы требовать от каждой программы --no-foo для каждого --foo вариант. Поскольку это невозможно сделать из командной строки Make, оно не дает прямого ответа на вопрос, на который вы ссылаетесь. Но переопределение Make переменных из командной строки для принудительного создания чего-либо - это довольно хороший способ сделать ваш некомпилируемый код еще менее поддерживаемым!

Вы можете увидеть пример переопределения переменных в Git Makefile с CFLAGS который теперь можно настроить при вызове Make во время использования DEVELOPER=YesPlease с Git 2.22 (Q2 2019)

DEVELOPER (в Git Makefile) - это переменная для группировки предупреждений компилятора.

См. Коммит 6d5d4b4, коммит 71a7894, коммит 8fb2a23, коммит 65260a4, коммит 9559f8f, коммит 4f14a8c (22 февраля 2019 г.). Автор Ævar Arnfjörð Bjarmason ( avar )
(Объединено Юнио С Хамано - gitster - в комитете 3cef676 от 20 марта 2019 г.)

Makefile: разрешить объединение DEVELOPER=1 а также CFLAGS="..."

С тех пор как DEVELOPER=1 введено средство, не было никакого способа иметь собственные CFLAGS (например, CFLAGS="-O0 -g -ggdb3") все еще пользуясь набором предупреждений и утверждений DEVELOPER=1 позволяет.

Это потому, что семантика переменных в Makefile такова, что пользовательские настройки CFLAGS переопределяет все, что мы устанавливаем, включая то, что мы делаем в config.mak.dev,

Итак, давайте представим DEVELOPER_CFLAGS переменная в config.mak.dev и добавить его в ALL_CFLAGS, До этого ALL_CFLAGS Переменная (в основном, есть нюанс, в который мы не будем вдаваться) будет установлена ​​на:

$(CPPFLAGS) [$(CFLAGS) *or* $(CFLAGS) in config.mak.dev] $(BASIC_CFLAGS) $(EXTRA_CPPFLAGS)

Но теперь будет:

$(DEVELOPER_CFLAGS) $(CPPFLAGS) $(CFLAGS) $(BASIC_CFLAGS) $(EXTRA_CPPFLAGS)

Причина для постановки DEVELOPER_CFLAGS во-первых, чтобы позволить выборочно переопределить что-то DEVELOPER=1 приносит.
На обоих GCC а также Clang более поздние настройки переопределяют более ранние.
Например -Wextra -Wno-extra "не будет включать" лишние "предупреждения, но только если эти два аргумента не будут изменены.

Примеры вещей, которые раньше были невозможны, но есть сейчас:

# Use -O0 instead of -O2 for less painful debuggng
DEVELOPER=1 CFLAGS="-O0 -g"
# DEVELOPER=1 plus -Wextra, but disable some of the warnings
DEVELOPER=1 DEVOPTS="no-error extra-all" CFLAGS="-O0 -g -Wno-unused-parameter"

Причина патчей, приводящих к этому, переставила различные *FLAGS назначения и включает в себя только для удобства чтения.
Makefile поддерживает назначения не по порядку, например:

$ cat Makefile
X = $(A) $(B) $(C)
A = A
B = B
include c.mak
all:
        @echo $(X)
$ cat c.mak
C=C
$ make
A B C
Другие вопросы по тегам