Как передать определение макроса из аргументов командной строки «make» (-D) в исходный код C?

107

Я обычно передаю определения макросов из «make command line» в «makefile», используя параметр: -Dname = value. Определение доступно внутри make-файла.

Я также передаю определения макросов из «makefile» в «исходный код», используя аналогичный параметр компилятора: -Dname = value (поддерживается во многих компиляторах). Это определение доступно в исходном коде.

Что мне сейчас нужно, так это позволить пользователю моего make-файла сразу передавать произвольные макроопределения из "командной строки make.exe" в "исходный код" без необходимости изменять что-либо в make-файле.

поэтому пользователь может ввести: make -f mymakefile.mk -SOMEOPTION var = 5

тогда непосредственно код main.c может увидеть var:

int main()
{
  int i = var;
}
МохамедЭзз
источник
15
Почему голос против? Мне кажется, это вполне законный вопрос.
Thomas

Ответы:

99

Вызовите makeкоманду так:

make CFLAGS=-Dvar=42

И обязательно используйте $(CFLAGS)команду компиляции в Makefile. Как упоминалось в @ jørgensen, присвоение переменной после makeкоманды переопределит CFLAGSзначение, уже определенное в Makefile.

В качестве альтернативы вы можете установить -Dvar=42другую переменную, CFLAGSа затем повторно использовать эту переменную, CFLAGSчтобы избежать полного переопределения CFLAGS.

ауа
источник
8
Вы не можете использовать "CFLAGS = $ (CFLAGS) -Wall"; это будет рекурсивное определение, и make этого не допускает. Вы можете использовать «CFLAGS: = $ (CFLAGS) -Wall» или «CFLAGS + = -Wall», но они не будут работать, потому что назначение в командной строке имеет более высокий приоритет. Вы можете использовать "override CFLAGS + = -Wall", но обычно мы рекомендуем вам просто выбирать другие переменные внутри. Стандарты кодирования GNU требуют, чтобы CFLAGS и т. Д. Оставались для пользователя, а make-файлы выбирали другую переменную, например "local_CFLAGS = $ (CFLAGS) -Wall".
MadScientist
2
Чтобы добавить к примечанию @MadScientist, стандарты кодирования GNU также заявляют, что это $(CFLAGS)должно быть последним, так что любые параметры, указанные пользователем, переопределят все, что Makefile устанавливает внутри. Это означало бы использовать, например local_CFLAGS = -Wall $(CFLAGS). И наоборот, если есть что-то, что вы действительно хотите иметь приоритет, поместите это после $(CFLAGS), как в комментарии @MadScientist.
Сэм,
1
Как установить этим несколько макросов?
Woody Huang
2
@WoodyHuang напримерCFLAGS="-Dvar1=42 -Dvar2=314"
ууу
1
CPPFLAGSможет быть лучше, чем CFLAGSили CXXFLAGS: stackoverflow.com/a/53527858/2278206
psq
11

Просто используйте для этого конкретную переменную.

$ cat Makefile 
all:
    echo foo | gcc $(USER_DEFINES) -E -xc - 

$ make USER_DEFINES="-Dfoo=one"
echo foo | gcc -Dfoo=one -E -xc - 
...
one

$ make USER_DEFINES="-Dfoo=bar"
echo foo | gcc -Dfoo=bar -E -xc - 
...
bar

$ make 
echo foo | gcc  -E -xc - 
...
foo
Мат
источник
10

Вызов сделать этот путь

make CFLAGS=-Dvar=42

потому что вы действительно хотите переопределить CFLAGS вашего Makefile, а не только среду (которая имеет более низкий приоритет по отношению к переменным Makefile).

Йоргенсен
источник
6

Из-за низкой репутации я не могу комментировать принятый ответ.

Я хотел бы упомянуть предопределенную переменную CPPFLAGS. Это может быть лучше, чем CFLAGSили CXXFLAGS, поскольку оно описано в руководстве GNU Make как:

Дополнительные флаги для препроцессора C и программ, которые его используют (компиляторы C и Fortran).

Примеры встроенных неявных правил, использующих CPPFLAGS

  • n.oпроизводится автоматически n.cпо рецепту формы:
    • $(CC) $(CPPFLAGS) $(CFLAGS) -c
  • n.oпроизводится автоматически из n.cc, n.cppили n.Cпо рецепту формы:
    • $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c

Можно использовать команду make CPPFLAGS=-Dvar=123для определения желаемого макроса.

Больше информации

psq
источник
1
$ cat x.mak
все:
    echo $ (ОПЦИЯ)
$ make -f x.mak 'ОПЦИЯ = -DPASSTOC = 42'
эхо -DPASSTOC = 42
-DPASSTOC = 42
pmg
источник
-4

Найдите файл C и реализацию Makefile ниже, чтобы удовлетворить ваши требования.

foo.c

 main ()
    {
        int a = MAKE_DEFINE;
        printf ("MAKE_DEFINE value:%d\n", a);
    }

Makefile

all:
    gcc -DMAKE_DEFINE=11 foo.c
mahendiran.b
источник
вопрос в том, чтобы передать произвольные определения из командной строки make непосредственно в исходный код C "без изменения make-файла". Итак, я хотел однажды изменить свой make-файл, чтобы можно было делать эти произвольные определения.
MohamedEzz 07
Не работает для make. То есть make -DMAKE_DEFINE = 11 говорит о недопустимой опции.
Рамакришнан Каннан