Определенные переменные рецепта makefile и оценка $ @ - PullRequest
0 голосов
/ 22 января 2019

Я пытаюсь настроить make-файл, который состоит из цели отладки и выпуска.Существуют некоторые целевые переменные, в основном имена папок, которые в разных случаях установлены правильно, но не применяются правильно для автоматической переменной $@.Следующий код:

SRC_DIR = src
OBJ_ROOT_DIR = obj
REL_DIR = release
DBG_DIR = debug
TGT_DIR = $(REL_DIR)
SRC_LIST = main.cc prime.cc
SRC_SUFF = cc
SRCS = $(patsubst %.cc, $(SRC_DIR)/%.$(SRC_SUFF), $(SRC_LIST))
OBJ_DIR = $(OBJ_ROOT_DIR)/$(TGT_DIR)
OBJS = $(patsubst %.cc, $(OBJ_DIR)/%.o, $(SRC_LIST))

all:                        $(OBJS)

release:                    all

debug:                      TGT_DIR = $(DBG_DIR)
debug:                      OBJ_DIR = $(OBJ_ROOT_DIR)/$(TGT_DIR)
debug:                      OBJS = $(patsubst %.cc, $(OBJ_DIR)/%.o, $(SRC_LIST))
debug:                      $(OBJS)

$(OBJS):$(OBJ_DIR)/%.o:     $(SRC_DIR)/%.$(SRC_SUFF)
                            @echo "TGT_DIR: $(TGT_DIR) OBJ_DIR: $(OBJ_DIR) OBJS: $(OBJS)"
                            @echo "Compiling $< to $@ ..."
                            @echo "... done !"
                            @echo "."

Запуск make release производит следующий ожидаемый вывод:

TGT_DIR: release OBJ_DIR: obj / release OBJS: obj / release /main.o obj / release / prime.o Компиляция src / main.cc в obj / release / main.o ... ... готово!.

TGT_DIR: выпуск OBJ_DIR: obj / выпуск OBJS: obj / release / main.o obj / release / prime.o Компиляция src / prime.cc в obj / release / prime.o ... ..готово!

Wheas make отладка приводит к следующему неожиданному:

TGT_DIR: debug OBJ_DIR: obj / debug OBJS: obj / debug /main.o obj / debug / prime.o Компиляция src / main.cc в obj / release / main.o ... ... готово!.

TGT_DIR: отладка OBJ_DIR: obj / debug OBJS: obj / debug / main.o obj / debug / prime.o Компиляция src / prime.cc в obj / release / prime.o ... ..готово!

Я не могу понять, почему $@ не соответствует требуемой версии отладки во втором случае.Кажется, переменные установлены правильно.Как мне добиться правильного имени каталога при выполнении рецепта?Заранее спасибо!

1 Ответ

0 голосов
/ 24 января 2019

У вас есть несколько вариантов / способов сделать это.

  1. Один быстрый способ - проверить содержимое MAKECMDGOALS (это слова после make, например, release или debug),Примечание: их может быть больше одного, но если ваш make-файл прост и имеет только один, будет работать следующее:

например:

ifneq ($(MAKECMDGOALS),debug)
  TGT_DIR = $(DBG_DIR)
  OBJ_DIR = $(OBJ_ROOT_DIR)/$(TGT_DIR)
  OBJS = $(patsubst %.cc, $(OBJ_DIR)/%.o, $(SRC_LIST))
endif

Другой вариант - использовать второе расширение, я просто добавлю ссылку: вторичное расширение

Еще один вариант - настроитьпеременных в вашем правиле, затем экспортируйте их и снова вызовите make (рекурсивно), возможно, что-то вроде этого:

например (не полностью):

# Note you can just export the ones you want but... for ease of the example:
.EXPORT_ALL_VARIABLES

debug: TGT_DIR = $(DBG_DIR)
debug: OBJ_DIR = $(OBJ_ROOT_DIR)/$(TGT_DIR)
debug: OBJS = $(patsubst %.cc, $(OBJ_DIR)/%.o, $(SRC_LIST))
debug:
    $(MAKE) do_build

do_build: $(OBJS)

...etc...

Где в вашемпервый вызов, чтобы настроить некоторые переменные в правиле отладки.Во втором он вызывает do_build напрямую и переменные уже настроены.На рекурсивную марку обычно нахмурились - но я обнаружил, что во многих случаях это самый простой способ сделать определенные вещи.

Я бы, вероятно, ошибся в выборе варианта 1. для его простоты.Есть еще больше способов сделать это, но это в некоторой степени зависит от того, как вы хотите работать - я просто устанавливаю некоторые параметры, которые сохраняют структуру вашего make-файла более или менее неизменной ...

...