Прохождение дополнительных переменных из командной строки, чтобы сделать


могу ли я передавать переменные в GNU Makefile в качестве аргументов командной строки? Другими словами, Я хочу передать некоторые аргументы, которые в конечном итоге станут переменными в файле Makefile.

7 438

7 ответов:

у вас есть несколько вариантов настройки переменных вне вашего makefile:

  • окружающая среда - каждая переменная среды преобразуется в переменную makefile с тем же именем и значением.

    вы также можете установить (Он же --environments-override) on, и ваши переменные среды будут переопределять назначения, сделанные в makefile (если только эти назначения сами не используют override директива . Тем не менее, это не рекомендуется, и это гораздо лучше и гибко использовать ?= присваивание (оператор присваивания условной переменной, он действует только в том случае, если переменная еще не определена):

    FOO?=default_value_if_not_set_in_environment
    

    обратите внимание, что некоторые переменные не наследуются от среды:

    • MAKE получается из названия скрипта
    • SHELL устанавливается либо в файле makefile, либо по умолчанию /bin/sh (обоснование: команды, указанные в makefile, и они специфичны для оболочки).
  • из командной строки -make может принимать переменные назначения как часть его командной строки, смешанные с целями:

    make target FOO=bar
    

    а то все поручения FOO переменная в файле makefile будет проигнорирована если вы используете override директива в назначении. (Эффект тот же, что и с для окружающей среды переменные параметры.)

  • экспорт из родительского Make - если вы вызываете Make из файла Makefile, вы обычно не должны явно писать назначения переменных следующим образом:

    # Don't do this!
    target:
            $(MAKE) -C target CC=$(CC) CFLAGS=$(CFLAGS)
    

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

    # Do like this
    CFLAGS=-g
    export CFLAGS
    target:
            $(MAKE) -C target
    

    вы можете также экспорт все переменные с помощью export без аргументов.

самый простой способ-это:

make foo=bar target

тогда в вашем makefile вы можете ссылаться на $(foo). Обратите внимание, что это не будет распространяться на суб-делает автоматически.

Если вы используете суб-делает, см. Эту статью:передача переменных в суб-make

скажем, у вас есть makefile, как это:

action:
    echo argument is $(argument)

вы бы тогда назвали это make action argument=something

С руководство:

переменные в make могут поступать из среды, в которой выполняется make. Каждая переменная среды, которая make видит, когда она запускается, преобразуется в переменную make с тем же именем и значением. Однако явное назначение в файле makefile или с аргументом команды переопределяет среду.

Так что вы можете сделать (от bash):

FOOBAR=1 make

в результате в переменной FOOBAR в файл Makefile.

export ROOT_DIR=<path/value>

затем используйте переменную,$(ROOT_DIR) в Makefile.

Если вы создадите файл с именем Makefile и добавите такую переменную, как $(unittest) тогда вы сможете использовать эту переменную внутри файла Makefile даже с подстановочными знаками

пример :

make unittest=*

Я использую BOOST_TEST и, давая подстановочный знак параметру --run_test=$(unittest) тогда я смогу использовать регулярное выражение для фильтрации теста, который я хочу, чтобы мой Makefile для запуска

есть еще один вариант, не упомянутый здесь, который включен в Книгу GNU Make Stallman and McGrath (см. http://www.chemie.fu-berlin.de/chemnet/use/info/make/make_7.html). он дает пример:

archive.a: ...
ifneq (,$(findstring t,$(MAKEFLAGS)))
        +touch archive.a
        +ranlib -t archive.a
else
        ranlib archive.a
endif

это включает в себя проверку, если данный параметр появляется в MAKEFLAGS. Например.. предположим, что вы изучаете темы в c++11 и разделили свое исследование на несколько файлов (class01, ... ,classNM) и вы хотите: собрать потом все и запускаются по отдельности или компилируются по одному и запускаются, если указан флаг (-r, например). Итак, вы могли бы придумать следующее Makefile:

CXX=clang++-3.5
CXXFLAGS = -Wall -Werror -std=c++11
LDLIBS = -lpthread

SOURCES = class01 class02 class03

%: %.cxx
    $(CXX) $(CXXFLAGS) -o $@.out $^ $(LDLIBS)
ifneq (,$(findstring r,  $(MAKEFLAGS)))
    ./$@.out
endif

all: $(SOURCES)

.PHONY: clean

clean:
    find . -name "*.out" -delete

имея это, вы бы:

  • построить и запустить файл W/ make -r class02;
  • построить все ж/ make или make all;
  • построить и запустить все ж/ make -r (предположим, что все они содержат некоторые определенные вещи assert, и вы просто хотите их проверить все)