Как правильно сделать makefile для компиляции и запуска?

Вопрос, вероятно, не самый лучший, чтобы описать мою проблему, но я не мог придумать лучшего. Мой make файл выглядит следующим образом:

PROGRAM_NAME = prog

OBJECT_FILES = $(PROGRAM_NAME).o
CFLAGS = -O2 -Wall -g

$(PROGRAM_NAME) : $(OBJECT_FILES)
    gcc $(CFLAGS) -o [email protected] $(OBJECT_FILES)

$(PROGRAM_NAME).o : $(PROGRAM_NAME).c data.h
    gcc $(CFLAGS) -c $<

clean :
    $(RM) $(PROGRAM_NAME)
    $(RM) $(OBJECT_FILES)
    $(RM) *~ *.bak

run :
    @$(MAKE) && ./$(PROGRAM_NAME) $(ARGS)

Когда я хочу скомпилировать и запустить, я просто делаю "make run" . Проблема в том, что моя программа обрабатывает сигнал, созданный Ctrl + Z, и если я запустил свою программу с "make run" , сигнал будет отправлен на "make run" , а не на мою программу.

В принципе, вызов "make run" - это не то же самое, что вызывать прямо "make & &./prog", потому что в первом случае "make run" не заканчивается, если только "prog" не завершается первым.

Есть ли способ обойти это?

Ответы

Ответ 1

Запуск из make файла немного необычен. Возможно, вы пытаетесь дублировать пункт меню "Скомпилировать и запустить", который предоставляет некоторые IDE? Make не хорошо подготовлен для этого.

Все, что происходит в целевых командах, происходит в подпроцессах, которые не привязаны непосредственно к терминалу, поэтому make получает ваш ключевой штрих.

Еще одна вещь, на которую нужно обратить внимание: обычно объект файл на исполняемый этап (привязка) использует другой набор флагов (LDFLAGS и LIBS), а затем этап компиляции. В этом простом примере вы можете обойтись без него, но если вы скопируете этот make файл для использования в более сложном случае, вы столкнетесь с неприятностями.

Ответ 2

Вы можете упростить задачу "запустить", поскольку она зависит от того, обновлена ​​ли ваша программа, а затем просто запустите программу:

run:    ${PROGRAM_NAME}
        ./${PROGRAM} ${ARGS}

В запуске make при запуске make не так много смысла, по крайней мере, не в этом контексте. Возможно, для рекурсивных операций (в разных каталогах), но см. "" Рекурсивное принятие считается вредным".

Кроме того, ваш make файл должен, как правило, предоставлять цель "all", и обычно это должна быть первая и поэтому цель по умолчанию.

Ответ 3

Если вы собираетесь создавать и запускать снова и снова, вы можете использовать команду history, чтобы помочь с этим:

# Run this once
make && ./foo

# Repeat last command
!!

Ответ 4

Как сказал dmckee ответ, make (1) что-то делает, а не для компиляции и запуска.

Конечно, ничто не мешает вам создать shell псевдоним make-run, который делает предполагаемый make & &./prog args ".