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

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

Ответ 1

У вас есть несколько параметров для настройки переменных вне вашего make файла:

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

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

    FOO?=default_value_if_not_set_in_environment
    

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

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

    make target FOO=bar
    

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

  • Экспорт из родителя 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 без аргументов.

Ответ 2

Самый простой способ:

make foo=bar target

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

Если вы используете подзапросы, см. эту статью: Передача переменных в суб файл

Ответ 3

Скажем, у вас есть make файл, подобный этому:

action:
    echo argument is $(argument)

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

Ответ 4

Из manual:

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

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

FOOBAR=1 make

приводит к переменной FOOBAR в вашем файле Makefile.

Ответ 5

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

пример:

make unittest=*

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

Ответ 6

export ROOT_DIR=<path/value>

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

Ответ 7

Здесь также не указан другой вариант, который включен в книгу GNU. Сделайте книгу Stallman и 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. Например.. предположим, что вы изучаете потоки в С++ 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 [email protected] $^ $(LDLIBS)
ifneq (,$(findstring r,  $(MAKEFLAGS)))
    ./[email protected]
endif

all: $(SOURCES)

.PHONY: clean

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

После этого вы должны:

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